From 08295a592d7e54e6bea00daeb2abe7ac79a3aaba Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Mon, 13 Sep 2010 22:18:28 +0000 Subject: [PATCH] Don't crash when using type traits on a class with a constructor template. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113796 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExprCXX.cpp | 8 ++++++++ test/SemaCXX/type-traits.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index b380a4b7a7..e03c5721c6 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2148,6 +2148,11 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T) { DeclContext::lookup_const_iterator Con, ConEnd; for (llvm::tie(Con, ConEnd) = Self.LookupConstructors(RD); Con != ConEnd; ++Con) { + // A template constructor is never a copy constructor. + // FIXME: However, it may actually be selected at the actual overload + // resolution point. + if (isa(*Con)) + continue; CXXConstructorDecl *Constructor = cast(*Con); if (Constructor->isCopyConstructor(FoundTQs)) { FoundConstructor = true; @@ -2181,6 +2186,9 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T) { DeclContext::lookup_const_iterator Con, ConEnd; for (llvm::tie(Con, ConEnd) = Self.LookupConstructors(RD); Con != ConEnd; ++Con) { + // FIXME: In C++0x, a constructor template can be a default constructor. + if (isa(*Con)) + continue; CXXConstructorDecl *Constructor = cast(*Con); if (Constructor->isDefaultConstructor()) { const FunctionProtoType *CPT diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index cb88220bb1..d6fccffaac 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -215,6 +215,13 @@ struct HasCopy { HasCopy(HasCopy& cp); }; +struct HasTemplateCons { + HasVirt Annoying; + + template + HasTemplateCons(const T&); +}; + void has_trivial_default_constructor() { int t01[T(__has_trivial_constructor(Int))]; int t02[T(__has_trivial_constructor(IntAr))]; @@ -236,6 +243,7 @@ void has_trivial_default_constructor() { int t18[F(__has_trivial_constructor(VirtAr))]; int t19[F(__has_trivial_constructor(void))]; int t20[F(__has_trivial_constructor(cvoid))]; + int t21[F(__has_trivial_constructor(HasTemplateCons))]; } void has_trivial_copy_constructor() { @@ -259,6 +267,7 @@ void has_trivial_copy_constructor() { int t18[F(__has_trivial_copy(VirtAr))]; int t19[F(__has_trivial_copy(void))]; int t20[F(__has_trivial_copy(cvoid))]; + int t21[F(__has_trivial_copy(HasTemplateCons))]; } void has_trivial_copy_assignment() { @@ -367,6 +376,7 @@ void has_nothrow_copy() { int t22[F(__has_nothrow_copy(void))]; int t23[F(__has_nothrow_copy(cvoid))]; int t24[T(__has_nothrow_copy(HasVirtDest))]; + int t25[T(__has_nothrow_copy(HasTemplateCons))]; } void has_nothrow_constructor() { @@ -394,6 +404,7 @@ void has_nothrow_constructor() { int t21[F(__has_nothrow_constructor(void))]; int t22[F(__has_nothrow_constructor(cvoid))]; int t23[T(__has_nothrow_constructor(HasVirtDest))]; + int t24[F(__has_nothrow_constructor(HasTemplateCons))]; } void has_virtual_destructor() { -- 2.40.0