]> granicus.if.org Git - clang/commitdiff
Make one expected-diag directive match exactly one actual diagnostic.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 7 Feb 2009 19:52:04 +0000 (19:52 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 7 Feb 2009 19:52:04 +0000 (19:52 +0000)
This uncovers some bugs, so several test cases now fail.

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

14 files changed:
Driver/DiagChecker.cpp
test/Sema/array-constraint.c
test/Sema/flexible-array-init.c
test/Sema/incomplete-decl.c
test/Sema/pointer-addition.c
test/SemaCXX/condition.cpp
test/SemaCXX/dcl_init_aggr.cpp
test/SemaCXX/dynamic-cast.cpp
test/SemaCXX/functional-cast.cpp
test/SemaCXX/namespace.cpp
test/SemaCXX/new-delete.cpp
test/SemaCXX/overload-member-call.cpp
test/SemaCXX/try-catch.cpp
test/SemaObjC/check-dup-objc-decls-1.m

index 5b1669b18ddaa393dbdb2a5548c1461b210077f8..346d9e0b06366415cfa2fbcc18aac0fc22dc22dc 100644 (file)
@@ -43,6 +43,15 @@ static void EmitError(Preprocessor &PP, SourceLocation Pos, const char *String){
 //
 // You can place as many diagnostics on one line as you wish. To make the code
 // more readable, you can use slash-newline to separate out the diagnostics.
+//
+// The simple syntax above allows each specification to match exactly one error.
+// You can use the extended syntax to customize this. The extended syntax is
+// "expected-<type> <n> {{diag text}}", where <type> is one of "error",
+// "warning" or "note", and <n> is a positive integer. This allows the
+// diagnostic to appear as many times as specified. Example:
+//
+//   void f(); // expected-note 2 {{previous declaration is here}}
+//
 
 /// FindDiagnostics - Go through the comment and see if it indicates expected
 /// diagnostics. If so, then put them in a diagnostic list.
@@ -73,6 +82,24 @@ static void FindDiagnostics(const char *CommentStart, unsigned CommentLen,
            isspace(CommentStart[0]))
       ++CommentStart;
     
+    // Default, if we find the '{' now, is 1 time.
+    int Times = 1;
+    int Temp = 0;
+    // In extended syntax, there could be a digit now.
+    while (CommentStart != CommentEnd &&
+           CommentStart[0] >= '0' && CommentStart[0] <= '9') {
+      Temp *= 10;
+      Temp += CommentStart[0] - '0';
+      ++CommentStart;
+    }
+    if (Temp > 0)
+      Times = Temp;
+    
+    // Skip whitespace again.
+    while (CommentStart != CommentEnd &&
+           isspace(CommentStart[0]))
+      ++CommentStart;
+    
     // We should have a {{ now.
     if (CommentEnd-CommentStart < 2 ||
         CommentStart[0] != '{' || CommentStart[1] != '{') {
@@ -81,7 +108,7 @@ static void FindDiagnostics(const char *CommentStart, unsigned CommentLen,
       else
         EmitError(PP, Pos, "cannot find start ('{{') of expected string");
       return;
-    }    
+    }
     CommentStart += 2;
 
     // Find the }}.
@@ -103,8 +130,10 @@ static void FindDiagnostics(const char *CommentStart, unsigned CommentLen,
     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));
-    
+    // Add is possibly multiple times.
+    for (int i = 0; i < Times; ++i)
+      ExpectedDiags.push_back(std::make_pair(Pos, Msg));
+
     CommentStart = ExpectedEnd;
   }
 }
