From: Douglas Gregor Date: Tue, 13 Oct 2009 17:02:54 +0000 (+0000) Subject: Diagnose attempts to add default function arguments to a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=096ebfda90b35a5cd6e399920fca7d9b5b0859f3;p=clang 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 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 051dd436bd..2a70ff2e66 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -973,6 +973,9 @@ def note_instantiation_required_here : Note< "%select{implicit|explicit}0 instantiation first required here">; def err_template_spec_friend : Error< "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 def err_template_spec_needs_header : Error< diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 519694aea8..646ac75dd3 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -296,6 +296,22 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) { << NewParam->getDefaultArgRange(); Diag(Old->getLocation(), diag::note_template_prev_declaration) << 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()) { // C++ [dcl.fct.default]p6 (DR217): // Default arguments for a member function of a class template shall diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp new file mode 100644 index 0000000000..9dae3eb519 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp @@ -0,0 +1,30 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template +struct X { + void mf1(T); + template void mf2(T, U); // expected-note{{previous}} +}; + +template<> +void X::mf1(int i = 17) // expected-error{{default}} +{ +} + +template<> template<> +void X::mf2(int, int = 17) // expected-error{{default}} +{ } + +template<> template +void X::mf2(int, U = U()) // expected-error{{default}} +{ +} + +template<> +struct X { + void mf1(float); +}; + +void X::mf1(float = 3.14f) // okay +{ +} diff --git a/www/cxx_status.html b/www/cxx_status.html index 151ffc6866..23da6f116b 100644 --- a/www/cxx_status.html +++ b/www/cxx_status.html @@ -2085,11 +2085,11 @@ welcome!

    14.7.3 [temp.expl.spec] - - - - - O + ✓ + ✓ + ✓ + +   14.8 [temp.fct.spec]