[cfe-commits] r148072 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/DeclSpec.h include/clang/Sema/Sema.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/Parser.cpp lib/Sema/AnalysisBasedWarnings.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaFixItUtils.cpp test/CXX/basic/basic.link/p9.cpp test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp test/FixIt/fixit-vexing-parse.cpp test/SemaCXX/condition.cpp test/SemaCXX/conditional-expr.cpp test/SemaCXX/decl-expr-ambiguity.cpp

Richard Smith richard-llvm at metafoo.co.uk
Thu Jan 12 15:53:29 PST 2012


Author: rsmith
Date: Thu Jan 12 17:53:29 2012
New Revision: 148072

URL: http://llvm.org/viewvc/llvm-project?rev=148072&view=rev
Log:
Improve 0-argument -Wvexing-parse diagnostic by adding notes with fix-its:

 - If the declarator is at the start of a line, and the previous line contained
   another declarator and ended with a comma, then that comma was probably a
   typo for a semicolon:

   int n = 0, m = 1, l = 2, // k = 5;
   myImportantFunctionCall(); // oops!

 - If removing the parentheses would correctly initialize the object, then
   produce a note suggesting that fix.

 - Otherwise, if there is a simple initializer we can suggest which performs
   value-initialization, then provide a note suggesting a correction to that
   initializer.

Sema::Declarator now tracks the location of the comma prior to the declarator in
the declaration, if there is one, to facilitate providing the note. The code to
determine an appropriate initializer from the -Wuninitialized warning has been
factored out to allow use in both that and -Wvexing-parse.

Added:
    cfe/trunk/test/FixIt/fixit-vexing-parse.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaFixItUtils.cpp
    cfe/trunk/test/CXX/basic/basic.link/p9.cpp
    cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
    cfe/trunk/test/SemaCXX/condition.cpp
    cfe/trunk/test/SemaCXX/conditional-expr.cpp
    cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jan 12 17:53:29 2012
@@ -115,6 +115,12 @@
 def warn_empty_parens_are_function_decl : Warning<
   "empty parentheses interpreted as a function declaration">,
   InGroup<VexingParse>;
+def note_empty_parens_function_call : Note<
+  "change this ',' to a ';' to call %0">;
+def note_empty_parens_default_ctor : Note<
+  "remove parentheses to declare a variable">;
+def note_empty_parens_zero_initialize : Note<
+  "replace parentheses with an initializer to declare a variable">;
 def warn_unused_function : Warning<"unused function %0">,
   InGroup<UnusedFunction>, DefaultIgnore;
 def warn_unused_member_function : Warning<"unused member function %0">,

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Thu Jan 12 17:53:29 2012
@@ -1468,6 +1468,10 @@
   /// Extension - true if the declaration is preceded by __extension__.
   bool Extension : 1;
 
+  /// \brief If this is the second or subsequent declarator in this declaration,
+  /// the location of the comma before this declarator.
+  SourceLocation CommaLoc;
+
   /// \brief If provided, the source location of the ellipsis used to describe
   /// this declarator as a parameter pack.
   SourceLocation EllipsisLoc;
@@ -1557,6 +1561,8 @@
     Attrs.clear();
     AsmLabel = 0;
     InlineParamsUsed = false;
+    CommaLoc = SourceLocation();
+    EllipsisLoc = SourceLocation();
   }
 
   /// mayOmitIdentifier - Return true if the identifier is either optional or
@@ -1846,7 +1852,11 @@
 
   void setGroupingParens(bool flag) { GroupingParens = flag; }
   bool hasGroupingParens() const { return GroupingParens; }
-  
+
+  bool isFirstDeclarator() const { return !CommaLoc.isValid(); }
+  SourceLocation getCommaLoc() const { return CommaLoc; }
+  void setCommaLoc(SourceLocation CL) { CommaLoc = CL; }
+
   bool hasEllipsis() const { return EllipsisLoc.isValid(); }
   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
   void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; }

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jan 12 17:53:29 2012
@@ -756,6 +756,9 @@
 
   bool findMacroSpelling(SourceLocation &loc, StringRef name);
 
