From: Richard Smith Date: Wed, 31 Aug 2016 23:23:25 +0000 (+0000) Subject: DR259: Demote the pedantic error for an explicit instantiation after an X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f3b78ea7320dc81622421c36271adbec3c923ece;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@280308 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 7d0b9d7741..a70b27bac2 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4076,14 +4076,10 @@ def ext_explicit_instantiation_duplicate : ExtWarn< InGroup; 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; -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, DefaultIgnore; +def warn_explicit_instantiation_after_specialization : Warning< + "explicit instantiation of %0 that occurs after an explicit " + "specialization has no effect">, + InGroup>; def note_previous_template_specialization : Note< "previous template specialization is here">; def err_explicit_instantiation_nontemplate_type : Error< diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index ab5f545181..7d573293f4 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -6821,13 +6821,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, // 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); diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp index 25c853590a..7372ecb26c 100644 --- a/test/CXX/drs/dr2xx.cpp +++ b/test/CXX/drs/dr2xx.cpp @@ -679,17 +679,13 @@ namespace dr258 { // dr258: yes } f; // expected-error {{abstract}} } -namespace dr259 { // dr259: yes c++11 +namespace dr259 { // dr259: 4.0 template struct A {}; template struct A; // expected-note {{previous}} template struct A; // expected-error {{duplicate explicit instantiation}} - // FIXME: We only apply this DR in C++11 mode. - template<> struct A; - template struct A; -#if __cplusplus < 201103L - // expected-error@-2 {{extension}} expected-note@-3 {{here}} -#endif + template<> struct A; // expected-note {{previous}} + template struct A; // expected-warning {{has no effect}} template struct A; // expected-note {{here}} template<> struct A; // expected-error {{explicit specialization of 'dr259::A' after instantiation}} @@ -702,11 +698,8 @@ namespace dr259 { // dr259: yes c++11 template struct B; // expected-note {{here}} template struct B; // expected-error {{undefined}} - template<> struct B; - template struct B; -#if __cplusplus < 201103L - // expected-error@-2 {{extension}} expected-note@-3 {{here}} -#endif + template<> struct B; // expected-note {{previous}} + template struct B; // expected-warning {{has no effect}} } // FIXME: When dr260 is resolved, also add tests for DR507. diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp index d12feeff0b..1af47a0ed5 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp @@ -223,8 +223,8 @@ namespace spec_vs_expl_inst { namespace SID { template class BasicStringPiece; - template <> class BasicStringPiece { }; - template class BasicStringPiece; // expected-note {{explicit instantiation definition is here}} + template <> class BasicStringPiece { }; // expected-note {{previous template specialization is here}} + template class BasicStringPiece; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}} extern template class BasicStringPiece; // 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 class BasicStringPiece; // expected-note {{template is declared here}} extern template class BasicStringPiece; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece'}} - template <> class BasicStringPiece { }; - template class BasicStringPiece; + template <> class BasicStringPiece { }; // expected-note {{previous}} + template class BasicStringPiece; // 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 class BasicStringPiece {}; - template <> class BasicStringPiece { }; - template class BasicStringPiece; // expected-note {{explicit instantiation definition is here}} + template <> class BasicStringPiece { }; // expected-note {{previous}} + template class BasicStringPiece; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}} extern template class BasicStringPiece; // 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 class BasicStringPiece {}; - template <> class BasicStringPiece { }; - template class BasicStringPiece; // expected-note {{previous explicit instantiation is here}} + template <> class BasicStringPiece { }; // expected-note {{previous}} + template class BasicStringPiece; // expected-note {{previous explicit instantiation is here}} expected-warning {{has no effect}} template class BasicStringPiece; // expected-error {{duplicate explicit instantiation of 'BasicStringPiece'}} } namespace SIS { template class BasicStringPiece; - template <> class BasicStringPiece { }; // expected-note {{previous definition is here}} - template class BasicStringPiece; + template <> class BasicStringPiece { }; // expected-note {{previous definition is here}} expected-note {{previous}} + template class BasicStringPiece; // expected-warning {{has no effect}} template <> class BasicStringPiece { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece'}} } diff --git a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp index 09c428e01d..0a8a0ce9ff 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp @@ -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 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::f1(); // expected-error{{explicit instantiation of undefi template int X0::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' that occurs after an explicit specialization will be ignored}} +template void f0(long); // expected-warning{{explicit instantiation of 'f0' that occurs after an explicit specialization has no effect}} 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 void X0::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization has no effect}} 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 struct X0::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization has no effect}} 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 long X0::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization has no effect}} 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}} +template struct X0; // expected-warning{{explicit instantiation of 'X0' 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; // expected-warning {{extern templates are a C++11 extension}} + extern template class foo; // expected-warning 0-1{{extern templates are a C++11 extension}} template class foo; } diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp index e2fbdfd699..76f1bb9905 100644 --- a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -26,10 +26,10 @@ namespace out_of_line { template static CONST T right = T(100); template static CONST T right = T(5); }; - template<> CONST int B0::right = 7; - template CONST int B0::right; - template<> CONST int B0::right; - template CONST int B0::right; + template<> CONST int B0::right = 7; // expected-note {{previous}} + template CONST int B0::right; // expected-warning {{has no effect}} + template<> CONST int B0::right; // expected-note {{previous}} + template CONST int B0::right; // expected-warning {{has no effect}} class B1 { template static CONST T right; diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp index 496ae88873..ec3e2b6f63 100644 --- a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp +++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp @@ -264,9 +264,9 @@ namespace explicit_specialization { template T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}} - template<> int pi0 = 10; - template int pi0; - template float pi0; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} + template<> int pi0 = 10; // expected-note 2{{previous template specialization is here}} + template int pi0; // expected-warning {{has no effect}} + template float pi0; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} expected-warning {{has no effect}} template CONST int pi2 = 1; diff --git a/test/SemaCXX/cxx98-compat-pedantic.cpp b/test/SemaCXX/cxx98-compat-pedantic.cpp index 38bc341e83..8b0dcc8713 100644 --- a/test/SemaCXX/cxx98-compat-pedantic.cpp +++ b/test/SemaCXX/cxx98-compat-pedantic.cpp @@ -21,10 +21,6 @@ enum Enum { Enum_value, // expected-warning {{commas at the end of enumerator lists are incompatible with C++98}} }; -template struct InstantiationAfterSpecialization {}; -template<> struct InstantiationAfterSpecialization {}; // expected-note {{here}} -template struct InstantiationAfterSpecialization; // expected-warning {{explicit instantiation of 'InstantiationAfterSpecialization' 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}} diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp index 25a086d9bc..4a9baf5100 100644 --- a/test/SemaCXX/cxx98-compat.cpp +++ b/test/SemaCXX/cxx98-compat.cpp @@ -361,7 +361,7 @@ template T var = T(10); // diagnosed the primary template. template T* var = new T(); template<> int var = 10; -template int var; +template char var; float fvar = var; class A { @@ -391,7 +391,7 @@ template T B::v = T(); template T* B::v = new T(); template<> int B::v = 10; -template int B::v; +template char B::v; float fsvar = B::v; #ifdef CXX14COMPAT diff --git a/test/SemaTemplate/temp_explicit.cpp b/test/SemaTemplate/temp_explicit.cpp index 80c90d0cfc..e8c9dfb5f5 100644 --- a/test/SemaTemplate/temp_explicit.cpp +++ b/test/SemaTemplate/temp_explicit.cpp @@ -26,7 +26,7 @@ template class X0 { }; // expected-error{{explicit specialization}} template class X0; // expected-error{{duplicate}} template<> class X0 { }; // expected-note{{previous}} -template class X0; // expected-warning{{ignored}} +template class X0; // expected-warning{{has no effect}} void foo(X0) { } template class X0; diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html index 0e9af71f40..6fac95397c 100644 --- a/www/cxx_dr_status.html +++ b/www/cxx_dr_status.html @@ -1594,7 +1594,7 @@ accessible? 259 CD1 Restrictions on explicit specialization and instantiation - Yes (C++11 onwards) + SVN 260