]> granicus.if.org Git - clang/commitdiff
Don't crash when using type traits on a class with a constructor template.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 13 Sep 2010 22:18:28 +0000 (22:18 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 13 Sep 2010 22:18:28 +0000 (22:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113796 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExprCXX.cpp
test/SemaCXX/type-traits.cpp

index b380a4b7a79c567bb7e5aed48b5fa5ed12e4399f..e03c5721c6c5b8d45e8830a31b438d0d190f7b8f 100644 (file)
@@ -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<FunctionTemplateDecl>(*Con))
+          continue;
         CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*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<FunctionTemplateDecl>(*Con))
+          continue;
         CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
         if (Constructor->isDefaultConstructor()) {
           const FunctionProtoType *CPT
index cb88220bb1943f3b14357afccf4131f515bb234d..d6fccffaaca25876e74e61000fdf0d72a7a14a79 100644 (file)
@@ -215,6 +215,13 @@ struct HasCopy {
   HasCopy(HasCopy& cp);
 };
 
+struct HasTemplateCons {
+  HasVirt Annoying;
+
+  template <typename T>
+  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() {