@@ -178,31 +207,39 @@ static bool CompareDiagLists(SourceManager &SourceMgr,
                              const_diag_iterator d1_end,
                              const_diag_iterator d2_begin,
                              const_diag_iterator d2_end,
-                             const char *Msg) {
-  DiagList DiffList;
+                             const char *MsgLeftOnly,
+                             const char *MsgRightOnly) {
+  DiagList LeftOnly;
+  DiagList Left(d1_begin, d1_end);
+  DiagList Right(d2_begin, d2_end);
 
-  for (const_diag_iterator I = d1_begin, E = d1_end; I != E; ++I) {
+  for (const_diag_iterator I = Left.begin(), E = Left.end(); I != E; ++I) {
     unsigned LineNo1 = SourceMgr.getInstantiationLineNumber(I->first);
     const std::string &Diag1 = I->second;
-    bool Found = false;
 
-    for (const_diag_iterator II = d2_begin, IE = d2_end; II != IE; ++II) {
+    DiagList::iterator II, IE;
+    for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
       unsigned LineNo2 = SourceMgr.getInstantiationLineNumber(II->first);
       if (LineNo1 != LineNo2) continue;
 
       const std::string &Diag2 = II->second;
       if (Diag2.find(Diag1) != std::string::npos ||
           Diag1.find(Diag2) != std::string::npos) {
-        Found = true;
         break;
       }
     }
-
-    if (!Found)
-      DiffList.push_back(std::make_pair(I->first, Diag1));
+    if (II == IE) {
+      // Not found.
+      LeftOnly.push_back(*I);
+    } else {
+      // Found. The same cannot be found twice.
+      Right.erase(II);
+    }
   }
+  // Now all that's left in Right are those that were not matched.
 
-  return PrintProblem(SourceMgr, DiffList.begin(), DiffList.end(), Msg);
+  return PrintProblem(SourceMgr, LeftOnly.begin(), LeftOnly.end(), MsgLeftOnly)
+       | PrintProblem(SourceMgr, Right.begin(), Right.end(), MsgRightOnly);
 }
 
 /// CheckResults - This compares the expected results to those that
@@ -227,44 +264,27 @@ static bool CheckResults(Preprocessor &PP,
   //   Seen \ Expected - set seen but not expected
   bool HadProblem = false;
 
-  // See if there were errors that were expected but not seen.
+  // See if there are error mismatches.
   HadProblem |= CompareDiagLists(SourceMgr,
                                  ExpectedErrors.begin(), ExpectedErrors.end(),
                                  Diags.err_begin(), Diags.err_end(),
-                                 "Errors expected but not seen:");
-
-  // See if there were errors that were seen but not expected.
-  HadProblem |= CompareDiagLists(SourceMgr,
-                                 Diags.err_begin(), Diags.err_end(),
-                                 ExpectedErrors.begin(), ExpectedErrors.end(),
+                                 "Errors expected but not seen:",
                                  "Errors seen but not expected:");
 
-  // See if there were warnings that were expected but not seen.
+  // See if there are warning mismatches.
   HadProblem |= CompareDiagLists(SourceMgr,
                                  ExpectedWarnings.begin(),
                                  ExpectedWarnings.end(),
                                  Diags.warn_begin(), Diags.warn_end(),
-                                 "Warnings expected but not seen:");
-
-  // See if there were warnings that were seen but not expected.
-  HadProblem |= CompareDiagLists(SourceMgr,
-                                 Diags.warn_begin(), Diags.warn_end(),
-                                 ExpectedWarnings.begin(),
-                                 ExpectedWarnings.end(),
+                                 "Warnings expected but not seen:",
                                  "Warnings seen but not expected:");
 
-  // See if there were notes that were expected but not seen.
+  // See if there are note mismatches.
   HadProblem |= CompareDiagLists(SourceMgr,
                                  ExpectedNotes.begin(),
                                  ExpectedNotes.end(),
                                  Diags.note_begin(), Diags.note_end(),
-                                 "Notes expected but not seen:");
-
-  // See if there were notes that were seen but not expected.
-  HadProblem |= CompareDiagLists(SourceMgr,
-                                 Diags.note_begin(), Diags.note_end(),
-                                 ExpectedNotes.begin(),
-                                 ExpectedNotes.end(),
+                                 "Notes expected but not seen:",
                                  "Notes seen but not expected:");
 
   return HadProblem;
index 69475b76f64701ef7976611dda94e3876b363d5a..d35b0acdfe7500dad4ad73669519f524e8590441 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: clang -fsyntax-only -verify -pedantic %s
 
-struct s;  // expected-note {{forward declaration of 'struct s'}}
+struct s;  // expected-note {{forward declaration of 'struct s'}}
 struct s* t (struct s z[]) {   // expected-error {{array has incomplete element type}}
   return z;
 }
index 9ef6eb3bc00a98f68a2fa369faddc564c39ab58c..99ef66abe99afa296c684c7033c4abecc2c69b91 100644 (file)
@@ -12,7 +12,7 @@ void test() {
 
 struct foo { 
   int x; 
-  int y[]; // expected-note{{initialized flexible array member 'y' is here}}
+  int y[]; // expected-note 3 {{initialized flexible array member 'y' is here}}
 }; 
 struct bar { struct foo z; };
      
index bd603681d64184ba1355322f86a0e761f97f47d6..be52cfd7075cde530b413a10e7527b0ff570d37d 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: clang -fsyntax-only -verify %s
 
-struct foo; // expected-note {{forward declaration of 'struct foo'}}
+struct foo; // expected-note {{forward declaration of 'struct foo'}}
 
 void b;  // expected-error {{variable has incomplete type 'void'}}
 struct foo f; // expected-error {{variable has incomplete type 'struct foo'}}
index 81a1dc06c1f2651f08505c69eb06c59343fdad62..3a924b00825c5d7935728942bf30de832ade76d5 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: clang %s -fsyntax-only -verify -pedantic
 
-typedef struct S S; // expected-note{{forward declaration of 'struct S'}}
+typedef struct S S; // expected-note 3 {{forward declaration of 'struct S'}}
 void a(S* b, void* c) {
   void (*fp)(int) = 0;
   b++;       // expected-error {{arithmetic on pointer to incomplete type}}
index eb1e095c9c74a0e0e98999cfbb0e62e7caf72f83..babb8271088127e148272a8e696aa93748990bb7 100644 (file)
@@ -20,7 +20,7 @@ void test() {
   while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize 'x' with an rvalue of type 'int'}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}}
   switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{incompatible type}}
 
-  if (int x=0) { // expected-note {{previous definition is here}}
+  if (int x=0) { // expected-note {{previous definition is here}}
     int x;  // expected-error {{redefinition of 'x'}}
   }
   else
index fbe7de156391ecac7c3649cc0317c3fe49fa5595..bed526d399a030b61c8f8b9a78b1e4f15a41f0c5 100644 (file)
@@ -15,7 +15,7 @@ struct NonAggregate {
 };
 NonAggregate non_aggregate_test = { 1, 2 }; // expected-error{{initialization of non-aggregate type 'struct NonAggregate' with an initializer list}}
 
-NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error{{initialization of non-aggregate type 'struct NonAggregate' with an initializer list}}
+NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error 2 {{initialization of non-aggregate type 'struct NonAggregate' with an initializer list}}
 
 
 // C++ [dcl.init.aggr]p3
@@ -40,8 +40,8 @@ char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in ar
 struct TooFew { int a; char* b; int c; }; 
 TooFew too_few = { 1, "asdf" }; // okay
 
-struct NoDefaultConstructor { // expected-note{{candidate function}}
-  NoDefaultConstructor(int); // expected-note{{candidate function}}
+struct NoDefaultConstructor { // expected-note 5 {{candidate function}}
+  NoDefaultConstructor(int); // expected-note 5 {{candidate function}}
 };
 struct TooFewError {
   int a;
@@ -53,7 +53,7 @@ TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}}
 TooFewError too_few_okay2[2] = { 1, 1 };
 TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}}
 