+  /// \brief Get a string to suggest for zero-initialization of a type.
+  const char *getFixItZeroInitializerForType(QualType T) const;
+
   ExprResult Owned(Expr* E) { return E; }
   ExprResult Owned(ExprResult R) { return R; }
   StmtResult Owned(Stmt* S) { return S; }

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Jan 12 17:53:29 2012
@@ -1138,6 +1138,7 @@
 
     // Parse the next declarator.
     D.clear();
+    D.setCommaLoc(CommaLoc);
 
     // Accept attributes in an init-declarator.  In the first declarator in a
     // declaration, these would be part of the declspec.  In subsequent
@@ -2665,9 +2666,11 @@
 
   // Read struct-declarators until we find the semicolon.
   bool FirstDeclarator = true;
+  SourceLocation CommaLoc;
   while (1) {
     ParsingDeclRAIIObject PD(*this);
     FieldDeclarator DeclaratorInfo(DS);
+    DeclaratorInfo.D.setCommaLoc(CommaLoc);
 
     // Attributes are only allowed here on successive declarators.
     if (!FirstDeclarator)
@@ -2703,7 +2706,7 @@
       return;
 
     // Consume the comma.
-    ConsumeToken();
+    CommaLoc = ConsumeToken();
 
     FirstDeclarator = false;
   }

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Jan 12 17:53:29 2012
@@ -2044,6 +2044,7 @@
     BitfieldSize = true;
     Init = true;
     HasInitializer = false;
+    DeclaratorInfo.setCommaLoc(CommaLoc);
 
     // Attributes are only allowed on the second declarator.
     MaybeParseGNUAttributes(DeclaratorInfo);

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Thu Jan 12 17:53:29 2012
@@ -1067,11 +1067,12 @@
       if (Tok.isNot(tok::comma))
         break;
 
+      ParmDeclarator.clear();
+
       // Consume the comma.
-      ConsumeToken();
+      ParmDeclarator.setCommaLoc(ConsumeToken());
 
       // Parse the next declarator.
-      ParmDeclarator.clear();
       ParseDeclarator(ParmDeclarator);
     }
 

Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Thu Jan 12 17:53:29 2012
@@ -415,42 +415,15 @@
     return false;
 
   // Suggest possible initialization (if any).
-  const char *initialization = 0;
   QualType VariableTy = VD->getType().getCanonicalType();
-
-  if (VariableTy->isObjCObjectPointerType() ||
-      VariableTy->isBlockPointerType()) {
-    // Check if 'nil' is defined.
-    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil")))
-      initialization = " = nil";
-    else
-      initialization = " = 0";
-  }
-  else if (VariableTy->isRealFloatingType())
-    initialization = " = 0.0";
-  else if (VariableTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus)
-    initialization = " = false";
-  else if (VariableTy->isEnumeralType())
+  const char *Init = S.getFixItZeroInitializerForType(VariableTy);
+  if (!Init)
     return false;
-  else if (VariableTy->isPointerType() || VariableTy->isMemberPointerType()) {
-    if (S.Context.getLangOptions().CPlusPlus0x)
-      initialization = " = nullptr";
-    // Check if 'NULL' is defined.
-    else if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("NULL")))
-      initialization = " = NULL";
-    else
-      initialization = " = 0";
-  }
-  else if (VariableTy->isScalarType())
-    initialization = " = 0";
-
-  if (initialization) {
-    SourceLocation loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
-    S.Diag(loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
-      << FixItHint::CreateInsertion(loc, initialization);
-    return true;
-  }
-  return false;
+
+  SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
+  S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName()
+    << FixItHint::CreateInsertion(Loc, Init);
+  return true;
 }
 
 /// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 12 17:53:29 2012
