Diagnose attempts to add default function arguments to a

specialization. This completes C++ [temp.expl.spec]!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83980 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2009-10-13 17:02:54 +00:00
Родитель 70cf5306f0
Коммит 096ebfda90
4 изменённых файлов: 54 добавлений и 5 удалений

Просмотреть файл

@ -973,6 +973,9 @@ def note_instantiation_required_here : Note<
"%select{implicit|explicit}0 instantiation first required here">; "%select{implicit|explicit}0 instantiation first required here">;
def err_template_spec_friend : Error< def err_template_spec_friend : Error<
"template specialization declaration cannot be a friend">; "template specialization declaration cannot be a friend">;
def err_template_spec_default_arg : Error<
"default argument not permitted on an explicit "
"%select{instantiation|specialization}0 of function %1">;
// C++ class template specializations and out-of-line definitions // C++ class template specializations and out-of-line definitions
def err_template_spec_needs_header : Error< def err_template_spec_needs_header : Error<

Просмотреть файл

@ -296,6 +296,22 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
<< NewParam->getDefaultArgRange(); << NewParam->getDefaultArgRange();
Diag(Old->getLocation(), diag::note_template_prev_declaration) Diag(Old->getLocation(), diag::note_template_prev_declaration)
<< false; << false;
} else if (New->getTemplateSpecializationKind()
!= TSK_ImplicitInstantiation &&
New->getTemplateSpecializationKind() != TSK_Undeclared) {
// C++ [temp.expr.spec]p21:
// Default function arguments shall not be specified in a declaration
// or a definition for one of the following explicit specializations:
// - the explicit specialization of a function template;
// — the explicit specialization of a member function template;
// — the explicit specialization of a member function of a class
// template where the class template specialization to which the
// member function specialization belongs is implicitly
// instantiated.
Diag(NewParam->getLocation(), diag::err_template_spec_default_arg)
<< (New->getTemplateSpecializationKind() ==TSK_ExplicitSpecialization)
<< New->getDeclName()
<< NewParam->getDefaultArgRange();
} else if (New->getDeclContext()->isDependentContext()) { } else if (New->getDeclContext()->isDependentContext()) {
// C++ [dcl.fct.default]p6 (DR217): // C++ [dcl.fct.default]p6 (DR217):
// Default arguments for a member function of a class template shall // Default arguments for a member function of a class template shall

Просмотреть файл

@ -0,0 +1,30 @@
// RUN: clang-cc -fsyntax-only -verify %s
template<typename T>
struct X {
void mf1(T);
template<typename U> void mf2(T, U); // expected-note{{previous}}
};
template<>
void X<int>::mf1(int i = 17) // expected-error{{default}}
{
}
template<> template<>
void X<int>::mf2(int, int = 17) // expected-error{{default}}
{ }
template<> template<typename U>
void X<int>::mf2(int, U = U()) // expected-error{{default}}
{
}
template<>
struct X<float> {
void mf1(float);
};
void X<float>::mf1(float = 3.14f) // okay
{
}

Просмотреть файл

@ -2085,11 +2085,11 @@ welcome!</p>
</tr> </tr>
<tr> <tr>
<td>&nbsp;&nbsp;&nbsp;&nbsp;14.7.3 [temp.expl.spec]</td> <td>&nbsp;&nbsp;&nbsp;&nbsp;14.7.3 [temp.expl.spec]</td>
<td class="advanced" align="center"></td> <td class="complete" align="center">&#x2713;</td>
<td class="medium" align="center"></td> <td class="complete" align="center">&#x2713;</td>
<td class="medium" align="center"></td> <td class="complete" align="center">&#x2713;</td>
<td class="broken" align="center"></td> <td class="complete" align="center"></td>
<td>O</td> <td></td>
</tr> </tr>
<tr> <tr>
<td>&nbsp;&nbsp;14.8 [temp.fct.spec]</td> <td>&nbsp;&nbsp;14.8 [temp.fct.spec]</td>