-NoDefaultConstructor too_few_error3[3] = { }; // expected-error{{no matching constructor}}
+NoDefaultConstructor too_few_error3[3] = { }; // expected-error 3 {{no matching constructor}}
 
 // C++ [dcl.init.aggr]p8
 struct Empty { };
index 654f2e41bc5473a9fb7677221f44bea9b765b0eb..1fa8c3dc2a33872feae1f516a9958cdfa48c4366 100644 (file)
@@ -8,7 +8,7 @@ struct D : private A {};
 struct E : A {};
 struct F : B, E {};
 
-struct Incomplete; // expected-note{{forward declaration of 'struct Incomplete'}}
+struct Incomplete; // expected-note 2 {{forward declaration of 'struct Incomplete'}}
 
 struct Poly
 {
index 3b65031d9c48dba49187f95c0189d9fa95a44b91..9db742e732f8fcf79f2802a3b773436af91d44a0 100644 (file)
@@ -10,8 +10,8 @@ struct InitViaConstructor {
 
 // FIXME: error messages for implicitly-declared special member
 // function candidates are very poor
-struct NoValueInit { // expected-note{{candidate function}} 
-  NoValueInit(int i, int j); // expected-note{{candidate function}}
+struct NoValueInit { // expected-note 2 {{candidate function}} 
+  NoValueInit(int i, int j); // expected-note 2 {{candidate function}}
 };
 
 void test_cxx_functional_value_init() {
index 7af25ec35f3961a40a51502ff13d3c4cbce6d73a..ea7737e8a94800ed0bfebd8a18b841473e69bfeb 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: clang -fsyntax-only -verify %s 
-namespace A { // expected-note {{previous definition is here}}
+namespace A { // expected-note {{previous definition is here}}
   int A;
   void f() { A = 0; }
 }
index ce96897e1f85edcc74fc29112a1fa0dd815d3068..5618b47f2089af4efe60117f30957040d686af4f 100644 (file)
@@ -5,8 +5,8 @@
 struct S // expected-note {{candidate}}
 {
   S(int, int, double); // expected-note {{candidate}}
-  S(double, int); // expected-note {{candidate}} expected-note {{candidate}}
-  S(float, int); // expected-note {{candidate}} expected-note {{candidate}}
+  S(double, int); // expected-note 2 {{candidate}}
+  S(float, int); // expected-note 2 {{candidate}}
 };
 struct T; // expected-note{{forward declaration of 'struct T'}}
 struct U
@@ -18,9 +18,9 @@ struct V : U
 {
 };
 
-void* operator new(size_t); // expected-note {{candidate}}
-void* operator new(size_t, int*); // expected-note {{candidate}}
-void* operator new(size_t, float*); // expected-note {{candidate}}
+void* operator new(size_t); // expected-note {{candidate}}
+void* operator new(size_t, int*); // expected-note {{candidate}}
+void* operator new(size_t, float*); // expected-note {{candidate}}
 
 void good_news()
 {
index 8b7b148b3f892028eaccd402956b39a8ba24a6f8..07936e7eecc5be40c0ac8c2276f237c3b3ca64c1 100644 (file)
@@ -1,8 +1,8 @@
 // RUN: clang -fsyntax-only -verify %s
 
 struct X {
-  int& f(int) const; // expected-note{{candidate function}}
-  float& f(int); // expected-note{{candidate function}}
+  int& f(int) const; // expected-note 2 {{candidate function}}
+  float& f(int); // expected-note 2 {{candidate function}}
 
   void test_f(int x) const {
     int& i = f(x);
@@ -12,9 +12,9 @@ struct X {
     float& f2 = f(x);
   }
 
-  int& g(int) const; // expected-note{{candidate function}}
-  float& g(int); // expected-note{{candidate function}}
-  static double& g(double); // expected-note{{candidate function}}
+  int& g(int) const; // expected-note 2 {{candidate function}}
+  float& g(int); // expected-note 2 {{candidate function}}
+  static double& g(double); // expected-note 2 {{candidate function}}
 
   void h(int);
 
index 0d72f119df7006421febe396961e4257c90e23b6..cb5d0f84548c105c055958e0abdc61fa1d96d1af 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: clang -fsyntax-only -verify %s
 
-struct A; // expected-note{{forward declaration of 'struct A'}}
+struct A; // expected-note 3 {{forward declaration of 'struct A'}}
 
 void f()
 {
index fa9b8674be0dd55960f07fb3e957adfb1fb3b1c9..54988501136aa4cf24b1157b970620ae0ff0be87 100644 (file)
@@ -18,13 +18,13 @@ typedef int OBJECT; // expected-note {{previous definition is here}}
 @class OBJECT ;        // expected-error {{redefinition of 'OBJECT' as different kind of symbol}}
 
 
-typedef int Gorf;  // expected-note {{previous definition is here}}
+typedef int Gorf;  // expected-note {{previous definition is here}}
 
 @interface Gorf @end // expected-error {{redefinition of 'Gorf' as different kind of symbol}}
 
 void Gorf() // expected-error {{redefinition of 'Gorf' as different kind of symbol}}
 {
-       int Bar, Foo, FooBar;
+  int Bar, Foo, FooBar;
 }
 
 @protocol P -im1; @end