From c42b6520b607cda57e850a60143e9f98bf421dbb Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 9 Apr 2010 21:02:29 +0000 Subject: [PATCH] Only complain about explicit instantiations following explicit specializations when the explicit instantiation was... explicitly written, i.e., not the product of an explicit instantiation of an enclosing class. Fixes this spurious warning when Clang builds LLVM: /Volumes/Data/dgregor/Projects/llvm/lib/CodeGen/MachineDominators.cpp:22:1: warning: explicit instantiation of 'addRoot' that occurs after an explicit specialization will be ignored (C++0x extension) [-pedantic] git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100900 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplate.cpp | 3 ++- lib/Sema/SemaTemplateInstantiate.cpp | 13 ++++++++++++ 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(*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 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::f1(); // expected-error{{explicit instantiation of undefi template int X0::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' that occurs after an explicit specialization will be ignored}} -template<> void X0::f1(); -template void X0::f1(); +template<> void X0::f1(); // expected-note{{previous template specialization is here}} +template void X0::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization will be ignored}} -template<> struct X0::Inner; -template struct X0::Inner; +template<> struct X0::Inner; // expected-note{{previous template specialization is here}} +template struct X0::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization will be ignored}} -template<> long X0::value; -template long X0::value; +template<> long X0::value; // expected-note{{previous template specialization is here}} +template long X0::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization will be ignored}} -template<> struct X0; -template struct X0; +template<> struct X0; // expected-note{{previous template specialization is here}} +template struct X0; // expected-warning{{explicit instantiation of 'X0' that occurs after an explicit specialization will be ignored}} // PR 6458 namespace test0 { -- 2.40.0