Skip to content

Commit 16397e8

Browse files
authored
[Clang][Sema] Push an evaluation context for type constraints (#93945)
This helps getTemplateInstantiationArgs() to properly recover template arguments of an enclosing concept Decl. Fixes #93821
1 parent daaaf4e commit 16397e8

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,7 @@ Bug Fixes to C++ Support
822822
- Fix a regression introduced in Clang 18 causing incorrect overload resolution in the presence of functions only
823823
differering by their constraints when only one of these function was variadic.
824824
- Fix a crash when a variable is captured by a block nested inside a lambda. (Fixes #GH93625).
825+
- Fixed a type constraint substitution issue involving a generic lambda expression. (#GH93821)
825826

826827
Bug Fixes to AST Handling
827828
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5660,7 +5660,7 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
56605660
LocalInstantiationScope Scope(*this);
56615661

56625662
EnterExpressionEvaluationContext EECtx{
5663-
*this, ExpressionEvaluationContext::ConstantEvaluated, CSD};
5663+
*this, ExpressionEvaluationContext::Unevaluated, CSD};
56645664

56655665
if (!AreArgsDependent &&
56665666
CheckConstraintSatisfaction(

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5134,6 +5134,20 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
51345134
return true;
51355135
MultiLevelTemplateArgumentList MLTAL(Concept, CanonicalConverted,
51365136
/*Final=*/false);
5137+
// Build up an EvaluationContext with an ImplicitConceptSpecializationDecl so
5138+
// that the template arguments of the constraint can be preserved. For
5139+
// example:
5140+
//
5141+
// template <class T>
5142+
// concept C = []<D U = void>() { return true; }();
5143+
//
5144+
// We need the argument for T while evaluating type constraint D in
5145+
// building the CallExpr to the lambda.
5146+
EnterExpressionEvaluationContext EECtx(
5147+
S, Sema::ExpressionEvaluationContext::Unevaluated,
5148+
ImplicitConceptSpecializationDecl::Create(
5149+
S.getASTContext(), Concept->getDeclContext(), Concept->getLocation(),
5150+
CanonicalConverted));
51375151
if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
51385152
MLTAL, TypeLoc.getLocalSourceRange(),
51395153
Satisfaction))

clang/test/SemaTemplate/concepts-lambda.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,15 @@ void foo() {
225225
}(x);
226226
}
227227
} // namespace GH73418
228+
229+
namespace GH93821 {
230+
231+
template <class>
232+
concept C = true;
233+
234+
template <class...>
235+
concept D = []<C T = int>() { return true; }();
236+
237+
D auto x = 0;
238+
239+
} // namespace GH93821

0 commit comments

Comments
 (0)