Skip to content

Commit

Permalink
Disallow explicit instantiation and explicit specialization for deduc…
Browse files Browse the repository at this point in the history
…tion guides.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@294641 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
zygoloid committed Feb 9, 2017
1 parent 7bf80c8 commit 32f0979
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 3 deletions.
2 changes: 2 additions & 0 deletions include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1991,6 +1991,8 @@ def err_deduction_guide_name_not_class_template : Error<
"template template parameter|dependent template name}0 %1">;
def err_deduction_guide_defines_function : Error<
"deduction guide cannot have a function definition">;
def err_deduction_guide_specialized : Error<"deduction guide cannot be "
"%select{explicitly instantiated|explicitly specialized}0">;

// C++1y deduced return types
def err_auto_fn_deduction_failure : Error<
Expand Down
10 changes: 9 additions & 1 deletion lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7657,8 +7657,9 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
} else if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) {
SemaRef.CheckDeductionGuideDeclarator(D, R, SC);

// We don't need to store any extra information for a deduction guide, so
// We don't need to store much extra information for a deduction guide, so
// just model it as a plain FunctionDecl.
// FIXME: Store IsExplicit!
return FunctionDecl::Create(SemaRef.Context, DC,
D.getLocStart(),
NameInfo, R, TInfo, SC, isInline,
Expand Down Expand Up @@ -9149,6 +9150,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
} else if (CXXConversionDecl *Conversion
= dyn_cast<CXXConversionDecl>(NewFD)) {
ActOnConversionDeclarator(Conversion);
} else if (NewFD->isDeductionGuide() &&
NewFD->getTemplateSpecializationKind() ==
TSK_ExplicitSpecialization) {
// A deduction guide is not on the list of entities that can be
// explicitly specialized.
Diag(NewFD->getLocStart(), diag::err_deduction_guide_specialized)
<< /*explicit specialization*/ 1;
}

// Find any virtual functions that this function overrides.
Expand Down
8 changes: 8 additions & 0 deletions lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8187,6 +8187,14 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
return true;
}

// A deduction guide is not on the list of entities that can be explicitly
// instantiated.
if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) {
Diag(D.getDeclSpec().getLocStart(), diag::err_deduction_guide_specialized)
<< /*explicit instantiation*/ 0;
return true;
}

// C++0x [temp.explicit]p2:
// There are two forms of explicit instantiation: an explicit instantiation
// definition and an explicit instantiation declaration. An explicit
Expand Down
20 changes: 20 additions & 0 deletions test/CXX/temp/temp.deduct.guide/p1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,23 @@ A(int(&)[43]) -> A<int> try {} catch (...) {} // expected-error {{deduction guid
#ifdef CLASS
};
#endif

namespace ExplicitInst {
// Explicit instantiation / specialization is not permitted.
template<typename T> struct B {};
template<typename T> B(T) -> B<T>;
template<> B(int) -> B<int>; // expected-error {{deduction guide cannot be explicitly specialized}}
extern template B(float) -> B<float>; // expected-error {{deduction guide cannot be explicitly instantiated}}
template B(char) -> B<char>; // expected-error {{deduction guide cannot be explicitly instantiated}}

// An attempt at partial specialization doesn't even parse as a deduction-guide.
template<typename T> B<T*>(T*) -> B<T*>; // expected-error 1+{{}} expected-note 0+{{}}

struct X {
template<typename T> struct C {};
template<typename T> C(T) -> C<T>;
template<> C(int) -> C<int>; // expected-error {{explicit specialization of '<deduction guide for C>' in class scope}}
extern template C(float) -> C<float>; // expected-error {{expected member name or ';'}}
template C(char) -> C<char>; // expected-error {{expected '<' after 'template'}}
};
}
8 changes: 6 additions & 2 deletions www/cxx_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -682,10 +682,14 @@ <h2 id="cxx17">C++1z implementation status</h2>
<td class="svn" align="center">Clang 4</td>
</tr>
<tr>
<td>Template argument deduction for class templates</td>
<td rowspan="2">Template argument deduction for class templates</td>
<td><a href="http://wg21.link/p0091r3">P0091R3</a></td>
<td class="none" align="center">No</td>
<td class="partial" align="center">Partial</td>
</tr>
<tr> <!-- from Issaquah -->
<td><a href="http://wg21.link/p0512r0">P0512R0</a></td>
<td class="partial" align="center">Partial</td>
</tr>
<tr>
<td>Non-type template parameters with <tt>auto</tt> type</td>
<td><a href="http://wg21.link/p0127r2">P0127R2</a></td>
Expand Down

0 comments on commit 32f0979

Please sign in to comment.