[clang] 12cb1cb - Revert "[clang] Instantiate concepts with sugared template arguments"

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 17 07:29:39 PST 2023


Author: Erich Keane
Date: 2023-01-17T07:29:31-08:00
New Revision: 12cb1cb3720de8d164196010123ce1a8901d8122

URL: https://github.com/llvm/llvm-project/commit/12cb1cb3720de8d164196010123ce1a8901d8122
DIFF: https://github.com/llvm/llvm-project/commit/12cb1cb3720de8d164196010123ce1a8901d8122.diff

LOG: Revert "[clang] Instantiate concepts with sugared template arguments"

This reverts commit b8064374b217db061213c561ec8f3376681ff9c8.

Based on the report here:
https://github.com/llvm/llvm-project/issues/59271

this produces a significant increase in memory use of the compiler and a
large compile-time regression.  This patch reverts this so that we don't
branch for release with that issue.

Added: 
    

Modified: 
    clang/lib/Sema/SemaConcept.cpp
    clang/lib/Sema/SemaExprCXX.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/lib/Sema/SemaTemplateDeduction.cpp
    clang/lib/Serialization/ASTReaderDecl.cpp
    clang/test/AST/ast-dump-concepts.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
    clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp
    clang/test/CXX/temp/temp.param/p10-2a.cpp
    clang/test/SemaTemplate/concepts-recursive-inst.cpp
    clang/test/SemaTemplate/cxx2a-constraint-caching.cpp
    clang/test/SemaTemplate/instantiate-requires-expr.cpp
    clang/test/SemaTemplate/pr52970.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index fa5509f0f14f8..f20e4751f41a3 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 4e9541abb0af5..e3eef9323b2f8 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<DeducedTemplateSpecializationType>(Deduced)) {
-      Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity, Kind,
-                                                       Exprs);
-      if (Ty.isNull())
-        return ExprError();
-      Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
-    } else {
-      assert(isa<AutoType>(Deduced));
-      MultiExprArg Inits = Exprs;
-      if (ListInitialization) {
-        auto *ILE = cast<InitListExpr>(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<AutoType>())
-          Diag(TyBeginLoc, diag::warn_cxx20_compat_auto_expr) << FullRange;
-      }
-      Expr *Deduce = Inits[0];
-      if (isa<InitListExpr>(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<DeducedTemplateSpecializationType>(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<InitListExpr>(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<AutoType>())
+        Diag(TyBeginLoc, diag::warn_cxx20_compat_auto_expr) << FullRange;
+    }
+    Expr *Deduce = Inits[0];
+    if (isa<InitListExpr>(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<DeducedTemplateSpecializationType>(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<AutoType>(Deduced));
-      MultiExprArg Inits = Exprs;
-      bool Braced = (initStyle == CXXNewExpr::ListInit);
-      if (Braced) {
-        auto *ILE = cast<InitListExpr>(Exprs[0]);
-        Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
-      }
+  auto *Deduced = AllocType->getContainedDeducedType();
+  if (Deduced && isa<DeducedTemplateSpecializationType>(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<InitListExpr>(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<InitListExpr>(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<InitListExpr>(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<TemplateArgument, 1> 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 17f0d0263a3d9..8466ed0da3901 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 b536e50be4c32..9e48a2a35a344 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 b7828441785c2..8173f7fb5e56b 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2271,7 +2271,7 @@ void ASTDeclReader::VisitImplicitConceptSpecializationDecl(
   VisitDecl(D);
   llvm::SmallVector<TemplateArgument, 4> 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 b835ab5f8d886..06518a71987a2 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 {{.*}} <col:13, col:31> 'bool' Concept {{.*}} 'binary_concept'
   // CHECK-NEXT:   |-ImplicitConceptSpecializationDecl {{.*}} <line:13:9> 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 {{.*}} <col:13> 'bool'
   // CHECK-NEXT:   |-ImplicitConceptSpecializationDecl {{.*}} <line:10:9> 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 <unary_concept R>
   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 7f5bbc5b038b7..b7366207882f9 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<A>; // expected-error{{constraints not satisfied for class templ
 using r2i3 = r2<D>;
 using r2i4 = r2<const D>; // expected-error{{constraints not satisfied for class template 'r2' [with T = const D]}}
 
-template<typename T> 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<typename T> 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<int>;
 using r3i2 = r3<A>;
 using r3i3 = r3<A &>;
 using r3i4 = r3<void>; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}}
-using r3i4 = r3<class nonexistent>; // expected-error{{constraints not satisfied for class template 'r3' [with T = class nonexistent]}}
+using r3i4 = r3<class nonexistent>; // expected-error{{constraints not satisfied for class template 'r3' [with T = nonexistent]}}
 
 // Non-dependent expressions
 
@@ -149,7 +149,7 @@ namespace std_example {
   template<typename T> constexpr bool is_same_v<T, T> = true;
 
   template<typename T, typename U> concept same_as = is_same_v<T, U>;
-  // expected-note at -1 {{because 'is_same_v<int, typename T2::inner>' evaluated to false}}
+  // expected-note at -1 {{because 'is_same_v<int, int *>' evaluated to false}}
 
   static_assert(C1<int>);
   static_assert(C1<int*>);
@@ -173,9 +173,9 @@ namespace std_example {
     int operator *() { return 0; }
   };
   static_assert(C2<T1>);
-  template<C2 T> struct C2_check {}; // expected-note{{because 'int' does not satisfy 'C2'}} expected-note{{because 'T2' does not satisfy 'C2'}}
+  template<C2 T> 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<int>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = int]}}
-  using c2c2 = C2_check<T2>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = T2]}}
+  using c2c2 = C2_check<T2>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = std_example::T2]}}
 
   template<typename T>
   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 3abff0bb32e1c..e7428b5061c2e 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<void>::r4<int>; // expected-error{{constraints not satisfied for c
 
 // C++ [expr.prim.req.nested] Examples
 namespace std_example {
-  template<typename U> concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(decltype(+t)) == 1' (4 == 1) evaluated to false}}
+  template<typename U> concept C1 = sizeof(U) == 1; // expected-note{{because 'sizeof(int) == 1' (4 == 1) evaluated to false}}
   template<typename T> concept D =
     requires (T t) {
       requires C1<decltype (+t)>; // 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 abfadfa348841..7515f5c62d5ea 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<const D>; // expected-error{{constraints not satisfied for class
 
 template<typename T> requires requires { sizeof(T); }
 // expected-note at -1{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'void'}}
-// expected-note at -2{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'class nonexistent'}}
+// expected-note at -2{{because 'sizeof(T)' would be invalid: invalid application of 'sizeof' to an incomplete type 'nonexistent'}}
 struct r3 {};
 
 using r3i1 = r3<int>;
 using r3i2 = r3<A>;
 using r3i3 = r3<A &>;
 using r3i4 = r3<void>; // expected-error{{constraints not satisfied for class template 'r3' [with T = void]}}
-using r3i4 = r3<class nonexistent>; // expected-error{{constraints not satisfied for class template 'r3' [with T = class nonexistent]}}
+using r3i4 = r3<class nonexistent>; // expected-error{{constraints not satisfied for class template 'r3' [with T = nonexistent]}}
 
 template<typename T> 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 28dff336d053c..5433cfb21955d 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<has_inner_and_type> && C2<has_inner_and_type> && C3<has_inner_and_type>);
   template<C1 T> struct C1_check {};
   // expected-note at -1 {{because 'int' does not satisfy 'C1'}}
-  // expected-note at -2 {{because 'has_type' does not satisfy 'C1'}}
+  // expected-note at -2 {{because 'std_example::has_type' does not satisfy 'C1'}}
   template<C2 T> struct C2_check {};
-  // expected-note at -1 {{because 'has_inner' does not satisfy 'C2'}}
+  // expected-note at -1 {{because 'std_example::has_inner' does not satisfy 'C2'}}
   template<C3 T> struct C3_check {};
   // expected-note at -1 {{because 'void' does not satisfy 'C3'}}
   using c1 = C1_check<int>; // expected-error{{constraints not satisfied for class template 'C1_check' [with T = int]}}
-  using c2 = C1_check<has_type>; // expected-error{{constraints not satisfied for class template 'C1_check' [with T = has_type]}}
-  using c3 = C2_check<has_inner>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = has_inner]}}
+  using c2 = C1_check<has_type>; // expected-error{{constraints not satisfied for class template 'C1_check' [with T = std_example::has_type]}}
+  using c3 = C2_check<has_inner>; // expected-error{{constraints not satisfied for class template 'C2_check' [with T = std_example::has_inner]}}
   using c4 = C3_check<void>; // expected-error{{constraints not satisfied for class template 'C3_check' [with T = void]}}
 }
 
