aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2016-11-28 20:37:50 +0000
committerTom Stellard <thomas.stellard@amd.com>2016-11-28 20:37:50 +0000
commit6c2a4d630ec3c37177fcf730aedc736275029513 (patch)
tree2a7f20c7e24a9792e9fabab06029e0316420a742
parentdd822f5bd55340546dbdb928d926e392a99f43ac (diff)
downloadllvm-6c2a4d630ec3c37177fcf730aedc736275029513.zip
llvm-6c2a4d630ec3c37177fcf730aedc736275029513.tar.gz
llvm-6c2a4d630ec3c37177fcf730aedc736275029513.tar.bz2
Merging r287999:
------------------------------------------------------------------------ r287999 | hfinkel | 2016-11-27 08:26:14 -0800 (Sun, 27 Nov 2016) | 14 lines Adjust type-trait evaluation to properly handle Using(Shadow)Decls Since r274049, for an inheriting constructor declaration, the name of the using declaration (and using shadow declaration comes from the using declaration) is the name of a derived class, not the base class (line 8225-8232 of lib/Sema/SemaDeclCXX.cpp in https://reviews.llvm.org/rL274049). Because of this, name-based lookup performed inside Sema::LookupConstructors returns not only CXXConstructorDecls but also Using(Shadow)Decls, which results assertion failure reported in PR29087. Patch by Taewook Oh, thanks! Differential Revision: https://reviews.llvm.org/D23765 ------------------------------------------------------------------------ llvm-svn: 288058
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp14
-rw-r--r--clang/test/SemaCXX/cxx11-crashes.cpp12
2 files changed, 22 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 56f4019..dfdd367 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -4221,9 +4221,12 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
// A template constructor is never a copy constructor.
// FIXME: However, it may actually be selected at the actual overload
// resolution point.
- if (isa<FunctionTemplateDecl>(ND))
+ if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
continue;
- const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND);
+ // UsingDecl itself is not a constructor
+ if (isa<UsingDecl>(ND))
+ continue;
+ auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
if (Constructor->isCopyConstructor(FoundTQs)) {
FoundConstructor = true;
const FunctionProtoType *CPT
@@ -4257,9 +4260,12 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
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))
+ if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
+ continue;
+ // UsingDecl itself is not a constructor
+ if (isa<UsingDecl>(ND))
continue;
- const CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(ND);
+ auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
if (Constructor->isDefaultConstructor()) {
FoundConstructor = true;
const FunctionProtoType *CPT
diff --git a/clang/test/SemaCXX/cxx11-crashes.cpp b/clang/test/SemaCXX/cxx11-crashes.cpp
index 97c95945..7c455ee 100644
--- a/clang/test/SemaCXX/cxx11-crashes.cpp
+++ b/clang/test/SemaCXX/cxx11-crashes.cpp
@@ -91,3 +91,15 @@ void test(int some_number) { // expected-note {{'some_number' declared here}}
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); }
+
+ struct A { template <typename T> A(); };
+ struct B : A { using A::A; };
+ bool baz() { return __has_nothrow_constructor(B); }
+ bool qux() { return __has_nothrow_copy(B); }
+}