luken-google created this revision. Herald added a project: All. luken-google requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Fixes GH48182. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D138210 Files: clang/lib/Sema/SemaTemplate.cpp clang/test/SemaTemplate/concepts.cpp Index: clang/test/SemaTemplate/concepts.cpp =================================================================== --- clang/test/SemaTemplate/concepts.cpp +++ clang/test/SemaTemplate/concepts.cpp @@ -766,3 +766,24 @@ __iterator_traits_member_pointer_or_arrow_or_void<counted_iterator<int>> f; } }// namespace InheritedFromPartialSpec + +namespace GH48182 { +template<typename, typename..., typename = int> // expected-error{{template parameter pack must be the last template parameter}} +concept invalid = true; + +template<typename> requires invalid<int> // expected-error{{use of undeclared identifier 'invalid'}} +no errors are printed +; + +static_assert(invalid<int> also here ; // expected-error{{use of undeclared identifier 'invalid'}} + +int foo() { + bool b; + b = invalid<int> not just in declarations; // expected-error{{expected ';' after expression}} + // expected-error@-1{{use of undeclared identifier 'invalid'}} + // expected-error@-2{{expected ';' after expression}} + // expected-error@-3{{use of undeclared identifier 'just'}} + // expected-error@-4{{unknown type name 'in'}} + return b; +} +} // namespace GH48182 \ No newline at end of file Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -8923,17 +8923,31 @@ return nullptr; } - if (TemplateParameterLists.front()->size() == 0) { + TemplateParameterList *Params = TemplateParameterLists.front(); + + if (Params->size() == 0) { Diag(NameLoc, diag::err_concept_no_parameters); return nullptr; } + for (TemplateParameterList::const_iterator ParamIt = Params->begin(), + ParamEnd = Params->end(); + ParamIt != ParamEnd; ++ParamIt) { + Decl const *Param = *ParamIt; + if (Param->isParameterPack()) { + if (++ParamIt == ParamEnd) + break; + Diag(Param->getLocation(), + diag::err_template_param_pack_must_be_last_template_parameter); + return nullptr; + } + } + if (DiagnoseUnexpandedParameterPack(ConstraintExpr)) return nullptr; - ConceptDecl *NewDecl = ConceptDecl::Create(Context, DC, NameLoc, Name, - TemplateParameterLists.front(), - ConstraintExpr); + ConceptDecl *NewDecl = + ConceptDecl::Create(Context, DC, NameLoc, Name, Params, ConstraintExpr); if (NewDecl->hasAssociatedConstraints()) { // C++2a [temp.concept]p4:
Index: clang/test/SemaTemplate/concepts.cpp =================================================================== --- clang/test/SemaTemplate/concepts.cpp +++ clang/test/SemaTemplate/concepts.cpp @@ -766,3 +766,24 @@ __iterator_traits_member_pointer_or_arrow_or_void<counted_iterator<int>> f; } }// namespace InheritedFromPartialSpec + +namespace GH48182 { +template<typename, typename..., typename = int> // expected-error{{template parameter pack must be the last template parameter}} +concept invalid = true; + +template<typename> requires invalid<int> // expected-error{{use of undeclared identifier 'invalid'}} +no errors are printed +; + +static_assert(invalid<int> also here ; // expected-error{{use of undeclared identifier 'invalid'}} + +int foo() { + bool b; + b = invalid<int> not just in declarations; // expected-error{{expected ';' after expression}} + // expected-error@-1{{use of undeclared identifier 'invalid'}} + // expected-error@-2{{expected ';' after expression}} + // expected-error@-3{{use of undeclared identifier 'just'}} + // expected-error@-4{{unknown type name 'in'}} + return b; +} +} // namespace GH48182 \ No newline at end of file Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -8923,17 +8923,31 @@ return nullptr; } - if (TemplateParameterLists.front()->size() == 0) { + TemplateParameterList *Params = TemplateParameterLists.front(); + + if (Params->size() == 0) { Diag(NameLoc, diag::err_concept_no_parameters); return nullptr; } + for (TemplateParameterList::const_iterator ParamIt = Params->begin(), + ParamEnd = Params->end(); + ParamIt != ParamEnd; ++ParamIt) { + Decl const *Param = *ParamIt; + if (Param->isParameterPack()) { + if (++ParamIt == ParamEnd) + break; + Diag(Param->getLocation(), + diag::err_template_param_pack_must_be_last_template_parameter); + return nullptr; + } + } + if (DiagnoseUnexpandedParameterPack(ConstraintExpr)) return nullptr; - ConceptDecl *NewDecl = ConceptDecl::Create(Context, DC, NameLoc, Name, - TemplateParameterLists.front(), - ConstraintExpr); + ConceptDecl *NewDecl = + ConceptDecl::Create(Context, DC, NameLoc, Name, Params, ConstraintExpr); if (NewDecl->hasAssociatedConstraints()) { // C++2a [temp.concept]p4:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits