From a60a6db73f36f72ed7ad1474b713630d938c42eb Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 6 Jul 2015 01:04:39 +0000 Subject: [PATCH] When we see something that looks like a constructor with a return type, only issue one error, not two. llvm-svn: 241424 --- clang/lib/Sema/SemaDecl.cpp | 13 +++++++------ clang/test/CXX/class/class.mem/p2.cpp | 7 ++----- clang/test/CXX/drs/dr1xx.cpp | 4 ++-- clang/test/Parser/cxx-default-delete.cpp | 2 +- clang/test/SemaCXX/constructor.cpp | 3 +-- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6508d6f04bb2..3c0e83c5a25b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4742,15 +4742,16 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, } } - if (DiagnoseClassNameShadow(DC, NameInfo)) - // If this is a typedef, we'll end up spewing multiple diagnostics. - // Just return early; it's safer. - if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) - return nullptr; - TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType R = TInfo->getType(); + if (!R->isFunctionType() && DiagnoseClassNameShadow(DC, NameInfo)) + // If this is a typedef, we'll end up spewing multiple diagnostics. + // Just return early; it's safer. If this is a function, let the + // "constructor cannot have a return type" diagnostic handle it. + if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) + return nullptr; + if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo, UPPC_DeclarationType)) D.setInvalidType(); diff --git a/clang/test/CXX/class/class.mem/p2.cpp b/clang/test/CXX/class/class.mem/p2.cpp index d45c03860654..1f0dfd05a20d 100644 --- a/clang/test/CXX/class/class.mem/p2.cpp +++ b/clang/test/CXX/class/class.mem/p2.cpp @@ -76,13 +76,10 @@ namespace PR12629 { namespace PR12688 { struct S { - // FIXME: Producing one error saying this can't have the same name - // as the class because it's not a constructor, then producing - // another error saying this can't have a return type because - // it is a constructor, is redundant and inconsistent. + // FIXME: Maybe suppress the "constructor cannot have a return type" error + // if the return type is invalid. nonsense S() throw (more_nonsense); // \ // expected-error {{'nonsense'}} \ - // expected-error {{has the same name as its class}} \ // expected-error {{constructor cannot have a return type}} }; } diff --git a/clang/test/CXX/drs/dr1xx.cpp b/clang/test/CXX/drs/dr1xx.cpp index cc6c5af81708..d8d9307a5ebb 100644 --- a/clang/test/CXX/drs/dr1xx.cpp +++ b/clang/test/CXX/drs/dr1xx.cpp @@ -943,10 +943,10 @@ namespace dr188 { // dr188: yes namespace dr194 { // dr194: yes struct A { A(); - void A(); // expected-error {{has the same name as its class}} expected-error {{constructor cannot have a return type}} + void A(); // expected-error {{constructor cannot have a return type}} }; struct B { - void B(); // expected-error {{has the same name as its class}} expected-error {{constructor cannot have a return type}} + void B(); // expected-error {{constructor cannot have a return type}} B(); }; struct C { diff --git a/clang/test/Parser/cxx-default-delete.cpp b/clang/test/Parser/cxx-default-delete.cpp index df24b3d0075a..8766d861732e 100644 --- a/clang/test/Parser/cxx-default-delete.cpp +++ b/clang/test/Parser/cxx-default-delete.cpp @@ -19,5 +19,5 @@ struct foo { void baz() = delete; struct quux { - int quux() = default; // expected-error{{constructor cannot have a return type}} expected-error {{member 'quux' has the same name as its class}} + int quux() = default; // expected-error{{constructor cannot have a return type}} }; diff --git a/clang/test/SemaCXX/constructor.cpp b/clang/test/SemaCXX/constructor.cpp index fa930bdb95dc..105605c6e37b 100644 --- a/clang/test/SemaCXX/constructor.cpp +++ b/clang/test/SemaCXX/constructor.cpp @@ -15,8 +15,7 @@ class Foo { virtual Foo(double); // expected-error{{constructor cannot be declared 'virtual'}} Foo(long) const; // expected-error{{'const' qualifier is not allowed on a constructor}} - int Foo(int, int); // expected-error{{constructor cannot have a return type}} \ - // expected-error{{member 'Foo' has the same name as its class}} + int Foo(int, int); // expected-error{{constructor cannot have a return type}} volatile Foo(float); // expected-error{{constructor cannot have a return type}} };