Author: rsmith Date: Wed Aug 31 18:23:25 2016 New Revision: 280308 URL: http://llvm.org/viewvc/llvm-project?rev=280308&view=rev Log: DR259: Demote the pedantic error for an explicit instantiation after an explicit specialization to a warning for C++98 mode (this is a defect report resolution, so per our informal policy it should apply in C++98), and turn the warning on by default for C++11 and later. In all cases where it fires, the right thing to do is to remove the pointless explicit instantiation.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/CXX/drs/dr2xx.cpp cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p4.cpp cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp cfe/trunk/test/SemaCXX/cxx98-compat.cpp cfe/trunk/test/SemaTemplate/temp_explicit.cpp cfe/trunk/www/cxx_dr_status.html Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Aug 31 18:23:25 2016 @@ -4076,14 +4076,10 @@ def ext_explicit_instantiation_duplicate InGroup<MicrosoftTemplate>; def note_previous_explicit_instantiation : Note< "previous explicit instantiation is here">; -def ext_explicit_instantiation_after_specialization : Extension< - "explicit instantiation of %0 that occurs after an explicit " - "specialization will be ignored (C++11 extension)">, - InGroup<CXX11>; -def warn_cxx98_compat_explicit_instantiation_after_specialization : Warning< - "explicit instantiation of %0 that occurs after an explicit " - "specialization is incompatible with C++98">, - InGroup<CXX98CompatPedantic>, DefaultIgnore; +def warn_explicit_instantiation_after_specialization : Warning< + "explicit instantiation of %0 that occurs after an explicit " + "specialization has no effect">, + InGroup<DiagGroup<"instantiation-after-specialization">>; def note_previous_template_specialization : Note< "previous template specialization is here">; def err_explicit_instantiation_nontemplate_type : Error< Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Aug 31 18:23:25 2016 @@ -6821,13 +6821,7 @@ Sema::CheckSpecializationInstantiationRe // instantiation of a template appears after a declaration of // an explicit specialization for that template, the explicit // instantiation has no effect. - // - // In C++98/03 mode, we only give an extension warning here, because it - // is not harmful to try to explicitly instantiate something that - // has been explicitly specialized. - Diag(NewLoc, getLangOpts().CPlusPlus11 ? - diag::warn_cxx98_compat_explicit_instantiation_after_specialization : - diag::ext_explicit_instantiation_after_specialization) + Diag(NewLoc, diag::warn_explicit_instantiation_after_specialization) << PrevDecl; Diag(PrevDecl->getLocation(), diag::note_previous_template_specialization); Modified: cfe/trunk/test/CXX/drs/dr2xx.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr2xx.cpp?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/test/CXX/drs/dr2xx.cpp (original) +++ cfe/trunk/test/CXX/drs/dr2xx.cpp Wed Aug 31 18:23:25 2016 @@ -679,17 +679,13 @@ namespace dr258 { // dr258: yes } f; // expected-error {{abstract}} } -namespace dr259 { // dr259: yes c++11 +namespace dr259 { // dr259: 4.0 template<typename T> struct A {}; template struct A<int>; // expected-note {{previous}} template struct A<int>; // expected-error {{duplicate explicit instantiation}} - // FIXME: We only apply this DR in C++11 mode. - template<> struct A<float>; - template struct A<float>; -#if __cplusplus < 201103L - // expected-error@-2 {{extension}} expected-note@-3 {{here}} -#endif + template<> struct A<float>; // expected-note {{previous}} + template struct A<float>; // expected-warning {{has no effect}} template struct A<char>; // expected-note {{here}} template<> struct A<char>; // expected-error {{explicit specialization of 'dr259::A<char>' after instantiation}} @@ -702,11 +698,8 @@ namespace dr259 { // dr259: yes c++11 template<typename T> struct B; // expected-note {{here}} template struct B<int>; // expected-error {{undefined}} - template<> struct B<float>; - template struct B<float>; -#if __cplusplus < 201103L - // expected-error@-2 {{extension}} expected-note@-3 {{here}} -#endif + template<> struct B<float>; // expected-note {{previous}} + template struct B<float>; // expected-warning {{has no effect}} } // FIXME: When dr260 is resolved, also add tests for DR507. Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp Wed Aug 31 18:23:25 2016 @@ -223,8 +223,8 @@ namespace spec_vs_expl_inst { namespace SID { template <typename STRING_TYPE> class BasicStringPiece; - template <> class BasicStringPiece<int> { }; - template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} + template <> class BasicStringPiece<int> { }; // expected-note {{previous template specialization is here}} + template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}} extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} } @@ -252,8 +252,8 @@ namespace spec_vs_expl_inst { namespace DSI { template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece<int>'}} - template <> class BasicStringPiece<int> { }; - template class BasicStringPiece<int>; + template <> class BasicStringPiece<int> { }; // expected-note {{previous}} + template class BasicStringPiece<int>; // expected-warning {{has no effect}} } // The same again, with a defined template class. @@ -267,8 +267,8 @@ namespace spec_vs_expl_inst { namespace SID_WithDefinedTemplate { template <typename STRING_TYPE> class BasicStringPiece {}; - template <> class BasicStringPiece<int> { }; - template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} + template <> class BasicStringPiece<int> { }; // expected-note {{previous}} + template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}} extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}} } @@ -304,15 +304,15 @@ namespace spec_vs_expl_inst { namespace SII_WithDefinedTemplate { template <typename STRING_TYPE> class BasicStringPiece {}; - template <> class BasicStringPiece<int> { }; - template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} + template <> class BasicStringPiece<int> { }; // expected-note {{previous}} + template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} expected-warning {{has no effect}} template class BasicStringPiece<int>; // expected-error {{duplicate explicit instantiation of 'BasicStringPiece<int>'}} } namespace SIS { template <typename STRING_TYPE> class BasicStringPiece; - template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} - template class BasicStringPiece<int>; + template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} expected-note {{previous}} + template class BasicStringPiece<int>; // expected-warning {{has no effect}} template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}} } Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p4.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p4.cpp?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p4.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p4.cpp Wed Aug 31 18:23:25 2016 @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s template<typename T> void f0(T); // expected-note{{here}} template void f0(int); // expected-error{{explicit instantiation of undefined function template}} @@ -17,19 +18,19 @@ template void X0<int>::f1(); // expected template int X0<int>::value; // expected-error{{explicit instantiation of undefined static data member}} 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 f0(long); // expected-warning{{explicit instantiation of 'f0<long>' that occurs after an explicit specialization has no effect}} 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 void X0<long>::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization has no effect}} 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 struct X0<long>::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization has no effect}} 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 long X0<long>::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization has no effect}} 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}} +template struct X0<double>; // expected-warning{{explicit instantiation of 'X0<double>' that occurs after an explicit specialization has no effect}} // PR 6458 namespace test0 { @@ -43,6 +44,6 @@ namespace test0 { // inappropriately instantiating this template. void *ptr = x; } - extern template class foo<char>; // expected-warning {{extern templates are a C++11 extension}} + extern template class foo<char>; // expected-warning 0-1{{extern templates are a C++11 extension}} template class foo<char>; } Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp Wed Aug 31 18:23:25 2016 @@ -26,10 +26,10 @@ namespace out_of_line { template<typename T, typename T0> static CONST T right = T(100); template<typename T> static CONST T right<T,int> = T(5); }; - template<> CONST int B0::right<int,int> = 7; - template CONST int B0::right<int,int>; - template<> CONST int B0::right<int,float>; - template CONST int B0::right<int,float>; + template<> CONST int B0::right<int,int> = 7; // expected-note {{previous}} + template CONST int B0::right<int,int>; // expected-warning {{has no effect}} + template<> CONST int B0::right<int,float>; // expected-note {{previous}} + template CONST int B0::right<int,float>; // expected-warning {{has no effect}} class B1 { template<typename T, typename T0> static CONST T right; Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp Wed Aug 31 18:23:25 2016 @@ -264,9 +264,9 @@ namespace explicit_specialization { template<typename T> T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}} - template<> int pi0<int> = 10; - template int pi0<int>; - template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} + template<> int pi0<int> = 10; // expected-note 2{{previous template specialization is here}} + template int pi0<int>; // expected-warning {{has no effect}} + template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} expected-warning {{has no effect}} template<typename T1, typename T2> CONST int pi2 = 1; Modified: cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx98-compat-pedantic.cpp Wed Aug 31 18:23:25 2016 @@ -21,10 +21,6 @@ enum Enum { Enum_value, // expected-warning {{commas at the end of enumerator lists are incompatible with C++98}} }; -template<typename T> struct InstantiationAfterSpecialization {}; -template<> struct InstantiationAfterSpecialization<int> {}; // expected-note {{here}} -template struct InstantiationAfterSpecialization<int>; // expected-warning {{explicit instantiation of 'InstantiationAfterSpecialization<int>' that occurs after an explicit specialization is incompatible with C++98}} - void *dlsym(); void (*FnPtr)() = (void(*)())dlsym(); // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}} void *FnVoidPtr = (void*)&dlsym; // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}} Modified: cfe/trunk/test/SemaCXX/cxx98-compat.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx98-compat.cpp?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx98-compat.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx98-compat.cpp Wed Aug 31 18:23:25 2016 @@ -361,7 +361,7 @@ template<typename T> T var = T(10); // diagnosed the primary template. template<typename T> T* var<T*> = new T(); template<> int var<int> = 10; -template int var<int>; +template char var<char>; float fvar = var<float>; class A { @@ -391,7 +391,7 @@ template<typename T> T B::v = T(); template<typename T> T* B::v<T*> = new T(); template<> int B::v<int> = 10; -template int B::v<int>; +template char B::v<char>; float fsvar = B::v<float>; #ifdef CXX14COMPAT Modified: cfe/trunk/test/SemaTemplate/temp_explicit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_explicit.cpp?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/temp_explicit.cpp (original) +++ cfe/trunk/test/SemaTemplate/temp_explicit.cpp Wed Aug 31 18:23:25 2016 @@ -26,7 +26,7 @@ template class X0<double> { }; // expect template class X0<int, int>; // expected-error{{duplicate}} template<> class X0<char> { }; // expected-note{{previous}} -template class X0<char>; // expected-warning{{ignored}} +template class X0<char>; // expected-warning{{has no effect}} void foo(X0<short>) { } template class X0<short>; Modified: cfe/trunk/www/cxx_dr_status.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=280308&r1=280307&r2=280308&view=diff ============================================================================== --- cfe/trunk/www/cxx_dr_status.html (original) +++ cfe/trunk/www/cxx_dr_status.html Wed Aug 31 18:23:25 2016 @@ -1594,7 +1594,7 @@ accessible?</td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#259";>259</a></td> <td>CD1</td> <td>Restrictions on explicit specialization and instantiation</td> - <td class="full" align="center">Yes (C++11 onwards)</td> + <td class="svn" align="center">SVN</td> </tr> <tr class="open" id="260"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#260";>260</a></td> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits