-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Clang][Sema] Push an evaluation context for type constraints #93945
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This helps getTemplateInstantiationArgs to properly recover template arguments of an enclosing concept Decl. Fixes llvm#93821
@llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) ChangesThis helps getTemplateInstantiationArgs to properly recover template arguments of an enclosing concept Decl. Fixes #93821 Full diff: https://github.com/llvm/llvm-project/pull/93945.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 49ab222bec405..83eb285e9ca48 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -710,6 +710,7 @@ Bug Fixes to C++ Support
- Correctly treat the compound statement of an ``if consteval`` as an immediate context. Fixes (#GH91509).
- When partial ordering alias templates against template template parameters,
allow pack expansions when the alias has a fixed-size parameter list. Fixes (#GH62529).
+- Fixed a type constraint substitution issue involving a generic lambda expression. (#GH93821)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 853c0e1b50619..56529b4d852e7 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5004,6 +5004,20 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
return true;
MultiLevelTemplateArgumentList MLTAL(Concept, CanonicalConverted,
/*Final=*/false);
+ // Build up an EvaluationContext with an ImplicitConceptSpecializationDecl so
+ // that the template arguments of the constraint can be preserved. For
+ // example:
+ //
+ // template <class T>
+ // concept C = []<D U = void>() { return true; }();
+ //
+ // We need the argument for T while evaluating type constraint D in
+ // building the CallExpr to the lambda.
+ EnterExpressionEvaluationContext EECtx(
+ S, Sema::ExpressionEvaluationContext::ConstantEvaluated,
+ ImplicitConceptSpecializationDecl::Create(
+ S.getASTContext(), Concept->getDeclContext(), Concept->getLocation(),
+ CanonicalConverted));
if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
MLTAL, TypeLoc.getLocalSourceRange(),
Satisfaction))
diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp
index fac790d09f9cf..280be71284f97 100644
--- a/clang/test/SemaTemplate/concepts-lambda.cpp
+++ b/clang/test/SemaTemplate/concepts-lambda.cpp
@@ -225,3 +225,15 @@ void foo() {
}(x);
}
} // namespace GH73418
+
+namespace GH93821 {
+
+template <class>
+concept C = true;
+
+template <class...>
+concept D = []<C T = int>() { return true; }();
+
+D auto x = 0;
+
+} // namespace GH93821
|
// We need the argument for T while evaluating type constraint D in | ||
// building the CallExpr to the lambda. | ||
EnterExpressionEvaluationContext EECtx( | ||
S, Sema::ExpressionEvaluationContext::ConstantEvaluated, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should that not be UnevaluatedContext?
https://eel.is/c++draft/temp.concept#6
(I appreciate the great comment, thanks!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. Honestly, I copied the line from Sema::CheckConceptTemplateId
:
llvm-project/clang/lib/Sema/SemaTemplate.cpp
Lines 5662 to 5670 in f34dedb
EnterExpressionEvaluationContext EECtx{ | |
*this, ExpressionEvaluationContext::ConstantEvaluated, CSD}; | |
if (!AreArgsDependent && | |
CheckConstraintSatisfaction( | |
NamedConcept, {NamedConcept->getConstraintExpr()}, MLTAL, | |
SourceRange(SS.isSet() ? SS.getBeginLoc() : ConceptNameInfo.getLoc(), | |
TemplateArgs->getRAngleLoc()), | |
Satisfaction)) |
I'll look into the details later and hopefully get back with an answer. (Of course I'd appreciate it if @erichkeane could beat me to it.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Corentin is right. And that link from SemaTemplate might actually be wrong too, but I'm not completely sure. Though I would have expected us to see a bunch of bugs for evaluating that incorreclty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed these two to Unevaluated
and all our tests were still passed.
a bunch of bugs for evaluating that incorreclty.
Probably? Or it could be we have been pushing another unevaluated context during the evaluation, so the context kind here doesn't matter.
This helps getTemplateInstantiationArgs to properly recover template arguments of an enclosing concept Decl.
Fixes #93821