diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index fa5509f0f14f88..f20e4751f41a36 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1141,7 +1141,7 @@ static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, TemplateArgumentList TAL{TemplateArgumentList::OnStack, CSE->getTemplateArguments()}; MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs( - CSE->getNamedConcept(), /*Final=*/true, &TAL, + CSE->getNamedConcept(), /*Final=*/false, &TAL, /*RelativeToPrimary=*/true, /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/true); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 4e9541abb0af54..e3eef9323b2f8d 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1482,57 +1482,53 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, // C++2b: // Otherwise, if the type contains a placeholder type, it is replaced by the // type determined by placeholder type deduction. - if (const DeducedType *Deduced = Ty->getContainedDeducedType(); - Deduced && !Deduced->isDeduced()) { - if (isa(Deduced)) { - Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity, Kind, - Exprs); - if (Ty.isNull()) - return ExprError(); - Entity = InitializedEntity::InitializeTemporary(TInfo, Ty); - } else { - assert(isa(Deduced)); - MultiExprArg Inits = Exprs; - if (ListInitialization) { - auto *ILE = cast(Exprs[0]); - Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits()); - } - - if (Inits.empty()) - return ExprError( - Diag(TyBeginLoc, diag::err_auto_expr_init_no_expression) - << Ty << FullRange); - if (Inits.size() > 1) { - Expr *FirstBad = Inits[1]; - return ExprError(Diag(FirstBad->getBeginLoc(), - diag::err_auto_expr_init_multiple_expressions) - << Ty << FullRange); - } - if (getLangOpts().CPlusPlus2b) { - if (Ty->getAs()) - Diag(TyBeginLoc, diag::warn_cxx20_compat_auto_expr) << FullRange; - } - Expr *Deduce = Inits[0]; - if (isa(Deduce)) - return ExprError( - Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces) - << ListInitialization << Ty << FullRange); - QualType DeducedType; - TemplateDeductionInfo Info(Deduce->getExprLoc()); - TemplateDeductionResult Result = - DeduceAutoType(TInfo->getTypeLoc(), Deduce, DeducedType, Info); - if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed) - return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_deduction_failure) - << Ty << Deduce->getType() << FullRange - << Deduce->getSourceRange()); - if (DeducedType.isNull()) { - assert(Result == TDK_AlreadyDiagnosed); - return ExprError(); - } + DeducedType *Deduced = Ty->getContainedDeducedType(); + if (Deduced && isa(Deduced)) { + Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity, + Kind, Exprs); + if (Ty.isNull()) + return ExprError(); + Entity = InitializedEntity::InitializeTemporary(TInfo, Ty); + } else if (Deduced) { + MultiExprArg Inits = Exprs; + if (ListInitialization) { + auto *ILE = cast(Exprs[0]); + Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits()); + } - Ty = DeducedType; - Entity = InitializedEntity::InitializeTemporary(TInfo, Ty); + if (Inits.empty()) + return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_init_no_expression) + << Ty << FullRange); + if (Inits.size() > 1) { + Expr *FirstBad = Inits[1]; + return ExprError(Diag(FirstBad->getBeginLoc(), + diag::err_auto_expr_init_multiple_expressions) + << Ty << FullRange); } + if (getLangOpts().CPlusPlus2b) { + if (Ty->getAs()) + Diag(TyBeginLoc, diag::warn_cxx20_compat_auto_expr) << FullRange; + } + Expr *Deduce = Inits[0]; + if (isa(Deduce)) + return ExprError( + Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces) + << ListInitialization << Ty << FullRange); + QualType DeducedType; + TemplateDeductionInfo Info(Deduce->getExprLoc()); + TemplateDeductionResult Result = + DeduceAutoType(TInfo->getTypeLoc(), Deduce, DeducedType, Info); + if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed) + return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_deduction_failure) + << Ty << Deduce->getType() << FullRange + << Deduce->getSourceRange()); + if (DeducedType.isNull()) { + assert(Result == TDK_AlreadyDiagnosed); + return ExprError(); + } + + Ty = DeducedType; + Entity = InitializedEntity::InitializeTemporary(TInfo, Ty); } if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) { @@ -2019,62 +2015,59 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, DirectInitRange.getEnd()); // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for. - if (const DeducedType *Deduced = AllocType->getContainedDeducedType(); - Deduced && !Deduced->isDeduced()) { - if (isa(Deduced)) { - if (ArraySize) - return ExprError( - Diag(*ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(), - diag::err_deduced_class_template_compound_type) - << /*array*/ 2 - << (*ArraySize ? (*ArraySize)->getSourceRange() : TypeRange)); - - InitializedEntity Entity = - InitializedEntity::InitializeNew(StartLoc, AllocType); - AllocType = DeduceTemplateSpecializationFromInitializer( - AllocTypeInfo, Entity, Kind, Exprs); - if (AllocType.isNull()) - return ExprError(); - } else { - assert(isa(Deduced)); - MultiExprArg Inits = Exprs; - bool Braced = (initStyle == CXXNewExpr::ListInit); - if (Braced) { - auto *ILE = cast(Exprs[0]); - Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits()); - } + auto *Deduced = AllocType->getContainedDeducedType(); + if (Deduced && isa(Deduced)) { + if (ArraySize) + return ExprError( + Diag(*ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(), + diag::err_deduced_class_template_compound_type) + << /*array*/ 2 + << (*ArraySize ? (*ArraySize)->getSourceRange() : TypeRange)); - if (initStyle == CXXNewExpr::NoInit || Inits.empty()) - return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg) - << AllocType << TypeRange); - if (Inits.size() > 1) { - Expr *FirstBad = Inits[1]; - return ExprError(Diag(FirstBad->getBeginLoc(), - diag::err_auto_new_ctor_multiple_expressions) - << AllocType << TypeRange); - } - if (Braced && !getLangOpts().CPlusPlus17) - Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init) - << AllocType << TypeRange; - Expr *Deduce = Inits[0]; - if (isa(Deduce)) - return ExprError( - Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces) - << Braced << AllocType << TypeRange); - QualType DeducedType; - TemplateDeductionInfo Info(Deduce->getExprLoc()); - TemplateDeductionResult Result = DeduceAutoType( - AllocTypeInfo->getTypeLoc(), Deduce, DeducedType, Info); - if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed) - return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure) - << AllocType << Deduce->getType() << TypeRange - << Deduce->getSourceRange()); - if (DeducedType.isNull()) { - assert(Result == TDK_AlreadyDiagnosed); - return ExprError(); - } - AllocType = DeducedType; + InitializedEntity Entity + = InitializedEntity::InitializeNew(StartLoc, AllocType); + AllocType = DeduceTemplateSpecializationFromInitializer( + AllocTypeInfo, Entity, Kind, Exprs); + if (AllocType.isNull()) + return ExprError(); + } else if (Deduced) { + MultiExprArg Inits = Exprs; + bool Braced = (initStyle == CXXNewExpr::ListInit); + if (Braced) { + auto *ILE = cast(Exprs[0]); + Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits()); + } + + if (initStyle == CXXNewExpr::NoInit || Inits.empty()) + return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg) + << AllocType << TypeRange); + if (Inits.size() > 1) { + Expr *FirstBad = Inits[1]; + return ExprError(Diag(FirstBad->getBeginLoc(), + diag::err_auto_new_ctor_multiple_expressions) + << AllocType << TypeRange); + } + if (Braced && !getLangOpts().CPlusPlus17) + Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init) + << AllocType << TypeRange; + Expr *Deduce = Inits[0]; + if (isa(Deduce)) + return ExprError( + Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces) + << Braced << AllocType << TypeRange); + QualType DeducedType; + TemplateDeductionInfo Info(Deduce->getExprLoc()); + TemplateDeductionResult Result = + DeduceAutoType(AllocTypeInfo->getTypeLoc(), Deduce, DeducedType, Info); + if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed) + return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure) + << AllocType << Deduce->getType() << TypeRange + << Deduce->getSourceRange()); + if (DeducedType.isNull()) { + assert(Result == TDK_AlreadyDiagnosed); + return ExprError(); } + AllocType = DeducedType; } // Per C++0x [expr.new]p5, the type being constructed may be a @@ -9025,7 +9018,8 @@ Sema::BuildExprRequirement( // be satisfied. TemplateParameterList *TPL = ReturnTypeRequirement.getTypeConstraintTemplateParameterList(); - QualType MatchedType = Context.getReferenceQualifiedType(E); + QualType MatchedType = + Context.getReferenceQualifiedType(E).getCanonicalType(); llvm::SmallVector Args; Args.push_back(TemplateArgument(MatchedType)); @@ -9033,7 +9027,7 @@ Sema::BuildExprRequirement( TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args); MultiLevelTemplateArgumentList MLTAL(Param, TAL.asArray(), - /*Final=*/true); + /*Final=*/false); MLTAL.addOuterRetainedLevels(TPL->getDepth()); Expr *IDC = Param->getTypeConstraint()->getImmediatelyDeclaredConstraint(); ExprResult Constraint = SubstExpr(IDC, MLTAL); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 17f0d0263a3d98..8466ed0da39010 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4875,13 +4875,13 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, auto *CSD = ImplicitConceptSpecializationDecl::Create( Context, NamedConcept->getDeclContext(), NamedConcept->getLocation(), - SugaredConverted); + CanonicalConverted); ConstraintSatisfaction Satisfaction; bool AreArgsDependent = TemplateSpecializationType::anyDependentTemplateArguments( - *TemplateArgs, SugaredConverted); - MultiLevelTemplateArgumentList MLTAL(NamedConcept, SugaredConverted, - /*Final=*/true); + *TemplateArgs, CanonicalConverted); + MultiLevelTemplateArgumentList MLTAL(NamedConcept, CanonicalConverted, + /*Final=*/false); LocalInstantiationScope Scope(*this); EnterExpressionEvaluationContext EECtx{ @@ -6117,7 +6117,7 @@ bool Sema::CheckTemplateArgumentList( if (!PartialTemplateArgs) { TemplateArgumentList StackTemplateArgs(TemplateArgumentList::OnStack, - SugaredConverted); + CanonicalConverted); // Setup the context/ThisScope for the case where we are needing to // re-instantiate constraints outside of normal instantiation. DeclContext *NewContext = Template->getDeclContext(); @@ -6137,7 +6137,7 @@ bool Sema::CheckTemplateArgumentList( CXXThisScopeRAII(*this, RD, ThisQuals, RD != nullptr); MultiLevelTemplateArgumentList MLTAL = getTemplateInstantiationArgs( - Template, /*Final=*/true, &StackTemplateArgs, + Template, /*Final=*/false, &StackTemplateArgs, /*RelativeToPrimary=*/true, /*Pattern=*/nullptr, /*ForConceptInstantiation=*/true); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index b536e50be4c32e..9e48a2a35a344e 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2869,10 +2869,10 @@ CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template, bool NeedsReplacement = DeducedArgsNeedReplacement(Template); TemplateArgumentList DeducedTAL{TemplateArgumentList::OnStack, - SugaredDeducedArgs}; + CanonicalDeducedArgs}; MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs( - Template, /*Final=*/true, + Template, /*Final=*/false, /*InnerMost=*/NeedsReplacement ? nullptr : &DeducedTAL, /*RelativeToPrimary=*/true, /*Pattern=*/ nullptr, /*ForConstraintInstantiation=*/true); @@ -2882,7 +2882,7 @@ CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template, // not class-scope explicit specialization, so replace with Deduced Args // instead of adding to inner-most. if (NeedsReplacement) - MLTAL.replaceInnermostTemplateArguments(SugaredDeducedArgs); + MLTAL.replaceInnermostTemplateArguments(CanonicalDeducedArgs); if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, MLTAL, Info.getLocation(), @@ -4656,8 +4656,8 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, /*PartialTemplateArgs=*/false, SugaredConverted, CanonicalConverted)) return true; - MultiLevelTemplateArgumentList MLTAL(Concept, SugaredConverted, - /*Final=*/true); + MultiLevelTemplateArgumentList MLTAL(Concept, CanonicalConverted, + /*Final=*/false); if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()}, MLTAL, TypeLoc.getLocalSourceRange(), Satisfaction)) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index b7828441785c23..8173f7fb5e56be 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2271,7 +2271,7 @@ void ASTDeclReader::VisitImplicitConceptSpecializationDecl( VisitDecl(D); llvm::SmallVector Args; for (unsigned I = 0; I < D->NumTemplateArgs; ++I) - Args.push_back(Record.readTemplateArgument(/*Canonicalize=*/false)); + Args.push_back(Record.readTemplateArgument(/*Canonicalize=*/true)); D->setTemplateArguments(Args); } diff --git a/clang/test/AST/ast-dump-concepts.cpp b/clang/test/AST/ast-dump-concepts.cpp index b835ab5f8d8861..06518a71987a22 100644 --- a/clang/test/AST/ast-dump-concepts.cpp +++ b/clang/test/AST/ast-dump-concepts.cpp @@ -20,9 +20,8 @@ struct Foo { // CHECK: TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 'binary_concept' // CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} 'bool' Concept {{.*}} 'binary_concept' // CHECK-NEXT: |-ImplicitConceptSpecializationDecl {{.*}} col:9 - // CHECK-NEXT: | |-TemplateArgument type 'R' - // CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'R' dependent {{.*}}depth 1 index 0 - // CHECK-NEXT: | | `-TemplateTypeParm {{.*}} 'R' + // CHECK-NEXT: | |-TemplateArgument type 'type-parameter-1-0' + // CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent {{.*}}depth 1 index 0 // CHECK-NEXT: | `-TemplateArgument type 'int' // CHECK-NEXT: | `-BuiltinType {{.*}} 'int' // CHECK-NEXT: |-TemplateArgument {{.*}} type 'R' @@ -36,9 +35,8 @@ struct Foo { // CHECK: TemplateTypeParmDecl {{.*}} referenced Concept {{.*}} 'unary_concept' // CHECK-NEXT: `-ConceptSpecializationExpr {{.*}} 'bool' // CHECK-NEXT: |-ImplicitConceptSpecializationDecl {{.*}} col:9 - // CHECK-NEXT: | `-TemplateArgument type 'R' - // CHECK-NEXT: | `-TemplateTypeParmType {{.*}} 'R' dependent {{.*}}depth 1 index 0 - // CHECK-NEXT: | `-TemplateTypeParm {{.*}} 'R' + // CHECK-NEXT: | `-TemplateArgument type 'type-parameter-1-0' + // CHECK-NEXT: | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent {{.*}}depth 1 index 0 template Foo(R); diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp index 7f5bbc5b038b75..b7366207882f9e 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp @@ -35,14 +35,14 @@ using r2i2 = r2; // expected-error{{constraints not satisfied for class templ using r2i3 = r2; using r2i4 = r2; // expected-error{{constraints not satisfied for class template 'r2' [with T = const D]}} -template requires requires { { sizeof(T) }; } // expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}} expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'class nonexistent'}} +template requires requires { { sizeof(T) }; } // expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}} expected-note{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'nonexistent'}} struct r3 {}; using r3i1 = r3; using r3i2 = r3; using r3i3 = r3; using r3i4 = r3; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}} -using r3i4 = r3; // expected-error{{constraints not satisfied for class template 'r3' [with T = class nonexistent]}} +using r3i4 = r3; // expected-error{{constraints not satisfied for class template 'r3' [with T = nonexistent]}} // Non-dependent expressions @@ -149,7 +149,7 @@ namespace std_example { template constexpr bool is_same_v = true; template concept same_as = is_same_v; - // expected-note@-1 {{because 'is_same_v' evaluated to false}} + // expected-note@-1 {{because 'is_same_v' evaluated to false}} static_assert(C1); static_assert(C1); @@ -173,9 +173,9 @@ namespace std_example { int operator *() { return 0; } }; static_assert(C2); - template struct C2_check {}; // expected-note{{because 'int' does not satisfy 'C2'}} expected-note{{because 'T2' does not satisfy 'C2'}} + template struct C2_check {}; // expected-note{{because 'int' does not satisfy 'C2'}} expected-note{{because 'std_example::T2' does not satisfy 'C2'}} using c2c1 = C2_check; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = int]}} - using c2c2 = C2_check; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = T2]}} + using c2c2 = C2_check; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = std_example::T2]}} template void g(T t) noexcept(sizeof(T) == 1) {} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp index 3abff0bb32e1cc..e7428b5061c2e9 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp @@ -27,7 +27,7 @@ using r4i = X::r4; // expected-error{{constraints not satisfied for c // C++ [expr.prim.req.nested] Examples namespace std_example { - template concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(decltype(+t)) == 1' (4 == 1) evaluated to false}} + template concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(int) == 1' (4 == 1) evaluated to false}} template concept D = requires (T t) { requires C1; // expected-note{{because 'decltype(+t)' (aka 'int') does not satisfy 'C1'}} diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp index abfadfa3488411..7515f5c62d5ea8 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp @@ -39,14 +39,14 @@ using r2i4 = r2; // expected-error{{constraints not satisfied for class template requires requires { sizeof(T); } // expected-note@-1{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}} -// expected-note@-2{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'class nonexistent'}} +// expected-note@-2{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'nonexistent'}} struct r3 {}; using r3i1 = r3; using r3i2 = r3; using r3i3 = r3; using r3i4 = r3; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}} -using r3i4 = r3; // expected-error{{constraints not satisfied for class template 'r3' [with T = class nonexistent]}} +using r3i4 = r3; // expected-error{{constraints not satisfied for class template 'r3' [with T = nonexistent]}} template requires requires (T t) { 0; "a"; (void)'a'; } struct r4 {}; diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp index 28dff336d053c6..5433cfb21955dd 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp @@ -182,14 +182,14 @@ namespace std_example { static_assert(C1 && C2 && C3); template struct C1_check {}; // expected-note@-1 {{because 'int' does not satisfy 'C1'}} - // expected-note@-2 {{because 'has_type' does not satisfy 'C1'}} + // expected-note@-2 {{because 'std_example::has_type' does not satisfy 'C1'}} template struct C2_check {}; - // expected-note@-1 {{because 'has_inner' does not satisfy 'C2'}} + // expected-note@-1 {{because 'std_example::has_inner' does not satisfy 'C2'}} template struct C3_check {}; // expected-note@-1 {{because 'void' does not satisfy 'C3'}} using c1 = C1_check; // expected-error{{constraints not satisfied for class template 'C1_check' [with T = int]}} - using c2 = C1_check; // expected-error{{constraints not satisfied for class template 'C1_check' [with T = has_type]}} - using c3 = C2_check; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = has_inner]}} + using c2 = C1_check; // expected-error{{constraints not satisfied for class template 'C1_check' [with T = std_example::has_type]}} + using c3 = C2_check; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = std_example::has_inner]}} using c4 = C3_check; // expected-error{{constraints not satisfied for class template 'C3_check' [with T = void]}} } @@ -199,10 +199,10 @@ template concept C = requires { requires requires { T::a; }; }; // expected-note@-1 {{because 'T::a' would be invalid: no member named 'a' in 'PR48656::T1'}} template struct A {}; -// expected-note@-1 {{because 'T1' does not satisfy 'C'}} +// expected-note@-1 {{because 'PR48656::T1' does not satisfy 'C'}} struct T1 {}; -template struct A; // expected-error {{constraints not satisfied for class template 'A' [with $0 = ]}} +template struct A; // expected-error {{constraints not satisfied for class template 'A' [with $0 = ]}} struct T2 { static constexpr bool a = false; }; template struct A; diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp index 02c97b4591a156..d80710937cdfa1 100644 --- a/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp +++ b/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp @@ -8,7 +8,7 @@ template requires Bar && true struct S { }; template concept True2 = sizeof(T) >= 0; template concept Foo2 = True2; -// expected-error@-1{{'type name' declared as a pointer to a reference of type 'T &'}} +// expected-error@-1{{'type name' declared as a pointer to a reference of type 'type-parameter-0-0 &'}} template concept Bar2 = Foo2; // expected-note@-1{{while substituting into concept arguments here; substitution failures not allowed in concept arguments}} template requires Bar2 struct S2 { }; diff --git a/clang/test/CXX/temp/temp.param/p10-2a.cpp b/clang/test/CXX/temp/temp.param/p10-2a.cpp index 97e0ef35837b16..4f5fdd3b4809ac 100644 --- a/clang/test/CXX/temp/temp.param/p10-2a.cpp +++ b/clang/test/CXX/temp/temp.param/p10-2a.cpp @@ -94,8 +94,8 @@ concept OneOf = (is_same_v || ...); // expected-note@-5 {{and 'is_same_v' evaluated to false}} // expected-note@-6 3{{because 'is_same_v' evaluated to false}} // expected-note@-7 3{{and 'is_same_v' evaluated to false}} -// expected-note@-8 2{{because 'is_same_v' evaluated to false}} -// expected-note@-9 2{{and 'is_same_v' evaluated to false}} +// expected-note@-8 2{{because 'is_same_v' evaluated to false}} +// expected-note@-9 2{{and 'is_same_v' evaluated to false}} template T, OneOf U> // expected-note@-1 2{{because 'OneOf' evaluated to false}} diff --git a/clang/test/SemaTemplate/concepts-recursive-inst.cpp b/clang/test/SemaTemplate/concepts-recursive-inst.cpp index 651ce1a4905580..d370f0e2a641bd 100644 --- a/clang/test/SemaTemplate/concepts-recursive-inst.cpp +++ b/clang/test/SemaTemplate/concepts-recursive-inst.cpp @@ -98,25 +98,18 @@ namespace GH50891 { }; static_assert(Numeric); // #STATIC_ASSERT - // expected-error@#OP_TO {{satisfaction of constraint 'Numeric' depends on itself}} - // expected-note@#OP_TO {{while substituting template arguments into constraint expression here}} - // FIXME: The following two refer to type-parameter-0-0, it would be nice to - // see if we could instead diagnose with the sugared name. - // expected-note@#FOO_CALL {{while checking constraint satisfaction for template}} - // expected-note@#FOO_CALL {{while substituting deduced template arguments into function template}} - // expected-note@#FOO_CALL {{in instantiation of requirement here}} + // expected-error@#NUMERIC{{satisfaction of constraint 'requires (T a) { foo(a); }' depends on itself}} // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} - // expected-note@#OP_TO {{skipping 2 contexts in backtrace}} + // expected-note@#OP_TO {{while checking the satisfaction of concept 'Numeric' requested here}} + // expected-note@#OP_TO {{while substituting template arguments into constraint expression here}} // expected-note@#FOO_CALL {{while checking constraint satisfaction for template}} // expected-note@#FOO_CALL {{in instantiation of function template specialization}} // expected-note@#FOO_CALL {{in instantiation of requirement here}} // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} - // expected-note@#STATIC_ASSERT{{while checking the satisfaction of concept 'Numeric' requested here}} - // Fallout of that failure is that deferred does not satisfy numeric, - // which is unfortunate, but about what we can accomplish here. // expected-error@#STATIC_ASSERT {{static assertion failed}} - // expected-note@#STATIC_ASSERT{{because 'Deferred' does not satisfy 'Numeric'}} - // expected-note@#FOO_CALL {{because 'foo(a)' would be invalid}} + // expected-note@#STATIC_ASSERT{{while checking the satisfaction of concept 'Numeric' requested here}} + // expected-note@#STATIC_ASSERT{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + } // namespace GH50891 diff --git a/clang/test/SemaTemplate/cxx2a-constraint-caching.cpp b/clang/test/SemaTemplate/cxx2a-constraint-caching.cpp index 6b6db373cfb53d..d44a42926891f4 100644 --- a/clang/test/SemaTemplate/cxx2a-constraint-caching.cpp +++ b/clang/test/SemaTemplate/cxx2a-constraint-caching.cpp @@ -14,13 +14,15 @@ constexpr bool foo() requires (f(T()), true) { return true; } namespace a { struct A {}; constexpr void f(A a) {} +} - static_assert(C); - static_assert(foo()); +static_assert(C); +static_assert(foo()); +namespace a { // This makes calls to f ambiguous, but the second check will still succeed // because the constraint satisfaction results are cached. constexpr void f(A a, int = 2) {} - static_assert(C); - static_assert(foo()); -} // namespace a +} +static_assert(C); +static_assert(foo()); diff --git a/clang/test/SemaTemplate/instantiate-requires-expr.cpp b/clang/test/SemaTemplate/instantiate-requires-expr.cpp index a9d8b8b7dac68e..ba82fc1313fc95 100644 --- a/clang/test/SemaTemplate/instantiate-requires-expr.cpp +++ b/clang/test/SemaTemplate/instantiate-requires-expr.cpp @@ -76,8 +76,8 @@ namespace type_requirement { // expected-note@-2 {{because 'false_v::temp >; }>' evaluated to false}} struct r2 {}; - using r2i1 = r2>; // expected-error{{constraints not satisfied for class template 'r2' [with T = contains_template]}} - using r2i2 = r2>; // expected-error{{constraints not satisfied for class template 'r2' [with T = contains_template]}} + using r2i1 = r2>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template]}} + using r2i2 = r2>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template]}} // substitution error occurs, then requires expr is instantiated again @@ -108,7 +108,7 @@ namespace type_requirement { // expected-note@-1 {{because 'false_v>; } && requires { <>; }>' evaluated to false}} struct r7 {}; - using r7i = r7; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = ]}} + using r7i = r7; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = ]}} } namespace expr_requirement { @@ -227,13 +227,3 @@ struct r6 {}; using r6i = r6; // expected-error@-1 {{constraints not satisfied for class template 'r6' [with T = int]}} - -namespace sugared_instantiation { - template concept C = requires { C1{}; }; - template concept D = requires { new D1; }; - - // Test that 'deduced auto' doesn't get confused with 'undeduced auto'. - auto f() { return 0; } - static_assert(requires { { f() } -> C; }); - static_assert(requires { { f() } -> D; }); -} // namespace sugared_instantiation diff --git a/clang/test/SemaTemplate/pr52970.cpp b/clang/test/SemaTemplate/pr52970.cpp index 6aabc419bd2b88..7aac5ee8565934 100644 --- a/clang/test/SemaTemplate/pr52970.cpp +++ b/clang/test/SemaTemplate/pr52970.cpp @@ -53,7 +53,7 @@ static_assert(!DotFollowingPointer::f(Bad{}), ""); #if __cplusplus >= 202002L template concept C = requires(T t) { t.begin(); }; - // cxx20-note@-1 {{because 't.begin()' would be invalid: member reference type 'Bad' (aka 'Holder *') is a pointer}} + // cxx20-note@-1 {{because 't.begin()' would be invalid: member reference type 'Holder *' is a pointer}} static_assert(C); static_assert(!C);