diff options
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 13 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p4.cpp | 22 |
3 files changed, 26 insertions, 12 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 7fc0cf85e3..285495a41b 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4047,7 +4047,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // instantiation has no effect. // // In C++98/03 mode, we only give an extension warning here, because it - // is not not harmful to try to explicitly instantiate something that + // is not harmful to try to explicitly instantiate something that // has been explicitly specialized. if (!getLangOptions().CPlusPlus0x) { Diag(NewLoc, diag::ext_explicit_instantiation_after_specialization) @@ -4204,6 +4204,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, // Ignore access information; it doesn't figure into redeclaration checking. FunctionDecl *Specialization = cast<FunctionDecl>(*Result); + Specialization->setLocation(FD->getLocation()); // FIXME: Check if the prior specialization has a point of instantiation. // If so, we have run afoul of . diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 6895364abf..a24d00f595 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1381,6 +1381,10 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, MemberSpecializationInfo *MSInfo = Function->getMemberSpecializationInfo(); assert(MSInfo && "No member specialization information?"); + if (MSInfo->getTemplateSpecializationKind() + == TSK_ExplicitSpecialization) + continue; + if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK, Function, MSInfo->getTemplateSpecializationKind(), @@ -1413,6 +1417,10 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, if (Var->isStaticDataMember()) { MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo(); assert(MSInfo && "No member specialization information?"); + if (MSInfo->getTemplateSpecializationKind() + == TSK_ExplicitSpecialization) + continue; + if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK, Var, MSInfo->getTemplateSpecializationKind(), @@ -1444,6 +1452,11 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, MemberSpecializationInfo *MSInfo = Record->getMemberSpecializationInfo(); assert(MSInfo && "No member specialization information?"); + + if (MSInfo->getTemplateSpecializationKind() + == TSK_ExplicitSpecialization) + continue; + if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK, Record, MSInfo->getTemplateSpecializationKind(), diff --git a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp index 2b852136f3..d304374115 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s template<typename T> void f0(T); // expected-note{{here}} template void f0(int); // expected-error{{explicit instantiation of undefined function template}} @@ -16,20 +16,20 @@ template void X0<int>::f1(); // expected-error{{explicit instantiation of undefi template int X0<int>::value; // expected-error{{explicit instantiation of undefined static data member}} -template<> void f0(long); -template void f0(long); // okay +template<> void f0(long); // expected-note{{previous template specialization is here}} +template void f0(long); // expected-warning{{explicit instantiation of 'f0<long>' that occurs after an explicit specialization will be ignored}} -template<> void X0<long>::f1(); -template void X0<long>::f1(); +template<> void X0<long>::f1(); // expected-note{{previous template specialization is here}} +template void X0<long>::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization will be ignored}} -template<> struct X0<long>::Inner; -template struct X0<long>::Inner; +template<> struct X0<long>::Inner; // expected-note{{previous template specialization is here}} +template struct X0<long>::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization will be ignored}} -template<> long X0<long>::value; -template long X0<long>::value; +template<> long X0<long>::value; // expected-note{{previous template specialization is here}} +template long X0<long>::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization will be ignored}} -template<> struct X0<double>; -template struct X0<double>; +template<> struct X0<double>; // expected-note{{previous template specialization is here}} +template struct X0<double>; // expected-warning{{explicit instantiation of 'X0<double>' that occurs after an explicit specialization will be ignored}} // PR 6458 namespace test0 { |