@@ -199,10 +199,10 @@ template <typename T> concept C = requires { requires requires { T::a; }; };
 // expected-note at -1 {{because 'T::a' would be invalid: no member named 'a' in 'PR48656::T1'}}
 
 template <C...> struct A {};
-// expected-note at -1 {{because 'T1' does not satisfy 'C'}}
+// expected-note at -1 {{because 'PR48656::T1' does not satisfy 'C'}}
 
 struct T1 {};
-template struct A<T1>; // expected-error {{constraints not satisfied for class template 'A' [with $0 = <T1>]}}
+template struct A<T1>; // expected-error {{constraints not satisfied for class template 'A' [with $0 = <PR48656::T1>]}}
 
 struct T2 { static constexpr bool a = false; };
 template struct A<T2>;

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 02c97b4591a15..d80710937cdfa 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<typename T> requires Bar<T> && true struct S<T> { };
 
 template<typename T> concept True2 = sizeof(T) >= 0;
 template<typename T> concept Foo2 = True2<T*>;
-// expected-error at -1{{'type name' declared as a pointer to a reference of type 'T &'}}
+// expected-error at -1{{'type name' declared as a pointer to a reference of type 'type-parameter-0-0 &'}}
 template<typename T> concept Bar2 = Foo2<T&>;
 // expected-note at -1{{while substituting into concept arguments here; substitution failures not allowed in concept arguments}}
 template<typename T> requires Bar2<T> 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 97e0ef35837b1..4f5fdd3b4809a 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<T, Ts> || ...);
 // expected-note at -5 {{and 'is_same_v<short, char>' evaluated to false}}
 // expected-note at -6 3{{because 'is_same_v<int, char[1]>' evaluated to false}}
 // expected-note at -7 3{{and 'is_same_v<int, char[2]>' evaluated to false}}
