From: Douglas Gregor Date: Fri, 15 May 2009 21:18:27 +0000 (+0000) Subject: Make sure that we use the canonical type for the names of instantiated X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=49f25ecf7ff358039ce4c9254b867f32110e660e;p=clang Make sure that we use the canonical type for the names of instantiated 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 --- diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp index 15461bb99b..a17abde777 100644 --- a/lib/AST/DeclarationName.cpp +++ b/lib/AST/DeclarationName.cpp @@ -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 *SpecialNames = static_cast*>(CXXSpecialNamesImpl); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index f1a02c48dd..382c2fa98a 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -333,7 +333,8 @@ Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) { CXXRecordDecl *Record = cast(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(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(), diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp index 51de6bca38..e7c4af163a 100644 --- a/test/SemaTemplate/instantiate-function-1.cpp +++ b/test/SemaTemplate/instantiate-function-1.cpp @@ -64,8 +64,12 @@ template 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 index 0000000000..51a60146d4 --- /dev/null +++ b/test/SemaTemplate/instantiate-function-2.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template struct S { + S() { } + S(T t); +}; + +template struct S; + +void f() { + S s1; + S s2(10); +}