diff options
| author | Nathan Wilson <nwilson20@gmail.com> | 2016-04-09 02:55:27 +0000 |
|---|---|---|
| committer | Nathan Wilson <nwilson20@gmail.com> | 2016-04-09 02:55:27 +0000 |
| commit | 8383912f8700297a7cc6d5be7e8bbaed71057067 (patch) | |
| tree | dee01919075e220cfee03acbf6657ae59093bdce | |
| parent | dd77e1e6a53cbf807783492706bcfa7a5d849148 (diff) | |
| download | bcm5719-llvm-8383912f8700297a7cc6d5be7e8bbaed71057067.tar.gz bcm5719-llvm-8383912f8700297a7cc6d5be7e8bbaed71057067.zip | |
[Concepts] Implement subsection [dcl.spec.concept]p7 of the Concepts TS
Summary: A program shall not declare an explicit instantiation (14.8.2), an explicit specialization (14.8.3), or a partial specialization of a concept definition.
Reviewers: rsmith, hubert.reinterpretcast, faisalv, aaron.ballman
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D18221
llvm-svn: 265868
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 21 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 28 | ||||
| -rw-r--r-- | clang/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp | 18 |
4 files changed, 70 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6f4c863a0a6..cc385bff72e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2098,6 +2098,9 @@ def err_variable_concept_bool_decl : Error< def err_concept_specified_specialization : Error< "'concept' cannot be applied on an " "%select{explicit instantiation|explicit specialization|partial specialization}0">; +def err_concept_specialized : Error< + "%select{function|variable}0 concept cannot be " + "%select{explicitly instantiated|explicitly specialized|partially specialized}1">; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 774af59e497..35682943907 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6285,6 +6285,25 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!IsVariableTemplateSpecialization) D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); + // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare [...] + // an explicit specialization (14.8.3) or a partial specialization of a + // concept definition. + if (IsVariableTemplateSpecialization && + !D.getDeclSpec().isConceptSpecified() && !Previous.empty() && + Previous.isSingleResult()) { + NamedDecl *PreviousDecl = Previous.getFoundDecl(); + if (VarTemplateDecl *VarTmpl = dyn_cast<VarTemplateDecl>(PreviousDecl)) { + if (VarTmpl->isConcept()) { + Diag(NewVD->getLocation(), diag::err_concept_specialized) + << 1 /*variable*/ + << (IsPartialSpecialization ? 2 /*partially specialized*/ + : 1 /*explicitly specialized*/); + Diag(VarTmpl->getLocation(), diag::note_previous_declaration); + NewVD->setInvalidDecl(); + } + } + } + if (NewTemplate) { VarTemplateDecl *PrevVarTemplate = NewVD->getPreviousDecl() @@ -7823,6 +7842,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (isFunctionTemplateSpecialization) { Diag(D.getDeclSpec().getConceptSpecLoc(), diag::err_concept_specified_specialization) << 1; + NewFD->setInvalidDecl(true); + return NewFD; } } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index fdb7d762d29..d840e426d7a 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -6920,6 +6920,15 @@ bool Sema::CheckFunctionTemplateSpecialization( // Ignore access information; it doesn't figure into redeclaration checking. FunctionDecl *Specialization = cast<FunctionDecl>(*Result); + // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare [...] + // an explicit specialization (14.8.3) [...] of a concept definition. + if (Specialization->getPrimaryTemplate()->isConcept()) { + Diag(FD->getLocation(), diag::err_concept_specialized) + << 0 /*function*/ << 1 /*explicitly specialized*/; + Diag(Specialization->getLocation(), diag::note_previous_declaration); + return true; + } + FunctionTemplateSpecializationInfo *SpecInfo = Specialization->getTemplateSpecializationInfo(); assert(SpecInfo && "Function template specialization info missing?"); @@ -7774,6 +7783,15 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, return true; } + // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare an + // explicit instantiation (14.8.2) [...] of a concept definition. + if (PrevTemplate->isConcept()) { + Diag(D.getIdentifierLoc(), diag::err_concept_specialized) + << 1 /*variable*/ << 0 /*explicitly instantiated*/; + Diag(PrevTemplate->getLocation(), diag::note_previous_declaration); + return true; + } + // Translate the parser's template argument list into our AST format. TemplateArgumentListInfo TemplateArgs = makeTemplateArgumentListInfo(*this, *D.getName().TemplateId); @@ -7988,6 +8006,16 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, diag::ext_explicit_instantiation_without_qualified_id) << Specialization << D.getCXXScopeSpec().getRange(); + // C++ Concepts TS [dcl.spec.concept]p7: A program shall not declare an + // explicit instantiation (14.8.2) [...] of a concept definition. + if (FunTmpl && FunTmpl->isConcept() && + !D.getDeclSpec().isConceptSpecified()) { + Diag(D.getIdentifierLoc(), diag::err_concept_specialized) + << 0 /*function*/ << 0 /*explicitly instantiated*/; + Diag(FunTmpl->getLocation(), diag::note_previous_declaration); + return true; + } + CheckExplicitInstantiationScope(*this, FunTmpl? (NamedDecl *)FunTmpl : Specialization->getInstantiatedFromMemberFunction(), diff --git a/clang/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp b/clang/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp new file mode 100644 index 00000000000..1bad6bb9329 --- /dev/null +++ b/clang/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s + +template <typename T> concept bool FCEI() { return true; } // expected-note {{previous declaration is here}} expected-note {{previous declaration is here}} +template bool FCEI<int>(); // expected-error {{function concept cannot be explicitly instantiated}} +extern template bool FCEI<double>(); // expected-error {{function concept cannot be explicitly instantiated}} + +template <typename T> concept bool FCES() { return true; } // expected-note {{previous declaration is here}} +template <> bool FCES<int>() { return true; } // expected-error {{function concept cannot be explicitly specialized}} + +template <typename T> concept bool VC { true }; // expected-note {{previous declaration is here}} expected-note {{previous declaration is here}} +template bool VC<int>; // expected-error {{variable concept cannot be explicitly instantiated}} +extern template bool VC<double>; // expected-error {{variable concept cannot be explicitly instantiated}} + +template <typename T> concept bool VCES { true }; // expected-note {{previous declaration is here}} +template <> bool VCES<int> { true }; // expected-error {{variable concept cannot be explicitly specialized}} + +template <typename T> concept bool VCPS { true }; // expected-note {{previous declaration is here}} +template <typename T> bool VCPS<T *> { true }; // expected-error {{variable concept cannot be partially specialized}} |

