diff options
author | Larisse Voufo <lvoufo@google.com> | 2013-08-14 03:09:19 +0000 |
---|---|---|
committer | Larisse Voufo <lvoufo@google.com> | 2013-08-14 03:09:19 +0000 |
commit | d8dd97c0a278ad685efaabc52f14acf4fd1bae6e (patch) | |
tree | 6750d927046c898752fdef510798ea8ca92a0d42 /clang/lib | |
parent | db2162903e02073e62a6265404977024fe16dfa1 (diff) | |
download | bcm5719-llvm-d8dd97c0a278ad685efaabc52f14acf4fd1bae6e.tar.gz bcm5719-llvm-d8dd97c0a278ad685efaabc52f14acf4fd1bae6e.zip |
Bug fix: disallow a variable template to be redeclared as a non-templated variable
llvm-svn: 188350
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 31 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 33 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 19 |
5 files changed, 49 insertions, 53 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index bc46aae0a6b..c5836746221 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2920,15 +2920,21 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, /// definitions here, since the initializer hasn't been attached. /// void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, - bool MergeTypeWithPrevious) { + bool IsVariableTemplate, bool MergeTypeWithPrevious) { // If the new decl is already invalid, don't do any other checking. if (New->isInvalidDecl()) return; - // Verify the old decl was also a variable. + // Verify the old decl was also a variable or variable template. VarDecl *Old = 0; - if (!Previous.isSingleResult() || - !(Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) { + if (Previous.isSingleResult() && + (Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) { + if (IsVariableTemplate) + Old = Old->getDescribedVarTemplate() ? Old : 0; + else + Old = Old->getDescribedVarTemplate() ? 0 : Old; + } + if (!Old) { Diag(New->getLocation(), diag::err_redefinition_different_kind) << New->getDeclName(); Diag(Previous.getRepresentativeDecl()->getLocation(), @@ -4919,6 +4925,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool IsExplicitSpecialization = false; bool IsVariableTemplateSpecialization = false; bool IsPartialSpecialization = false; + bool IsVariableTemplate = false; bool Invalid = false; // TODO: Can we remove this (error-prone)? TemplateParameterList *TemplateParams = 0; VarTemplateDecl *PrevVarTemplate = 0; @@ -5019,6 +5026,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } else { // if (TemplateParams->size() > 0) // This is a template declaration. + IsVariableTemplate = true; // Check that we can declare a template here. if (CheckTemplateDeclScope(S, TemplateParams)) @@ -5310,9 +5318,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, LookupResult PrevDecl(*this, GetNameForDeclarator(D), LookupOrdinaryName, ForRedeclaration); PrevDecl.addDecl(PrevVarTemplate->getTemplatedDecl()); - D.setRedeclaration(CheckVariableDeclaration(NewVD, PrevDecl)); + D.setRedeclaration( + CheckVariableDeclaration(NewVD, PrevDecl, IsVariableTemplate)); } else - D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); + D.setRedeclaration( + CheckVariableDeclaration(NewVD, Previous, IsVariableTemplate)); } // This is an explicit specialization of a static data member. Check it. @@ -5340,8 +5350,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - // If this is not a variable template, return it now - if (!TemplateParams || IsVariableTemplateSpecialization) + // If this is not a variable template, return it now. + if (!IsVariableTemplate) return NewVD; // If this is supposed to be a variable template, create it as such. @@ -5745,7 +5755,8 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { /// /// Returns true if the variable declaration is a redeclaration. bool Sema::CheckVariableDeclaration(VarDecl *NewVD, - LookupResult &Previous) { + LookupResult &Previous, + bool IsVariableTemplate) { CheckVariableDeclarationType(NewVD); // If the decl is already known invalid, don't check it. @@ -5795,7 +5806,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, filterNonConflictingPreviousDecls(Context, NewVD, Previous); if (!Previous.empty()) { - MergeVarDecl(NewVD, Previous, MergeTypeWithPrevious); + MergeVarDecl(NewVD, Previous, IsVariableTemplate, MergeTypeWithPrevious); return true; } return false; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index bd2936b6141..c8298a93bae 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2280,32 +2280,6 @@ static bool CheckTemplateSpecializationScope(Sema &S, NamedDecl *Specialized, bool IsPartialSpecialization); static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D); -/* -// Check the new variable specialization against the parsed input. -// -// FIXME: Model this against function specializations where -// a new function declaration is checked against the specialization -// as candidate for redefinition... (?) -static bool CheckVariableTemplateSpecializationType() { - - if (ExpectedType is undeduced && ParsedType is not undeduced) - ExpectedType = dedudeType(); - - if (both types are undeduced) - ???; - - bool CheckType = !ExpectedType()-> - - if (!Context.hasSameType(DI->getType(), ExpectedDI->getType())) { - unsigned ErrStr = IsPartialSpecialization ? 2 : 1; - Diag(D.getIdentifierLoc(), diag::err_invalid_var_template_spec_type) - << ErrStr << VarTemplate << DI->getType() << ExpectedDI->getType(); - Diag(VarTemplate->getLocation(), diag::note_template_declared_here) - << 2 << VarTemplate->getDeclName(); - return true; - } -} -*/ DeclResult Sema::ActOnVarTemplateSpecialization( Scope *S, VarTemplateDecl *VarTemplate, Declarator &D, TypeSourceInfo *DI, @@ -2359,13 +2333,6 @@ DeclResult Sema::ActOnVarTemplateSpecialization( if (!ExpectedDI) return true; - /* - // Check the new variable specialization against the parsed input. - // (Attributes are merged later below.) - if (CheckVariableTemplateSpecializationType()) - return true; - */ - // Find the variable template (partial) specialization declaration that // corresponds to these arguments. if (IsPartialSpecialization) { diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index c7242aa5f99..3379ebcd900 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3365,7 +3365,7 @@ void Sema::BuildVariableInstantiation( OldVar->hasLinkage()) LookupQualifiedName(Previous, NewVar->getDeclContext(), false); - CheckVariableDeclaration(NewVar, Previous); + CheckVariableDeclaration(NewVar, Previous, ForVarTemplate); if (OldVar->isOutOfLine()) { OldVar->getLexicalDeclContext()->addDecl(NewVar); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 1eef54b1421..7099d32b3d5 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -943,7 +943,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { VD->setCachedLinkage(Linkage(Record[Idx++])); // Only true variables (not parameters or implicit parameters) can be merged. - if (VD->getKind() == Decl::Var) + if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam) mergeRedeclarable(VD, Redecl); if (uint64_t Val = Record[Idx++]) { @@ -955,11 +955,22 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { } } - if (Record[Idx++]) { // HasMemberSpecializationInfo. + enum VarKind { + VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization + }; + switch ((VarKind)Record[Idx++]) { + case VarNotTemplate: + break; + case VarTemplate: + VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>(Record, Idx)); + break; + case StaticDataMemberSpecialization: { // HasMemberSpecializationInfo. VarDecl *Tmpl = ReadDeclAs<VarDecl>(Record, Idx); TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; SourceLocation POI = ReadSourceLocation(Record, Idx); Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI); + break; + } } return Redecl; @@ -1433,7 +1444,7 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) { RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D); if (ThisDeclID == Redecl.getFirstID()) { - // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of + // This VarTemplateDecl owns a CommonPtr; read it to keep track of all of // the specializations. SmallVector<serialization::DeclID, 2> SpecIDs; SpecIDs.push_back(0); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index c9f3a6541f8..80726309417 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -712,14 +712,21 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { } else { Record.push_back(0); } - - MemberSpecializationInfo *SpecInfo - = D->isStaticDataMember() ? D->getMemberSpecializationInfo() : 0; - Record.push_back(SpecInfo != 0); - if (SpecInfo) { + + enum { + VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization + }; + if (VarTemplateDecl *TemplD = D->getDescribedVarTemplate()) { + Record.push_back(VarTemplate); + Writer.AddDeclRef(TemplD, Record); + } else if (MemberSpecializationInfo *SpecInfo + = D->getMemberSpecializationInfo()) { + Record.push_back(StaticDataMemberSpecialization); Writer.AddDeclRef(SpecInfo->getInstantiatedFrom(), Record); Record.push_back(SpecInfo->getTemplateSpecializationKind()); Writer.AddSourceLocation(SpecInfo->getPointOfInstantiation(), Record); + } else { + Record.push_back(VarNotTemplate); } if (!D->hasAttrs() && @@ -739,7 +746,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { !isa<VarTemplateSpecializationDecl>(D) && !D->isConstexpr() && !D->isPreviousDeclInSameBlockScope() && - !SpecInfo) + !D->getMemberSpecializationInfo()) AbbrevToUse = Writer.getDeclVarAbbrev(); Code = serialization::DECL_VAR; |