@@ -4921,8 +4921,39 @@
       if (!T->isVoidType() && C.Fun.NumArgs == 0 && !C.Fun.isVariadic &&
           !C.Fun.TrailingReturnType &&
           C.Fun.getExceptionSpecType() == EST_None) {
-        Diag(C.Loc, diag::warn_empty_parens_are_function_decl)
-          << SourceRange(C.Loc, C.EndLoc);
+        SourceRange ParenRange(C.Loc, C.EndLoc);
+        Diag(C.Loc, diag::warn_empty_parens_are_function_decl) << ParenRange;
+
+        // If the declaration looks like:
+        //   T var1,
+        //   f();
+        // and name lookup finds a function named 'f', then the ',' was
+        // probably intended to be a ';'.
+        if (!D.isFirstDeclarator() && D.getIdentifier()) {
+          FullSourceLoc Comma(D.getCommaLoc(), SourceMgr);
+          FullSourceLoc Name(D.getIdentifierLoc(), SourceMgr);
+          if (Comma.getFileID() != Name.getFileID() ||
+              Comma.getSpellingLineNumber() != Name.getSpellingLineNumber()) {
+            LookupResult Result(*this, D.getIdentifier(), SourceLocation(),
+                                LookupOrdinaryName);
+            if (LookupName(Result, S))
+              Diag(D.getCommaLoc(), diag::note_empty_parens_function_call)
+                << FixItHint::CreateReplacement(D.getCommaLoc(), ";") << NewFD;
+          }
+        }
+        const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
+        // Empty parens mean value-initialization, and no parens mean default
+        // initialization. These are equivalent if the default constructor is
+        // user-provided, or if zero-initialization is a no-op.
+        if (RD && (RD->isEmpty() || RD->hasUserProvidedDefaultConstructor()))
+          Diag(C.Loc, diag::note_empty_parens_default_ctor)
+            << FixItHint::CreateRemoval(ParenRange);
+        else if (const char *Init = getFixItZeroInitializerForType(T))
+          Diag(C.Loc, diag::note_empty_parens_zero_initialize)
+            << FixItHint::CreateReplacement(ParenRange, Init);
+        else if (LangOpts.CPlusPlus0x)
+          Diag(C.Loc, diag::note_empty_parens_zero_initialize)
+            << FixItHint::CreateReplacement(ParenRange, "{}");
       }
     }
 

Modified: cfe/trunk/lib/Sema/SemaFixItUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaFixItUtils.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaFixItUtils.cpp (original)
+++ cfe/trunk/lib/Sema/SemaFixItUtils.cpp Thu Jan 12 17:53:29 2012
@@ -158,3 +158,31 @@
 
   return false;
 }
+
+const char *Sema::getFixItZeroInitializerForType(QualType T) const {
+  // Suggest 'nil' if it's defined and appropriate.
+  if ((T->isObjCObjectPointerType() || T->isBlockPointerType()) &&
+      PP.getMacroInfo(&getASTContext().Idents.get("nil")))
+    return " = nil";
+  if (T->isRealFloatingType())
+    return " = 0.0";
+  if (T->isBooleanType() && LangOpts.CPlusPlus)
+    return " = false";
+  if (T->isPointerType() || T->isMemberPointerType()) {
+    if (LangOpts.CPlusPlus0x)
+      return " = nullptr";
+    // Check if 'NULL' is defined.
+    else if (PP.getMacroInfo(&getASTContext().Idents.get("NULL")))
+      return " = NULL";
+  }
+  if (T->isEnumeralType())
+    return 0;
+  if (T->isScalarType())
+    return " = 0";
+  const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
+  if (LangOpts.CPlusPlus0x && RD && !RD->hasUserProvidedDefaultConstructor())
+    return "{}";
+  if (T->isAggregateType())
+    return " = {}";
+  return 0;
+}

Modified: cfe/trunk/test/CXX/basic/basic.link/p9.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.link/p9.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.link/p9.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.link/p9.cpp Thu Jan 12 17:53:29 2012
@@ -6,5 +6,5 @@
 // First bullet: two names with external linkage that refer to
 // different kinds of entities.
 void f() {
-  int N(); // expected-error{{redefinition}} expected-warning{{interpreted as a function declaration}}
+  int N(); // expected-error{{redefinition}} expected-warning{{interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
 }

