]> granicus.if.org Git - clang/commitdiff
Rewrite FindDiagnostics to be more strict about the formatting of the
authorChris Lattner <sabre@nondot.org>
Mon, 24 Nov 2008 01:28:17 +0000 (01:28 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 24 Nov 2008 01:28:17 +0000 (01:28 +0000)
expected-foo strings.  Now the only allowed characters between
expected-error and {{  is whitespace.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59925 91177308-0d34-0410-b5e6-96231b3b80d8

Driver/DiagChecker.cpp
test/Analysis/CheckNSError.m
test/Sema/decl-invalid.c
test/Sema/vla.c
test/SemaObjC/string.m

index 4c0aa4c6e99daaddbd5a4ed292af3f43c6cd210c..6f4cd7c509d99ae6e8dbb6d61e66941bfa7fe446 100644 (file)
@@ -47,43 +47,65 @@ static void EmitError(Preprocessor &PP, SourceLocation Pos, const char *String){
 /// FindDiagnostics - Go through the comment and see if it indicates expected
 /// diagnostics. If so, then put them in a diagnostic list.
 /// 
-static void FindDiagnostics(const std::string &Comment,
+static void FindDiagnostics(const char *CommentStart, unsigned CommentLen,
                             DiagList &ExpectedDiags,
-                            Preprocessor &PP,
-                            SourceLocation Pos,
-                            const char * const ExpectedStr) {
-  SourceManager &SourceMgr = PP.getSourceManager();
+                            Preprocessor &PP, SourceLocation Pos,
+                            const char *ExpectedStr) {
+  const char *CommentEnd = CommentStart+CommentLen;
+  unsigned ExpectedStrLen = strlen(ExpectedStr);
   
-  // Find all expected diagnostics.
-  typedef std::string::size_type size_type;
-  size_type ColNo = 0;
-
-  for (;;) {
-    ColNo = Comment.find(ExpectedStr, ColNo);
-    if (ColNo == std::string::npos) break;
-
-    size_type OpenDiag = Comment.find("{{", ColNo);
-
-    if (OpenDiag == std::string::npos) {
-      EmitError(PP, Pos,
-                "cannot find start ('{{') of expected diagnostic string");
-      return;
+  // Find all expected-foo diagnostics in the string and add them to
+  // ExpectedDiags.
+  while (CommentStart != CommentEnd) {
+    CommentStart = std::find(CommentStart, CommentEnd, 'e');
+    if (unsigned(CommentEnd-CommentStart) < ExpectedStrLen) return;
+    
+    // If this isn't expected-foo, ignore it.
+    if (memcmp(CommentStart, ExpectedStr, ExpectedStrLen)) {
+      ++CommentStart;
+      continue;
     }
-
-    OpenDiag += 2;
-    size_type CloseDiag = Comment.find("}}", OpenDiag);
-
-    if (CloseDiag == std::string::npos) {
-      EmitError(PP, Pos,"cannot find end ('}}') of expected diagnostic string");
+    
+    CommentStart += ExpectedStrLen;
+    
+    // Skip whitespace.
+    while (CommentStart != CommentEnd &&
+           isspace(CommentStart[0]))
+      ++CommentStart;
+    
+    // We should have a {{ now.
+    if (CommentEnd-CommentStart < 2 ||
+        CommentStart[0] != '{' || CommentStart[1] != '{') {
+      if (std::find(CommentStart, CommentEnd, '{') != CommentEnd)
+        EmitError(PP, Pos, "bogus characters before '{{' in expected string");
+      else
+        EmitError(PP, Pos, "cannot find start ('{{') of expected string");
       return;
+    }    
+    CommentStart += 2;
+
+    // Find the }}.
+    const char *ExpectedEnd = CommentStart;
+    while (1) {
+      ExpectedEnd = std::find(ExpectedEnd, CommentEnd, '}');
+      if (CommentEnd-ExpectedEnd < 2) {
+        EmitError(PP, Pos, "cannot find end ('}}') of expected string");
+        return;
+      }
+      
+      if (ExpectedEnd[1] == '}')
+        break;
+
+      ++ExpectedEnd;  // Skip over singular }'s
     }
 
-    std::string Msg(Comment.substr(OpenDiag, CloseDiag - OpenDiag));
-    size_type FindPos;
+    std::string Msg(CommentStart, ExpectedEnd);
+    std::string::size_type FindPos;
     while ((FindPos = Msg.find("\\n")) != std::string::npos)
       Msg.replace(FindPos, 2, "\n");
     ExpectedDiags.push_back(std::make_pair(Pos, Msg));
-    ColNo = CloseDiag + 2;
+    
+    CommentStart = ExpectedEnd;
   }
 }
 
@@ -113,17 +135,19 @@ static void FindExpectedDiags(Preprocessor &PP,
     if (!Tok.is(tok::comment)) continue;
     
     std::string Comment = PP.getSpelling(Tok);
+    if (Comment.empty()) continue;
 
+    
     // Find all expected errors.
-    FindDiagnostics(Comment, ExpectedErrors, PP,
+    FindDiagnostics(&Comment[0], Comment.size(), ExpectedErrors, PP,
                     Tok.getLocation(), "expected-error");
 
     // Find all expected warnings.
-    FindDiagnostics(Comment, ExpectedWarnings, PP,
+    FindDiagnostics(&Comment[0], Comment.size(), ExpectedWarnings, PP,
                     Tok.getLocation(), "expected-warning");
 
     // Find all expected notes.
-    FindDiagnostics(Comment, ExpectedNotes, PP,
+    FindDiagnostics(&Comment[0], Comment.size(), ExpectedNotes, PP,
                     Tok.getLocation(), "expected-note");
   };
 }
index c6d846ef440f7855d3ec3e555ed4daa7cc2b7946..241c68cd85b3317ffda250a56730346df77ab236 100644 (file)
@@ -20,8 +20,8 @@ extern NSString * const NSXMLParserErrorDomain ;
 @end
 
 @implementation A
-- (void)myMethodWhichMayFail:(NSError **)error {   // expected-warning: {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occured.}}
-  *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning: {{Potential null dereference.}}
+- (void)myMethodWhichMayFail:(NSError **)error {   // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occured.}}
+  *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference.}}
 }
 
 - (BOOL)myMethodWhichMayFail2:(NSError **)error {  // no-warning
@@ -33,8 +33,8 @@ extern NSString * const NSXMLParserErrorDomain ;
 struct __CFError {};
 typedef struct __CFError* CFErrorRef;
 
-void foo(CFErrorRef* error) { // expected-warning{{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occured.}}
-  *error = 0;  // expected-warning{{Potential null dereference.}}
+void foo(CFErrorRef* error) { // expected-warning {{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occured.}}
+  *error = 0;  // expected-warning {{Potential null dereference.}}
 }
 
 int bar(CFErrorRef* error) {
index b92146260ef11f66f8638f241d9b3de6b70aeeb0..767d6e6ab40c8af17a31eced8cd873f8151c6b22 100644 (file)
@@ -1,11 +1,11 @@
 // RUN: clang %s -fsyntax-only -verify
 
-typedef union <anonymous> __mbstate_t;  // expected-error: {{declaration of anonymous union must be a definition}}
+typedef union <anonymous> __mbstate_t;  // expected-error {{declaration of anonymous union must be a definition}}
 
 
 // PR2017
 void x(); 
 int a() {
-  int r[x()];  // expected-error: {{size of array has non-integer type 'void'}}
+  int r[x()];  // expected-error {{size of array has non-integer type 'void'}}
 }
 
index cd57eac9a4938dc0f0be0258a086a75acf1a2979..682d2fb2667fdff96b08d21a577bf916a53d7bf8 100644 (file)
@@ -14,5 +14,5 @@ void f (unsigned int m)
 }
 
 // PR3048
-int x = sizeof(struct{char qq[x];}); // expected-error {{fields must have a constant size}
+int x = sizeof(struct{char qq[x];}); // expected-error {{fields must have a constant size}}
 
index e3974ad8f662b3554223f55ec9cc7ceeb5852608..e14d3b15c19757dad063efc45ac5376cb4c3411f 100644 (file)
@@ -11,5 +11,5 @@
 
 id s = @"123"; // simple
 id t = @"123" @"456"; // concat
-id u = @"123" @ blah; // expected-error: {{unexpected token}}
+id u = @"123" @ blah; // expected-error {{unexpected token}}