diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 38e03ac35bcbfc..5699c14e80fbd3 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2929,22 +2929,21 @@ namespace { static void CopyTypeConstraintFromAutoType(Sema &SemaRef, const AutoType *Auto, TemplateTypeParmDecl *TP, - const bool IsParameterPack) { - TypeSourceInfo *DI = - SemaRef.getASTContext().getTrivialTypeSourceInfo(QualType(Auto, 0)); + const Declarator &D) { + TypeSourceInfo *DI = SemaRef.getASTContext().getTrivialTypeSourceInfo( + QualType(Auto, 0), D.getBeginLoc()); const AutoTypeLoc ATL = DI->getTypeLoc().findAutoTypeLoc(); TemplateArgumentListInfo TAL(ATL.getLAngleLoc(), ATL.getRAngleLoc()); - for (unsigned Idx = 0; Idx < ATL.getNumArgs(); ++Idx) { - TAL.addArgument(ATL.getArgLoc(Idx)); - } + + if (ATL.wereArgumentsSpecified()) + for (unsigned Idx = 0, C = ATL.getNumArgs(); Idx != C; ++Idx) + TAL.addArgument(ATL.getArgLoc(Idx)); SemaRef.AttachTypeConstraint( ATL.getNestedNameSpecifierLoc(), ATL.getConceptNameInfo(), ATL.getNamedConcept(), ATL.wereArgumentsSpecified() ? &TAL : nullptr, TP, - IsParameterPack - ? DI->getTypeLoc().getAs().getEllipsisLoc() - : SourceLocation()); + D.hasEllipsis() ? D.getEllipsisLoc() : SourceLocation()); } static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, @@ -3061,8 +3060,8 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, // Attach type constraints if (Auto->isConstrained()) - CopyTypeConstraintFromAutoType( - SemaRef, Auto, CorrespondingTemplateParam, IsParameterPack); + CopyTypeConstraintFromAutoType(SemaRef, Auto, + CorrespondingTemplateParam, D); // Replace the 'auto' in the function parameter with this invented // template type parameter. diff --git a/clang/test/CXX/concepts-ts/expr/expr.prim/expr.prim.lambda/abbrev-syntax.cpp b/clang/test/CXX/concepts-ts/expr/expr.prim/expr.prim.lambda/abbrev-syntax.cpp new file mode 100644 index 00000000000000..5b949fd63bcaee --- /dev/null +++ b/clang/test/CXX/concepts-ts/expr/expr.prim/expr.prim.lambda/abbrev-syntax.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +template +concept One = true; +// expected-note@-1 {{template is declared here}} + +template +concept Two = true; +// expected-note@-1 3{{template is declared here}} + +auto acc_1 = [](One auto) { return 0; }; +auto rej_1 = [](One auto) { return 0; }; +// expected-error@-1 {{too many template arguments for concept}} +auto rej_2_1 = [](Two auto) { return 0; }; +// expected-error@-1 {{too few template arguments for concept}} +auto acc_2_1 = [](Two auto) { return 0; }; +auto rej_2_2 = [](Two auto) { return 0; }; +// expected-error@-1 {{too many template arguments for concept}} +auto rej_2_3 = [](Two auto) { return 0; }; +// expected-error@-1 {{too many template arguments for concept}} + +template +concept LargerThan = sizeof(T) > Size; +// expected-note@-1 3{{because 'sizeof(char) > 1U' (1 > 1) evaluated to false}} + +template +concept Large = LargerThan; +// expected-note@-1 3{{because 'LargerThan' evaluated to false}} + +auto l1 = [](Large auto l) { return l; }; +// expected-note@-1{{candidate template ignored: constraints not satisfied [with l:auto = char]}} +// expected-note@-2{{because 'char' does not satisfy 'Large'}} +auto l1t1 = l1('a'); +// expected-error@-1{{no matching function for call to object of type '(lambda at}} +auto l1t2 = l1(1); + +auto l2 = [](Large auto ...ls) { return 0; }; +// expected-note@-1{{candidate template ignored: constraints not satisfied [with ls:auto = ]}} +// expected-note@-2{{candidate template ignored: constraints not satisfied [with ls:auto = ]}} +// expected-note@-3 2{{because 'char' does not satisfy 'Large'}} +auto l2t1 = l2('a'); +// expected-error@-1{{no matching function for call to object of type '(lambda at}} +auto l2t2 = l2(1, 'a'); +// expected-error@-1{{no matching function for call to object of type '(lambda at}} +auto l2t3 = l2(1, 2); +