Skip to content

Commit 62e10f0

Browse files
committed
Diagnose attempts to add default function arguments to a
specialization. This completes C++ [temp.expl.spec]! llvm-svn: 83980
1 parent 9f73552 commit 62e10f0

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,9 @@ def note_instantiation_required_here : Note<
973973
"%select{implicit|explicit}0 instantiation first required here">;
974974
def err_template_spec_friend : Error<
975975
"template specialization declaration cannot be a friend">;
976+
def err_template_spec_default_arg : Error<
977+
"default argument not permitted on an explicit "
978+
"%select{instantiation|specialization}0 of function %1">;
976979

977980
// C++ class template specializations and out-of-line definitions
978981
def err_template_spec_needs_header : Error<

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,22 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
296296
<< NewParam->getDefaultArgRange();
297297
Diag(Old->getLocation(), diag::note_template_prev_declaration)
298298
<< false;
299+
} else if (New->getTemplateSpecializationKind()
300+
!= TSK_ImplicitInstantiation &&
301+
New->getTemplateSpecializationKind() != TSK_Undeclared) {
302+
// C++ [temp.expr.spec]p21:
303+
// Default function arguments shall not be specified in a declaration
304+
// or a definition for one of the following explicit specializations:
305+
// - the explicit specialization of a function template;
306+
// — the explicit specialization of a member function template;
307+
// — the explicit specialization of a member function of a class
308+
// template where the class template specialization to which the
309+
// member function specialization belongs is implicitly
310+
// instantiated.
311+
Diag(NewParam->getLocation(), diag::err_template_spec_default_arg)
312+
<< (New->getTemplateSpecializationKind() ==TSK_ExplicitSpecialization)
313+
<< New->getDeclName()
314+
<< NewParam->getDefaultArgRange();
299315
} else if (New->getDeclContext()->isDependentContext()) {
300316
// C++ [dcl.fct.default]p6 (DR217):
301317
// Default arguments for a member function of a class template shall
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: clang-cc -fsyntax-only -verify %s
2+
3+
template<typename T>
4+
struct X {
5+
void mf1(T);
6+
template<typename U> void mf2(T, U); // expected-note{{previous}}
7+
};
8+
9+
template<>
10+
void X<int>::mf1(int i = 17) // expected-error{{default}}
11+
{
12+
}
13+
14+
template<> template<>
15+
void X<int>::mf2(int, int = 17) // expected-error{{default}}
16+
{ }
17+
18+
template<> template<typename U>
19+
void X<int>::mf2(int, U = U()) // expected-error{{default}}
20+
{
21+
}
22+
23+
template<>
24+
struct X<float> {
25+
void mf1(float);
26+
};
27+
28+
void X<float>::mf1(float = 3.14f) // okay
29+
{
30+
}

clang/www/cxx_status.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2085,11 +2085,11 @@ <h1>C++ Support in Clang</h1>
20852085
</tr>
20862086
<tr>
20872087
<td>&nbsp;&nbsp;&nbsp;&nbsp;14.7.3 [temp.expl.spec]</td>
2088-
<td class="advanced" align="center"></td>
2089-
<td class="medium" align="center"></td>
2090-
<td class="medium" align="center"></td>
2091-
<td class="broken" align="center"></td>
2092-
<td>O</td>
2088+
<td class="complete" align="center">&#x2713;</td>
2089+
<td class="complete" align="center">&#x2713;</td>
2090+
<td class="complete" align="center">&#x2713;</td>
2091+
<td class="complete" align="center"></td>
2092+
<td></td>
20932093
</tr>
20942094
<tr>
20952095
<td>&nbsp;&nbsp;14.8 [temp.fct.spec]</td>

0 commit comments

Comments
 (0)