Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit f3b78ea

Browse files
committed
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
1 parent 1051c8c commit f3b78ea

File tree

11 files changed

+39
-59
lines changed

11 files changed

+39
-59
lines changed

Diff for: include/clang/Basic/DiagnosticSemaKinds.td

+4-8
Original file line numberDiff line numberDiff line change
@@ -4076,14 +4076,10 @@ def ext_explicit_instantiation_duplicate : ExtWarn<
40764076
InGroup<MicrosoftTemplate>;
40774077
def note_previous_explicit_instantiation : Note<
40784078
"previous explicit instantiation is here">;
4079-
def ext_explicit_instantiation_after_specialization : Extension<
4080-
"explicit instantiation of %0 that occurs after an explicit "
4081-
"specialization will be ignored (C++11 extension)">,
4082-
InGroup<CXX11>;
4083-
def warn_cxx98_compat_explicit_instantiation_after_specialization : Warning<
4084-
"explicit instantiation of %0 that occurs after an explicit "
4085-
"specialization is incompatible with C++98">,
4086-
InGroup<CXX98CompatPedantic>, DefaultIgnore;
4079+
def warn_explicit_instantiation_after_specialization : Warning<
4080+
"explicit instantiation of %0 that occurs after an explicit "
4081+
"specialization has no effect">,
4082+
InGroup<DiagGroup<"instantiation-after-specialization">>;
40874083
def note_previous_template_specialization : Note<
40884084
"previous template specialization is here">;
40894085
def err_explicit_instantiation_nontemplate_type : Error<

Diff for: lib/Sema/SemaTemplate.cpp

+1-7
Original file line numberDiff line numberDiff line change
@@ -6821,13 +6821,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
68216821
// instantiation of a template appears after a declaration of
68226822
// an explicit specialization for that template, the explicit
68236823
// instantiation has no effect.
6824-
//
6825-
// In C++98/03 mode, we only give an extension warning here, because it
6826-
// is not harmful to try to explicitly instantiate something that
6827-
// has been explicitly specialized.
6828-
Diag(NewLoc, getLangOpts().CPlusPlus11 ?
6829-
diag::warn_cxx98_compat_explicit_instantiation_after_specialization :
6830-
diag::ext_explicit_instantiation_after_specialization)
6824+
Diag(NewLoc, diag::warn_explicit_instantiation_after_specialization)
68316825
<< PrevDecl;
68326826
Diag(PrevDecl->getLocation(),
68336827
diag::note_previous_template_specialization);

Diff for: test/CXX/drs/dr2xx.cpp

+5-12
Original file line numberDiff line numberDiff line change
@@ -679,17 +679,13 @@ namespace dr258 { // dr258: yes
679679
} f; // expected-error {{abstract}}
680680
}
681681

682-
namespace dr259 { // dr259: yes c++11
682+
namespace dr259 { // dr259: 4.0
683683
template<typename T> struct A {};
684684
template struct A<int>; // expected-note {{previous}}
685685
template struct A<int>; // expected-error {{duplicate explicit instantiation}}
686686

687-
// FIXME: We only apply this DR in C++11 mode.
688-
template<> struct A<float>;
689-
template struct A<float>;
690-
#if __cplusplus < 201103L
691-
// expected-error@-2 {{extension}} expected-note@-3 {{here}}
692-
#endif
687+
template<> struct A<float>; // expected-note {{previous}}
688+
template struct A<float>; // expected-warning {{has no effect}}
693689

694690
template struct A<char>; // expected-note {{here}}
695691
template<> struct A<char>; // expected-error {{explicit specialization of 'dr259::A<char>' after instantiation}}
@@ -702,11 +698,8 @@ namespace dr259 { // dr259: yes c++11
702698
template<typename T> struct B; // expected-note {{here}}
703699
template struct B<int>; // expected-error {{undefined}}
704700

705-
template<> struct B<float>;
706-
template struct B<float>;
707-
#if __cplusplus < 201103L
708-
// expected-error@-2 {{extension}} expected-note@-3 {{here}}
709-
#endif
701+
template<> struct B<float>; // expected-note {{previous}}
702+
template struct B<float>; // expected-warning {{has no effect}}
710703
}
711704

712705
// FIXME: When dr260 is resolved, also add tests for DR507.

Diff for: test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ namespace spec_vs_expl_inst {
223223

224224
namespace SID {
225225
template <typename STRING_TYPE> class BasicStringPiece;
226-
template <> class BasicStringPiece<int> { };
227-
template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}}
226+
template <> class BasicStringPiece<int> { }; // expected-note {{previous template specialization is here}}
227+
template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}}
228228
extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
229229
}
230230

