twoh updated this revision to Diff 75441.
twoh marked an inline comment as done.
twoh added a comment.

Addressing comments from @sepavloff. Thanks!


https://reviews.llvm.org/D23765

Files:
  lib/Sema/SemaExprCXX.cpp
  test/SemaCXX/cxx11-crashes.cpp


Index: test/SemaCXX/cxx11-crashes.cpp
===================================================================
--- test/SemaCXX/cxx11-crashes.cpp
+++ test/SemaCXX/cxx11-crashes.cpp
@@ -91,3 +91,10 @@
   Foo(lambda);
 }
 }
+
+namespace pr29091 {
+  struct X{ X(const X &x); };
+  struct Y: X { using X::X; };
+  bool foo() { return __has_nothrow_constructor(Y); }
+  bool bar() { return __has_nothrow_copy(Y); }
+}
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -4389,7 +4389,18 @@
         // resolution point.
         if (isa<FunctionTemplateDecl>(ND))
           continue;
-        const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND);
+        // UsingDecl itself is not a constructor
+        if (isa<UsingDecl>(ND))
+          continue;
+        const CXXConstructorDecl *Constructor = nullptr;
+        if (auto *CSD = dyn_cast<ConstructorUsingShadowDecl>(ND)) {
+          Constructor = cast<CXXConstructorDecl>(CSD->getTargetDecl());
+          // Default constructor and copy/move constructor are not inherited.
+          if (Constructor->isDefaultConstructor() ||
+              Constructor->isCopyOrMoveConstructor())
+            continue;
+        } else
+          Constructor = cast<CXXConstructorDecl>(ND);
         if (Constructor->isCopyConstructor(FoundTQs)) {
           FoundConstructor = true;
           const FunctionProtoType *CPT
@@ -4425,7 +4436,18 @@
         // FIXME: In C++0x, a constructor template can be a default 
constructor.
         if (isa<FunctionTemplateDecl>(ND))
           continue;
-        const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND);
+        // UsingDecl itself is not a constructor
+        if (isa<UsingDecl>(ND))
+          continue;
+        const CXXConstructorDecl *Constructor = nullptr;
+        if (auto *CSD = dyn_cast<ConstructorUsingShadowDecl>(ND)) {
+          Constructor = cast<CXXConstructorDecl>(CSD->getTargetDecl());
+          // Default constructor and copy/move constructor are not inherited.
+          if (Constructor->isDefaultConstructor() ||
+              Constructor->isCopyOrMoveConstructor())
+            continue;
+        } else
+          Constructor = cast<CXXConstructorDecl>(ND);
         if (Constructor->isDefaultConstructor()) {
           FoundConstructor = true;
           const FunctionProtoType *CPT


Index: test/SemaCXX/cxx11-crashes.cpp
===================================================================
--- test/SemaCXX/cxx11-crashes.cpp
+++ test/SemaCXX/cxx11-crashes.cpp
@@ -91,3 +91,10 @@
   Foo(lambda);
 }
 }
+
+namespace pr29091 {
+  struct X{ X(const X &x); };
+  struct Y: X { using X::X; };
+  bool foo() { return __has_nothrow_constructor(Y); }
+  bool bar() { return __has_nothrow_copy(Y); }
+}
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -4389,7 +4389,18 @@
         // resolution point.
         if (isa<FunctionTemplateDecl>(ND))
           continue;
-        const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND);
+        // UsingDecl itself is not a constructor
+        if (isa<UsingDecl>(ND))
+          continue;
+        const CXXConstructorDecl *Constructor = nullptr;
+        if (auto *CSD = dyn_cast<ConstructorUsingShadowDecl>(ND)) {
+          Constructor = cast<CXXConstructorDecl>(CSD->getTargetDecl());
+          // Default constructor and copy/move constructor are not inherited.
+          if (Constructor->isDefaultConstructor() ||
+              Constructor->isCopyOrMoveConstructor())
+            continue;
+        } else
+          Constructor = cast<CXXConstructorDecl>(ND);
         if (Constructor->isCopyConstructor(FoundTQs)) {
           FoundConstructor = true;
           const FunctionProtoType *CPT
@@ -4425,7 +4436,18 @@
         // FIXME: In C++0x, a constructor template can be a default constructor.
         if (isa<FunctionTemplateDecl>(ND))
           continue;
-        const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND);
+        // UsingDecl itself is not a constructor
+        if (isa<UsingDecl>(ND))
+          continue;
+        const CXXConstructorDecl *Constructor = nullptr;
+        if (auto *CSD = dyn_cast<ConstructorUsingShadowDecl>(ND)) {
+          Constructor = cast<CXXConstructorDecl>(CSD->getTargetDecl());
+          // Default constructor and copy/move constructor are not inherited.
+          if (Constructor->isDefaultConstructor() ||
+              Constructor->isCopyOrMoveConstructor())
+            continue;
+        } else
+          Constructor = cast<CXXConstructorDecl>(ND);
         if (Constructor->isDefaultConstructor()) {
           FoundConstructor = true;
           const FunctionProtoType *CPT
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to