[clang] 257cc5a - [Clang] Fix concept cache for normalized fold expressions (#190312)

via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 4 19:36:54 PDT 2026


Author: Younan Zhang
Date: 2026-04-05T10:36:50+08:00
New Revision: 257cc5ad89840cdfba4affcc8fe62cf9d02d9017

URL: https://github.com/llvm/llvm-project/commit/257cc5ad89840cdfba4affcc8fe62cf9d02d9017
DIFF: https://github.com/llvm/llvm-project/commit/257cc5ad89840cdfba4affcc8fe62cf9d02d9017.diff

LOG: [Clang] Fix concept cache for normalized fold expressions (#190312)

When both outer and inner pack substitution indexes are present, we
should cache both. Otherwise we will have wrong cached result.

This is a regression fix so no release note.

Fixes https://github.com/llvm/llvm-project/issues/190169

Added: 
    

Modified: 
    clang/lib/Sema/SemaConcept.cpp
    clang/test/SemaCXX/cxx2c-fold-exprs.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 9c4f52dd7150c..5af5fa5c2ce84 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -488,6 +488,12 @@ class ConstraintSatisfactionChecker {
   ConceptDecl *ParentConcept = nullptr;
 
 private:
+  template <class Constraint>
+  UnsignedOrNone getOuterPackIndex(const Constraint &C) const {
+    return C.getPackSubstitutionIndex() ? C.getPackSubstitutionIndex()
+                                        : PackSubstitutionIndex;
+  }
+
   ExprResult
   EvaluateAtomicConstraint(const Expr *AtomicExpr,
                            const MultiLevelTemplateArgumentList &MLTAL);
@@ -798,14 +804,11 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
 
   unsigned Size = Satisfaction.Details.size();
   llvm::FoldingSetNodeID ID;
-  UnsignedOrNone OuterPackSubstIndex =
-      Constraint.getPackSubstitutionIndex()
-          ? Constraint.getPackSubstitutionIndex()
-          : PackSubstitutionIndex;
-
   ID.AddPointer(Constraint.getConstraintExpr());
-  ID.AddInteger(OuterPackSubstIndex.toInternalRepresentation());
-  HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
+  ID.AddInteger(
+      Constraint.getPackSubstitutionIndex().toInternalRepresentation());
+  ID.AddInteger(PackSubstitutionIndex.toInternalRepresentation());
+  HashParameterMapping(S, MLTAL, ID, getOuterPackIndex(Constraint))
       .VisitConstraint(Constraint);
 
   if (auto Iter = S.UnsubstitutedConstraintSatisfactionCache.find(ID);
@@ -1034,12 +1037,6 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
     const MultiLevelTemplateArgumentList &MLTAL) {
 
   const ConceptReference *ConceptId = Constraint.getConceptId();
-
-  UnsignedOrNone OuterPackSubstIndex =
-      Constraint.getPackSubstitutionIndex()
-          ? Constraint.getPackSubstitutionIndex()
-          : PackSubstitutionIndex;
-
   Sema::InstantiatingTemplate InstTemplate(
       S, ConceptId->getBeginLoc(),
       Sema::InstantiatingTemplate::ConstraintsCheck{},
@@ -1075,8 +1072,10 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
 
   llvm::FoldingSetNodeID ID;
   ID.AddPointer(Constraint.getConceptId());
-  ID.AddInteger(OuterPackSubstIndex.toInternalRepresentation());
-  HashParameterMapping(S, MLTAL, ID, OuterPackSubstIndex)
+  ID.AddInteger(
+      Constraint.getPackSubstitutionIndex().toInternalRepresentation());
+  ID.AddInteger(PackSubstitutionIndex.toInternalRepresentation());
+  HashParameterMapping(S, MLTAL, ID, getOuterPackIndex(Constraint))
       .VisitConstraint(Constraint);
 
   if (auto Iter = S.UnsubstitutedConstraintSatisfactionCache.find(ID);

diff  --git a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
index 89ddcbaf11583..5b993fead4877 100644
--- a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
+++ b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
@@ -508,3 +508,17 @@ static_assert(!__callable<__mdispatch<int>>);
 }
 
 }
+
+namespace GH190169 {
+
+template <typename Type, typename... Choices>
+concept OneOf = (... || __is_same(Type, Choices));
+
+template <typename F, typename... Ts>
+using check = decltype((F{}(Ts{}), ...));
+
+using X = check<decltype([](auto val) {
+  [](OneOf<int, char> auto) {}(val);
+}), char>;
+
+}


        


More information about the cfe-commits mailing list