Skip to content

[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

Merged
merged 3 commits into from
Jun 1, 2024

Conversation

zyn0217
Copy link
Contributor

@zyn0217 zyn0217 commented May 31, 2024

This helps getTemplateInstantiationArgs to properly recover template arguments of an enclosing concept Decl.

Fixes #93821

This helps getTemplateInstantiationArgs to properly recover template
arguments of an enclosing concept Decl.

Fixes llvm#93821
@zyn0217 zyn0217 added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label May 31, 2024
@zyn0217 zyn0217 requested a review from erichkeane May 31, 2024 10:20
@llvmbot llvmbot added the clang Clang issues not falling into any other category label May 31, 2024
@llvmbot
Copy link
Member

llvmbot commented May 31, 2024

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

Changes

This 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:

  • (modified) clang/docs/ReleaseNotes.rst (+1)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+14)
  • (modified) clang/test/SemaTemplate/concepts-lambda.cpp (+12)
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,
Copy link
Contributor

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!)

Copy link
Contributor Author

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:

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.)

Copy link
Collaborator

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.

Copy link
Contributor Author

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.

@zyn0217 zyn0217 merged commit 16397e8 into llvm:main Jun 1, 2024
5 of 8 checks passed
@zyn0217 zyn0217 deleted the gh93821 branch June 1, 2024 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[clang++ 17.0.6] Segfault from using a concept which has immediatly invoked generic lambda with constrained template parameter.
4 participants