diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-08-31 23:23:25 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-08-31 23:23:25 +0000 |
commit | e4caa48dbb744fb809db1f6f09de2ed9576efcea (patch) | |
tree | 505582594879dcd41b23047a8bfffcff116dbd15 | |
parent | 77807637ffb0fffd6f215187258b0e12c6b6a620 (diff) | |
download | bcm5719-llvm-e4caa48dbb744fb809db1f6f09de2ed9576efcea.tar.gz bcm5719-llvm-e4caa48dbb744fb809db1f6f09de2ed9576efcea.zip |
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.
llvm-svn: 280308
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 12 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 8 | ||||
-rw-r--r-- | clang/test/CXX/drs/dr2xx.cpp | 17 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp | 20 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp | 15 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp | 8 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp | 6 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx98-compat-pedantic.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx98-compat.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaTemplate/temp_explicit.cpp | 2 | ||||
-rw-r--r-- | clang/www/cxx_dr_status.html | 2 |
11 files changed, 39 insertions, 59 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7d0b9d77419..a70b27bac2c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4076,14 +4076,10 @@ def ext_explicit_instantiation_duplicate : ExtWarn< 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< diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index ab5f545181b..7d573293f4e 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/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/clang/test/CXX/drs/dr2xx.cpp b/clang/test/CXX/drs/dr2xx.cpp index 25c853590ae..7372ecb26c8 100644 --- a/clang/test/CXX/drs/dr2xx.cpp +++ b/clang/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<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. diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp index d12feeff0bb..1af47a0ed56 100644 --- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp +++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp @@ -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>'}} } diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp index 09c428e01df..0a8a0ce9ff1 100644 --- a/clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp +++ b/clang/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<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-error{{explicit instantiation of undefi 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>; } diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp index e2fbdfd6995..76f1bb9905b 100644 --- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -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; diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp index 496ae888732..ec3e2b6f63d 100644 --- a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp +++ b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp @@ -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; diff --git a/clang/test/SemaCXX/cxx98-compat-pedantic.cpp b/clang/test/SemaCXX/cxx98-compat-pedantic.cpp index 38bc341e83c..8b0dcc87132 100644 --- a/clang/test/SemaCXX/cxx98-compat-pedantic.cpp +++ b/clang/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<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}} diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp index 25a086d9bcd..4a9baf5100d 100644 --- a/clang/test/SemaCXX/cxx98-compat.cpp +++ b/clang/test/SemaCXX/cxx98-compat.cpp @@ -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 diff --git a/clang/test/SemaTemplate/temp_explicit.cpp b/clang/test/SemaTemplate/temp_explicit.cpp index 80c90d0cfcd..e8c9dfb5f5d 100644 --- a/clang/test/SemaTemplate/temp_explicit.cpp +++ b/clang/test/SemaTemplate/temp_explicit.cpp @@ -26,7 +26,7 @@ template class X0<double> { }; // expected-error{{explicit specialization}} 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>; diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 0e9af71f402..6fac95397c2 100644 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -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> |