Author: hfinkel Date: Sun Nov 27 10:26:14 2016 New Revision: 287999 URL: http://llvm.org/viewvc/llvm-project?rev=287999&view=rev Log: 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 Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/test/SemaCXX/cxx11-crashes.cpp Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=287999&r1=287998&r2=287999&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun Nov 27 10:26:14 2016 @@ -4416,9 +4416,12 @@ static bool EvaluateUnaryTypeTrait(Sema // 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 @@ -4452,9 +4455,12 @@ static bool EvaluateUnaryTypeTrait(Sema 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 Modified: cfe/trunk/test/SemaCXX/cxx11-crashes.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx11-crashes.cpp?rev=287999&r1=287998&r2=287999&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx11-crashes.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx11-crashes.cpp Sun Nov 27 10:26:14 2016 @@ -91,3 +91,15 @@ void test(int some_number) { // expecte 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); } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits