]> granicus.if.org Git - clang/commitdiff
Make sure that we use the canonical type for the names of instantiated
authorDouglas Gregor <dgregor@apple.com>
Fri, 15 May 2009 21:18:27 +0000 (21:18 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 15 May 2009 21:18:27 +0000 (21:18 +0000)
constructors and destructors. This is a requirement of
DeclarationNameTable::getCXXSpecialName that we weren't assert()'ing,
so it should have been caught much earlier :(

Big thanks to Anders for the test case.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71895 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/DeclarationName.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/instantiate-function-1.cpp
test/SemaTemplate/instantiate-function-2.cpp [new file with mode: 0644]

index 15461bb99b80825ffa8e6df3b3b6458d5470f8de..a17abde7773033cdfeb49f5d00d33f3ca62ff4d2 100644 (file)
@@ -302,7 +302,8 @@ DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
   assert(Kind >= DeclarationName::CXXConstructorName &&
          Kind <= DeclarationName::CXXConversionFunctionName &&
          "Kind must be a C++ special name kind");
-  
+  assert(Ty->isCanonical() && 
+         "Can only build C++ special names from canonical types");
   llvm::FoldingSet<CXXSpecialName> *SpecialNames 
     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
 
index f1a02c48dd128e2ad1088f3386d4d2ed5ed9928b..382c2fa98ac13de40947b721402783598018ac83 100644 (file)
@@ -333,7 +333,8 @@ Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
   CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
   QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
   DeclarationName Name
-    = SemaRef.Context.DeclarationNames.getCXXConstructorName(ClassTy);
+    = SemaRef.Context.DeclarationNames.getCXXConstructorName(
+                                 SemaRef.Context.getCanonicalType(ClassTy));
   CXXConstructorDecl *Constructor
     = CXXConstructorDecl::Create(SemaRef.Context, Record, D->getLocation(), 
                                  Name, T, D->isExplicit(), D->isInline(), 
@@ -362,6 +363,7 @@ Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
   SemaRef.CheckFunctionDeclaration(Constructor, PrevDecl, Redeclaration,
                                    /*FIXME:*/OverloadableAttrRequired);
 
+  Record->addedConstructor(SemaRef.Context, Constructor);
   Owner->addDecl(SemaRef.Context, Constructor);
   return Constructor;
 }
@@ -377,7 +379,8 @@ Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
 
   // Build the instantiated destructor declaration.
   CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
-  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
+  QualType ClassTy = 
+    SemaRef.Context.getCanonicalType(SemaRef.Context.getTypeDeclType(Record));
   CXXDestructorDecl *Destructor
     = CXXDestructorDecl::Create(SemaRef.Context, Record,
                                 D->getLocation(),
index 51de6bca38dc7ddfe58db7f9fdb60b2860566735..e7c4af163a2bba44c4b65596d3422a5907b439f4 100644 (file)
@@ -64,8 +64,12 @@ template<typename T, typename U, typename V> struct X6 {
     // IfStmt
     if (t > 0)
       return u;
-    else
-      return v; // expected-error{{incompatible type}}
+    else { 
+      if (t < 0)
+        return v; // expected-error{{incompatible type}}
+    }
+
+    return v;
   }
 };
 
diff --git a/test/SemaTemplate/instantiate-function-2.cpp b/test/SemaTemplate/instantiate-function-2.cpp
new file mode 100644 (file)
index 0000000..51a6014
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+template <typename T> struct S {
+  S() { }
+  S(T t);
+};
+
+template struct S<int>;
+
+void f() {
+  S<int> s1;
+  S<int> s2(10);
+}