]> granicus.if.org Git - clang/commitdiff
Tweak to r147599 for PR10828: Move the check from the parser into sema, and use
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 6 Jan 2012 01:31:20 +0000 (01:31 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 6 Jan 2012 01:31:20 +0000 (01:31 +0000)
the Semantic Powers to only warn on class types (or dependent types), where the
constructor or destructor could do something interesting.

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

include/clang/Basic/DiagnosticParseKinds.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Parse/ParseDecl.cpp
lib/Sema/SemaDecl.cpp
test/CXX/basic/basic.link/p9.cpp
test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
test/SemaCXX/decl-expr-ambiguity.cpp

index bd30f486b7a66809735a0bb99aa68d5787364b76..919d105a514c47b7fa712f09210c3f6646554705 100644 (file)
@@ -389,9 +389,6 @@ def err_expected_equal_after_declarator : Error<
 def warn_parens_disambiguated_as_function_decl : Warning<
   "parentheses were disambiguated as a function declarator">,
   InGroup<VexingParse>;
-def warn_empty_parens_are_function_decl : Warning<
-  "empty parentheses interpreted as a function declaration">,
-  InGroup<VexingParse>;
 def warn_dangling_else : Warning<
   "add explicit braces to avoid dangling else">,
   InGroup<DanglingElse>;
index 3a11d14b22b928f354817ac460022df308bdbc1f..e15352bcd5d960747cee4f2e66744c186cf4286f 100644 (file)
@@ -112,6 +112,9 @@ def warn_unused_exception_param : Warning<"unused exception parameter %0">,
   InGroup<UnusedExceptionParameter>, DefaultIgnore;
 def warn_decl_in_param_list : Warning<
   "declaration of %0 will not be visible outside of this function">;
+def warn_empty_parens_are_function_decl : Warning<
+  "empty parentheses interpreted as a function declaration">,
+  InGroup<VexingParse>;
 def warn_unused_function : Warning<"unused function %0">,
   InGroup<UnusedFunction>, DefaultIgnore;
 def warn_unused_member_function : Warning<"unused member function %0">,
index d3c821137239cc47692d3d48f55d4d1e09deca7b..ee4a51e184a2b8372a156ba3b3ee092fcacb1e02 100644 (file)
@@ -1111,21 +1111,6 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
   if (FirstDecl)
     DeclsInGroup.push_back(FirstDecl);
 
-  // In C++, "T var();" at block scope is probably an attempt to initialize a
-  // variable, not a function declaration. We don't catch this case earlier,
-  // since there is no ambiguity here.
-  if (getLang().CPlusPlus && Context != Declarator::FileContext &&
-      D.getNumTypeObjects() == 1 && D.isFunctionDeclarator() &&
-      D.getDeclSpec().getStorageClassSpecAsWritten()
-        == DeclSpec::SCS_unspecified &&
-      D.getDeclSpec().getTypeSpecType() != DeclSpec::TST_void) {
-    DeclaratorChunk &C = D.getTypeObject(0);
-    if (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);
-  }
-
   bool ExpectSemi = Context != Declarator::ForContext;
 
   // If we don't have a comma, it is either the end of the list (a ';') or an
index 8353c087d5b47302cb4bbd61a3edc897776ef037..3e9e66d55dcc70a09197c47f71f6b3122c9e790d 100644 (file)
@@ -4904,6 +4904,25 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
         FunctionTemplate->setInvalidDecl();
     }
 
+    // If we see "T var();" at block scope, where T is a class type, it is
+    // probably an attempt to initialize a variable, not a function declaration.
+    // We don't catch this case earlier, since there is no ambiguity here.
+    if (!FunctionTemplate && D.getFunctionDefinitionKind() == FDK_Declaration &&
+        CurContext->isFunctionOrMethod() &&
+        D.getNumTypeObjects() == 1 && D.isFunctionDeclarator() &&
+        D.getDeclSpec().getStorageClassSpecAsWritten()
+          == DeclSpec::SCS_unspecified) {
+      QualType T = R->getAs<FunctionType>()->getResultType();
+      DeclaratorChunk &C = D.getTypeObject(0);
+      if ((T->isDependentType() || T->isRecordType()) &&
+          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);
+      }
+    }
+
     // C++ [dcl.fct.spec]p5:
     //   The virtual specifier shall only be used in declarations of
     //   nonstatic class member functions that appear within a
index c895253c68fb6bb892d553efe3b0a141f36cc321..d8969ba1ba988ba050069201abac31f8fa9328d7 100644 (file)
@@ -6,5 +6,5 @@ namespace N { } // expected-note{{here}}
 // 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}}
 }
index b1dcf4d0154368234008b508467250a694a45fdf..303df8d23043c687a2e4055e816c2a2dbeacd85d 100644 (file)
@@ -25,13 +25,13 @@ namespace test1 {
 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(); // 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(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
   }
 }
 
@@ -39,7 +39,7 @@ namespace test3 {
   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(); // expected-note {{conflicting declaration}}
       using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
     }
   };
@@ -47,7 +47,7 @@ namespace test3 {
   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(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
     }
   };
 }
@@ -56,7 +56,7 @@ namespace test4 {
   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(); // expected-note {{conflicting declaration}}
       using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
     }
   };
@@ -64,7 +64,7 @@ namespace test4 {
   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(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
     }
   };
 }
index 555e89ca7de2e3fbc3f4b91cb9aec15020455e65..4a93b9ae71dc73b10757b4d2e29e1368d251a027 100644 (file)
@@ -26,9 +26,13 @@ void f() {
   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}}
-  typedef T d3t();
-  extern T f3();
+  S d3(); // expected-warning {{empty parentheses interpreted as a function declaration}}
+  S d3v(void);
+  typedef S d3t();
+  extern S f3();
+  __typeof(*T()) f4(); // expected-warning {{empty parentheses interpreted as a function declaration}}
+  S multi1,
+    multi2(); // expected-warning {{empty parentheses interpreted as a function declaration}}
   T(d)[5]; // expected-error {{redefinition of 'd'}}
   typeof(int[])(f) = { 1, 2 }; // expected-error {{extension used}}
   void(b)(int);