Modified: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp Thu Jan 12 17:53:29 2012
@@ -12,26 +12,26 @@
 
 namespace test0 {
   namespace ns { void foo(); } // expected-note {{target of using declaration}}
-  int foo(); // expected-note {{conflicting declaration}}
+  int foo(void); // expected-note {{conflicting declaration}}
   using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
 }
 
 namespace test1 {
   namespace ns { void foo(); } // expected-note {{target of using declaration}}
   using ns::foo; //expected-note {{using declaration}}
-  int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+  int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}}
 }
 
 namespace test2 {
   namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
   void test0() {
-    int foo(); // expected-note {{conflicting declaration}} expected-warning{{function declaration}}
+    int foo(void); // expected-note {{conflicting declaration}}
     using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
   }
 
   void test1() {
     using ns::foo; //expected-note {{using declaration}}
-    int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}} expected-warning{{function declaration}}
+    int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}}
   }
 }
 
@@ -39,7 +39,7 @@
   namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
   class Test0 {
     void test() {
-      int foo(); // expected-note {{conflicting declaration}} expected-warning{{function declaration}}
+      int foo(void); // expected-note {{conflicting declaration}}
       using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
     }
   };
@@ -47,7 +47,7 @@
   class Test1 {
     void test() {
       using ns::foo; //expected-note {{using declaration}}
-      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}} expected-warning{{function declaration}}
+      int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}}
     }
   };
 }
@@ -56,7 +56,7 @@
   namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
   template <typename> class Test0 {
     void test() {
-      int foo(); // expected-note {{conflicting declaration}} expected-warning{{function declaration}}
+      int foo(void); // expected-note {{conflicting declaration}}
       using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
     }
   };
@@ -64,7 +64,7 @@
   template <typename> class Test1 {
     void test() {
       using ns::foo; //expected-note {{using declaration}}
-      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}} expected-warning{{function declaration}}
+      int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}}
     }
   };
 }