@@ -252,8 +252,8 @@ namespace spec_vs_expl_inst {
252252
namespace DSI {
253253
template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}}
254254
extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece<int>'}}
255-
template <> class BasicStringPiece<int> { };
256-
template class BasicStringPiece<int>;
255+
template <> class BasicStringPiece<int> { }; // expected-note {{previous}}
256+
template class BasicStringPiece<int>; // expected-warning {{has no effect}}
257257
}
258258

259259
// The same again, with a defined template class.
@@ -267,8 +267,8 @@ namespace spec_vs_expl_inst {
267267

268268
namespace SID_WithDefinedTemplate {
269269
template <typename STRING_TYPE> class BasicStringPiece {};
270-
template <> class BasicStringPiece<int> { };
271-
template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}}
270+
template <> class BasicStringPiece<int> { }; // expected-note {{previous}}
271+
template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-warning {{has no effect}}
272272
extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
273273
}
274274

@@ -304,15 +304,15 @@ namespace spec_vs_expl_inst {
304304

305305
namespace SII_WithDefinedTemplate {
306306
template <typename STRING_TYPE> class BasicStringPiece {};
307-
template <> class BasicStringPiece<int> { };
308-
template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}}
307+
template <> class BasicStringPiece<int> { }; // expected-note {{previous}}
308+
template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}} expected-warning {{has no effect}}
309309
template class BasicStringPiece<int>; // expected-error {{duplicate explicit instantiation of 'BasicStringPiece<int>'}}
310310
}
311311

312312
namespace SIS {
313313
template <typename STRING_TYPE> class BasicStringPiece;
314-
template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}}
315-
template class BasicStringPiece<int>;
314+
template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}} expected-note {{previous}}
315+
template class BasicStringPiece<int>; // expected-warning {{has no effect}}
316316
template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}}
317317
}
318318

Diff for: test/CXX/temp/temp.spec/temp.explicit/p4.cpp

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
1+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
23

34
template<typename T> void f0(T); // expected-note{{here}}
45
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
1718
template int X0<int>::value; // expected-error{{explicit instantiation of undefined static data member}}
1819

1920
template<> void f0(long); // expected-note{{previous template specialization is here}}
20-
template void f0(long); // expected-warning{{explicit instantiation of 'f0<long>' that occurs after an explicit specialization will be ignored}}
21+
template void f0(long); // expected-warning{{explicit instantiation of 'f0<long>' that occurs after an explicit specialization has no effect}}
2122

2223
template<> void X0<long>::f1(); // expected-note{{previous template specialization is here}}
23-
template void X0<long>::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization will be ignored}}
24+
template void X0<long>::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization has no effect}}
2425

2526
template<> struct X0<long>::Inner; // expected-note{{previous template specialization is here}}
26-
template struct X0<long>::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization will be ignored}}
27+
template struct X0<long>::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization has no effect}}
2728

2829
template<> long X0<long>::value; // expected-note{{previous template specialization is here}}
29-
template long X0<long>::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization will be ignored}}
30+
template long X0<long>::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization has no effect}}
3031

3132
template<> struct X0<double>; // expected-note{{previous template specialization is here}}
32-
template struct X0<double>; // expected-warning{{explicit instantiation of 'X0<double>' that occurs after an explicit specialization will be ignored}}
33+
template struct X0<double>; // expected-warning{{explicit instantiation of 'X0<double>' that occurs after an explicit specialization has no effect}}
3334

