Re: [PATCH] D18221: [Concepts] Implement subsection [dcl.spec.concept]p7 of the Concepts TS
This revision was automatically updated to reflect the committed changes. Closed by commit rL265868: [Concepts] Implement subsection [dcl.spec.concept]p7 of the Concepts TS (authored by nwilson). Changed prior to commit: http://reviews.llvm.org/D18221?vs=53103=53110#toc Repository: rL LLVM http://reviews.llvm.org/D18221 Files: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp Index: cfe/trunk/lib/Sema/SemaTemplate.cpp === --- cfe/trunk/lib/Sema/SemaTemplate.cpp +++ cfe/trunk/lib/Sema/SemaTemplate.cpp @@ -6920,6 +6920,15 @@ // Ignore access information; it doesn't figure into redeclaration checking. FunctionDecl *Specialization = cast(*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 @@ 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 @@ 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(), Index: cfe/trunk/lib/Sema/SemaDecl.cpp === --- cfe/trunk/lib/Sema/SemaDecl.cpp +++ cfe/trunk/lib/Sema/SemaDecl.cpp @@ -6285,6 +6285,25 @@ 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(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 @@ if (isFunctionTemplateSpecialization) { Diag(D.getDeclSpec().getConceptSpecLoc(), diag::err_concept_specified_specialization) << 1; +NewFD->setInvalidDecl(true); +return NewFD; } } Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td === --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -2098,6 +2098,9 @@ def err_concept_specified_specialization : Error< "'concept' cannot be applied on an " "%select{explicit instantiation|explicit specialization|partial specialization}0">; +def
Re: [PATCH] D18221: [Concepts] Implement subsection [dcl.spec.concept]p7 of the Concepts TS
nwilson updated this revision to Diff 53103. nwilson added a comment. - Address Aaron's comments by putting comments next to the magic numbers http://reviews.llvm.org/D18221 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp Index: test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp === --- /dev/null +++ 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 concept bool FCEI() { return true; } // expected-note {{previous declaration is here}} expected-note {{previous declaration is here}} +template bool FCEI(); // expected-error {{function concept cannot be explicitly instantiated}} +extern template bool FCEI(); // expected-error {{function concept cannot be explicitly instantiated}} + +template concept bool FCES() { return true; } // expected-note {{previous declaration is here}} +template <> bool FCES() { return true; } // expected-error {{function concept cannot be explicitly specialized}} + +template concept bool VC { true }; // expected-note {{previous declaration is here}} expected-note {{previous declaration is here}} +template bool VC; // expected-error {{variable concept cannot be explicitly instantiated}} +extern template bool VC; // expected-error {{variable concept cannot be explicitly instantiated}} + +template concept bool VCES { true }; // expected-note {{previous declaration is here}} +template <> bool VCES { true }; // expected-error {{variable concept cannot be explicitly specialized}} + +template concept bool VCPS { true }; // expected-note {{previous declaration is here}} +template bool VCPS { true }; // expected-error {{variable concept cannot be partially specialized}} Index: lib/Sema/SemaTemplate.cpp === --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -6920,6 +6920,15 @@ // Ignore access information; it doesn't figure into redeclaration checking. FunctionDecl *Specialization = cast(*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 @@ 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 @@ 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(), Index: lib/Sema/SemaDecl.cpp === --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -6285,6 +6285,25 @@ 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(); +
Re: [PATCH] D18221: [Concepts] Implement subsection [dcl.spec.concept]p7 of the Concepts TS
aaron.ballman added a comment. Generally looks good to me, but you should wait for @rsmith as he may have other ideas on the error recovery. Comment at: lib/Sema/SemaDecl.cpp:6295 @@ +6294,3 @@ + Diag(NewVD->getLocation(), diag::err_concept_specialized) + << 1 << (IsPartialSpecialization ? 2 : 1); + Diag(VarTmpl->getLocation(), diag::note_previous_declaration); Can you put comments near the magic numbers to describe what they mean? e.g., `1 /*variable*/` Same comment applies elsewhere in the patch as well. http://reviews.llvm.org/D18221 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D18221: [Concepts] Implement subsection [dcl.spec.concept]p7 of the Concepts TS
nwilson added inline comments. Comment at: lib/Sema/SemaDecl.cpp:7837 @@ -7819,1 +7836,3 @@ +NewFD->setInvalidDecl(true); +return NewFD; } Please let me know if there are thoughts about better error recovery here. I did this because we don't have the specifier information when checking an explicit specialization. So, we still diagnose for the explication specialization (one of the checks in this patch), when `concept` is specified, e.g.: template concept bool C() { return true; } template <> concept bool C() { return true; } Would it be okay to pass `Declarator` to Sema::CheckFunctionTemplateSpecialization? http://reviews.llvm.org/D18221 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits