From fd434d0f1574c1aa3bf81618707bc533b92317f7 Mon Sep 17 00:00:00 2001
From: Richard Smith <richard-llvm@metafoo.co.uk>
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241424 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaDecl.cpp              | 11 ++++++-----
 test/CXX/class/class.mem/p2.cpp    |  7 ++-----
 test/CXX/drs/dr1xx.cpp             |  4 ++--
 test/Parser/cxx-default-delete.cpp |  2 +-
 test/SemaCXX/constructor.cpp       |  3 +--
 5 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 6508d6f04bb..3c0e83c5a25 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4742,15 +4742,16 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
     }
   }
 
-  if (DiagnoseClassNameShadow(DC, NameInfo))
+  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.
+    // 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;
 
-  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
-  QualType R = TInfo->getType();
-
   if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo,
                                       UPPC_DeclarationType))
     D.setInvalidType();
diff --git a/test/CXX/class/class.mem/p2.cpp b/test/CXX/class/class.mem/p2.cpp
index d45c0386065..1f0dfd05a20 100644
--- a/test/CXX/class/class.mem/p2.cpp
+++ b/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/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp
index cc6c5af8170..d8d9307a5eb 100644
--- a/test/CXX/drs/dr1xx.cpp
+++ b/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/test/Parser/cxx-default-delete.cpp b/test/Parser/cxx-default-delete.cpp
index df24b3d0075..8766d861732 100644
--- a/test/Parser/cxx-default-delete.cpp
+++ b/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/test/SemaCXX/constructor.cpp b/test/SemaCXX/constructor.cpp
index fa930bdb95d..105605c6e37 100644
--- a/test/SemaCXX/constructor.cpp
+++ b/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}}
 };
-- 
GitLab