-// expected-note at -8 2{{because 'is_same_v<decltype(nullptr), char>' evaluated to false}}
-// expected-note at -9 2{{and 'is_same_v<decltype(nullptr), int>' evaluated to false}}
+// expected-note at -8 2{{because 'is_same_v<std::nullptr_t, char>' evaluated to false}}
+// expected-note at -9 2{{and 'is_same_v<std::nullptr_t, int>' evaluated to false}}
 
 template<OneOf<char[1], char[2]> T, OneOf<int, long, char> U>
 // expected-note at -1 2{{because 'OneOf<char, char[1], char[2]>' evaluated to false}}

diff  --git a/clang/test/SemaTemplate/concepts-recursive-inst.cpp b/clang/test/SemaTemplate/concepts-recursive-inst.cpp
index 651ce1a490558..d370f0e2a641b 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<Deferred>); // #STATIC_ASSERT
-  // expected-error@#OP_TO {{satisfaction of constraint 'Numeric<TO>' 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<GH50891::Deferred>' 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<Deferred>' 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<GH50891::Deferred>' 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 6b6db373cfb53..d44a42926891f 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<A>);
-  static_assert(foo<A>());
+static_assert(C<a::A>);
+static_assert(foo<a::A>());
 
+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<A>);
-  static_assert(foo<A>());
-} // namespace a
+}
+static_assert(C<a::A>);
+static_assert(foo<a::A>());

diff  --git a/clang/test/SemaTemplate/instantiate-requires-expr.cpp b/clang/test/SemaTemplate/instantiate-requires-expr.cpp
index a9d8b8b7dac68..ba82fc1313fc9 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 at -2 {{because 'false_v<requires { typename contains_template<short>::temp<contains_template<short> >; }>' evaluated to false}}
   struct r2 {};
 
-  using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = contains_template<int>]}}
-  using r2i2 = r2<contains_template<short>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = contains_template<short>]}}
+  using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<int>]}}
+  using r2i2 = r2<contains_template<short>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<short>]}}
 
   // substitution error occurs, then requires expr is instantiated again
 
@@ -108,7 +108,7 @@ namespace type_requirement {
   // expected-note at -1 {{because 'false_v<requires { <<error-type>>; } && requires { <<error-type>>; }>' evaluated to false}}
   struct r7 {};
 
-  using r7i = r7<int, A>; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = <int, A>]}}
+  using r7i = r7<int, A>; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = <int, type_requirement::A>]}}
 }
 
 namespace expr_requirement {
@@ -227,13 +227,3 @@ struct r6 {};
 
 using r6i = r6<int>;
 // expected-error at -1 {{constraints not satisfied for class template 'r6' [with T = int]}}
-
-namespace sugared_instantiation {
-  template <class C1> concept C = requires { C1{}; };
-  template <class D1> 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 6aabc419bd2b8..7aac5ee856593 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 <class T>
 concept C = requires(T t) { t.begin(); };
-  // cxx20-note at -1 {{because 't.begin()' would be invalid: member reference type 'Bad' (aka 'Holder<Incomplete> *') is a pointer}}
+  // cxx20-note at -1 {{because 't.begin()' would be invalid: member reference type 'Holder<Incomplete> *' is a pointer}}
 
 static_assert(C<Good>);
 static_assert(!C<Bad>);


        


More information about the cfe-commits mailing list