Bug fix: disallow a variable template to be redeclared as a non-templated variable
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188350 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index bc46aae..c583674 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2920,15 +2920,21 @@
/// 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 @@
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 @@
} 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 @@
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 @@
}
}
- // 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 @@
///
/// 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 @@
filterNonConflictingPreviousDecls(Context, NewVD, Previous);
if (!Previous.empty()) {
- MergeVarDecl(NewVD, Previous, MergeTypeWithPrevious);
+ MergeVarDecl(NewVD, Previous, IsVariableTemplate, MergeTypeWithPrevious);
return true;
}
return false;