Added: cfe/trunk/test/FixIt/fixit-vexing-parse.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-vexing-parse.cpp?rev=148072&view=auto
==============================================================================
--- cfe/trunk/test/FixIt/fixit-vexing-parse.cpp (added)
+++ cfe/trunk/test/FixIt/fixit-vexing-parse.cpp Thu Jan 12 17:53:29 2012
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -verify -x c++ %s
+// RUN: %clang_cc1 -fdiagnostics-parseable-fixits -x c++ %s 2>&1 | FileCheck %s
+
+struct S {
+  int n;
+};
+
+struct T {
+  T();
+  int n;
+};
+
+struct U {
+  ~U();
+  int n;
+};
+
+struct V {
+  ~V();
+};
+
+struct W : V {
+};
+
+struct X : U {
+};
+
+int F1();
+S F2();
+
+namespace N {
+  void test() {
+    // CHECK: fix-it:"{{.*}}":{34:9-34:11}:" = {}"
+    S s1(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
+
+    // CHECK: fix-it:"{{.*}}":{38:9-38:10}:";"
+    // CHECK: fix-it:"{{.*}}":{39:7-39:9}:" = {}"
+    S s2, // expected-note {{change this ',' to a ';' to call 'F2'}}
+    F2(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
+
+    // CHECK: fix-it:"{{.*}}":{43:9-43:11}:""
+    // CHECK: fix-it:"{{.*}}":{44:9-44:11}:""
+    T t1(), // expected-warning {{function declaration}} expected-note {{remove parentheses}}
+      t2(); // expected-warning {{function declaration}} expected-note {{remove parentheses}}
+
+    // CHECK: fix-it:"{{.*}}":{47:8-47:10}:" = {}"
+    U u(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
+
+    // CHECK: fix-it:"{{.*}}":{50:8-50:10}:""
+    V v(); // expected-warning {{function declaration}} expected-note {{remove parentheses}}
+
+    // CHECK: fix-it:"{{.*}}":{53:8-53:10}:""
+    W w(); // expected-warning {{function declaration}} expected-note {{remove parentheses}}
+
+    // TODO: Removing the parens here would not initialize U::n.
+    // Maybe suggest an " = X()" initializer for this case?
+    // Maybe suggest removing the parens anyway?
+    X x(); // expected-warning {{function declaration}}
+
+    // CHECK: fix-it:"{{.*}}":{61:11-61:13}:" = 0"
+    int n1(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
+
+    // CHECK: fix-it:"{{.*}}":{65:11-65:12}:";"
+    // CHECK: fix-it:"{{.*}}":{66:7-66:9}:" = 0"
+    int n2, // expected-note {{change this ',' to a ';' to call 'F1'}}
+    F1(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
+
+    // CHECK: fix-it:"{{.*}}":{69:13-69:15}:" = 0.0"
+    double d(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
+
+    typedef void *Ptr;
+
+    // CHECK: fix-it:"{{.*}}":{74:10-74:12}:" = 0"
+    Ptr p(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
+
+#define NULL 0
+    // CHECK: fix-it:"{{.*}}":{78:10-78:12}:" = NULL"
+    Ptr p(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
+  }
+}

Modified: cfe/trunk/test/SemaCXX/condition.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/condition.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/condition.cpp (original)
+++ cfe/trunk/test/SemaCXX/condition.cpp Thu Jan 12 17:53:29 2012
@@ -7,7 +7,7 @@
 
   typedef int arr[10];
   while (arr x=0) ; // expected-error {{an array type is not allowed here}} expected-error {{array initializer must be an initializer list}}
-  while (int f()=0) ; // expected-warning {{interpreted as a function declaration}} expected-error {{a function type is not allowed here}}
+  while (int f()=0) ; // expected-warning {{interpreted as a function declaration}} expected-note {{initializer}} expected-error {{a function type is not allowed here}}
 
   struct S {} s;
   if (s) ++x; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}

Modified: cfe/trunk/test/SemaCXX/conditional-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conditional-expr.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conditional-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/conditional-expr.cpp Thu Jan 12 17:53:29 2012
@@ -96,8 +96,8 @@
   (void)(i1 ? BadDerived() : BadBase());
 
   // b2.1 (hierarchy stuff)
-  const Base constret(); // expected-warning {{interpreted as a function declaration}}
-  const Derived constder(); // expected-warning {{interpreted as a function declaration}}
+  extern const Base constret();
+  extern const Derived constder();
   // should use const overload
   A a1((i1 ? constret() : Base()).trick());
   A a2((i1 ? Base() : constret()).trick());

Modified: cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp?rev=148072&r1=148071&r2=148072&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp (original)
+++ cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp Thu Jan 12 17:53:29 2012
@@ -26,15 +26,15 @@
   T(*d)(int(p)); // expected-warning {{parentheses were disambiguated as a function declarator}} expected-note {{previous definition is here}}
   typedef T(*td)(int(p));
   extern T(*tp)(int(p));
-  T d3(); // expected-warning {{empty parentheses interpreted as a function declaration}}
+  T d3(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
   T d3v(void);
   typedef T d3t();
   extern T f3();
-  __typeof(*T()) f4(); // expected-warning {{empty parentheses interpreted as a function declaration}}
+  __typeof(*T()) f4(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
   typedef void *V;
   __typeof(*V()) f5();
   T multi1,
-    multi2(); // expected-warning {{empty parentheses interpreted as a function declaration}}
+    multi2(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
   T(d)[5]; // expected-error {{redefinition of 'd'}}
   typeof(int[])(f) = { 1, 2 }; // expected-error {{extension used}}
   void(b)(int);
@@ -43,6 +43,20 @@
   int(d3(int()));
 }
 
+struct RAII {
+  RAII();
+  ~RAII();
+};
+
+void func();
+namespace N {
+  void emptyParens() {
+    RAII raii(); // expected-warning {{function declaration}} expected-note {{remove parentheses to declare a variable}}
+    int a, b, c, d, e, // expected-note {{change this ',' to a ';' to call 'func'}}
+    func(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
+  }
+}
+
 class C { };
 void fn(int(C)) { } // void fn(int(*fp)(C c)) { } expected-note{{candidate function}}
                     // not: void fn(int C);





More information about the cfe-commits mailing list