diff options
-rw-r--r-- | include/clang/Basic/DiagnosticParseKinds.td | 3 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 19 | ||||
-rw-r--r-- | test/CXX/basic/basic.link/p9.cpp | 2 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp | 12 | ||||
-rw-r--r-- | test/SemaCXX/decl-expr-ambiguity.cpp | 10 |
7 files changed, 36 insertions, 28 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index bd30f486b7..919d105a51 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -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>; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 3a11d14b22..e15352bcd5 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index d3c8211372..ee4a51e184 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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 diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8353c087d5..3e9e66d55d 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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 diff --git a/test/CXX/basic/basic.link/p9.cpp b/test/CXX/basic/basic.link/p9.cpp index c895253c68..d8969ba1ba 100644 --- a/test/CXX/basic/basic.link/p9.cpp +++ b/test/CXX/basic/basic.link/p9.cpp @@ -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}} } diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp index b1dcf4d015..303df8d230 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp @@ -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}} } }; } diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp index 555e89ca7d..4a93b9ae71 100644 --- a/test/SemaCXX/decl-expr-ambiguity.cpp +++ b/test/SemaCXX/decl-expr-ambiguity.cpp @@ -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); |