3435
// PR 6458
3536
namespace test0 {
@@ -43,6 +44,6 @@ namespace test0 {
4344
// inappropriately instantiating this template.
4445
void *ptr = x;
4546
}
46-
extern template class foo<char>; // expected-warning {{extern templates are a C++11 extension}}
47+
extern template class foo<char>; // expected-warning 0-1{{extern templates are a C++11 extension}}
4748
template class foo<char>;
4849
}

Diff for: test/SemaCXX/cxx1y-variable-templates_in_class.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ namespace out_of_line {
2626
template<typename T, typename T0> static CONST T right = T(100);
2727
template<typename T> static CONST T right<T,int> = T(5);
2828
};
29-
template<> CONST int B0::right<int,int> = 7;
30-
template CONST int B0::right<int,int>;
31-
template<> CONST int B0::right<int,float>;
32-
template CONST int B0::right<int,float>;
29+
template<> CONST int B0::right<int,int> = 7; // expected-note {{previous}}
30+
template CONST int B0::right<int,int>; // expected-warning {{has no effect}}
31+
template<> CONST int B0::right<int,float>; // expected-note {{previous}}
32+
template CONST int B0::right<int,float>; // expected-warning {{has no effect}}
3333

3434
class B1 {
3535
template<typename T, typename T0> static CONST T right;

Diff for: test/SemaCXX/cxx1y-variable-templates_top_level.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,9 @@ namespace explicit_specialization {
264264
template<typename T>
265265
T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}}
266266

267-
template<> int pi0<int> = 10;
268-
template int pi0<int>;
269-
template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}}
267+
template<> int pi0<int> = 10; // expected-note 2{{previous template specialization is here}}
268+
template int pi0<int>; // expected-warning {{has no effect}}
269+
template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} expected-warning {{has no effect}}
270270

271271
template<typename T1, typename T2>
272272
CONST int pi2 = 1;

Diff for: test/SemaCXX/cxx98-compat-pedantic.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ enum Enum {
2121
Enum_value, // expected-warning {{commas at the end of enumerator lists are incompatible with C++98}}
2222
};
2323

24-
template<typename T> struct InstantiationAfterSpecialization {};
25-
template<> struct InstantiationAfterSpecialization<int> {}; // expected-note {{here}}
26-
template struct InstantiationAfterSpecialization<int>; // expected-warning {{explicit instantiation of 'InstantiationAfterSpecialization<int>' that occurs after an explicit specialization is incompatible with C++98}}
27-
2824
void *dlsym();
2925
void (*FnPtr)() = (void(*)())dlsym(); // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}}
3026
void *FnVoidPtr = (void*)&dlsym; // expected-warning {{cast between pointer-to-function and pointer-to-object is incompatible with C++98}}

Diff for: test/SemaCXX/cxx98-compat.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ template<typename T> T var = T(10);
361361
// diagnosed the primary template.
362362
template<typename T> T* var<T*> = new T();
363363
template<> int var<int> = 10;
364-
template int var<int>;
364+
template char var<char>;
365365
float fvar = var<float>;
366366

367367
class A {
@@ -391,7 +391,7 @@ template<typename T> T B::v = T();
391391

392392
template<typename T> T* B::v<T*> = new T();
393393
template<> int B::v<int> = 10;
394-
template int B::v<int>;
394+
template char B::v<char>;
395395
float fsvar = B::v<float>;
396396

397397
#ifdef CXX14COMPAT

Diff for: test/SemaTemplate/temp_explicit.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ template class X0<double> { }; // expected-error{{explicit specialization}}
2626
template class X0<int, int>; // expected-error{{duplicate}}
2727

2828
template<> class X0<char> { }; // expected-note{{previous}}
29-
template class X0<char>; // expected-warning{{ignored}}
29+
template class X0<char>; // expected-warning{{has no effect}}
3030

3131
void foo(X0<short>) { }
3232
template class X0<short>;

Diff for: www/cxx_dr_status.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
15941594
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#259">259</a></td>
15951595
<td>CD1</td>
15961596
<td>Restrictions on explicit specialization and instantiation</td>
1597-
<td class="full" align="center">Yes (C++11 onwards)</td>
1597+
<td class="svn" align="center">SVN</td>
15981598
</tr>
15991599
<tr class="open" id="260">
16001600
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#260">260</a></td>

0 commit comments

Comments
 (0)