arphaman created this revision.
arphaman added a reviewer: rsmith.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.

This fixes PR 30274 by making sure that we skip the 'Using' and 
'ConstructorUsingShadowDecl' declarations when evaluating the 
'__has_nothrow_constructor' trait for a C++ type.

Repository:
  rL LLVM

https://reviews.llvm.org/D24884

Files:
  lib/Sema/SemaExprCXX.cpp
  test/SemaCXX/PR30274-inherited-constructor-has-nothrow.cpp

Index: test/SemaCXX/PR30274-inherited-constructor-has-nothrow.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/PR30274-inherited-constructor-has-nothrow.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+struct Base {
+    Base(int a) : i(a) {}
+    int i;
+};
+
+struct Derived : Base {
+    using Base::Base;
+};
+
+int foo() {
+   return __has_nothrow_constructor(Derived);
+}
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -4258,7 +4258,10 @@
       bool FoundConstructor = false;
       for (const auto *ND : Self.LookupConstructors(RD)) {
         // FIXME: In C++0x, a constructor template can be a default 
constructor.
-        if (isa<FunctionTemplateDecl>(ND))
+        // Skip the inherited constructors as we are only interested in default
+        // constructors which can't be inherited.
+        if (isa<FunctionTemplateDecl>(ND) || isa<UsingDecl>(ND) ||
+            isa<ConstructorUsingShadowDecl>(ND))
           continue;
         const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND);
         if (Constructor->isDefaultConstructor()) {


Index: test/SemaCXX/PR30274-inherited-constructor-has-nothrow.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/PR30274-inherited-constructor-has-nothrow.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+struct Base {
+    Base(int a) : i(a) {}
+    int i;
+};
+
+struct Derived : Base {
+    using Base::Base;
+};
+
+int foo() {
+   return __has_nothrow_constructor(Derived);
+}
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -4258,7 +4258,10 @@
       bool FoundConstructor = false;
       for (const auto *ND : Self.LookupConstructors(RD)) {
         // FIXME: In C++0x, a constructor template can be a default constructor.
-        if (isa<FunctionTemplateDecl>(ND))
+        // Skip the inherited constructors as we are only interested in default
+        // constructors which can't be inherited.
+        if (isa<FunctionTemplateDecl>(ND) || isa<UsingDecl>(ND) ||
+            isa<ConstructorUsingShadowDecl>(ND))
           continue;
         const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND);
         if (Constructor->isDefaultConstructor()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to