llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Daniel M. Katz (katzdm)

<details>
<summary>Changes</summary>

The following program is [accepted](https://godbolt.org/z/oEc34Trh4) by Clang, 
EDG, and MSVC, but rejected by Clang:
```cpp
#include &lt;vector&gt;

consteval auto fn() { return std::vector {1,2,3}; }

template &lt;typename T = int&gt;
void fn2() {
    (void)[]() consteval {
      for (auto e : fn()) {}
    };
}

void caller() {
    fn2();
}
```

The stated diagnostic is:
```cpp
&lt;source&gt;:8:21: error: call to consteval function 'fn' is not a constant 
expression
    8 |       for (auto e : fn()) {}
```

The body of the lambda should be evaluated as within an immediate function 
context when the lambda is marked as `consteval`.

---
Full diff: https://github.com/llvm/llvm-project/pull/89702.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+3) 
- (modified) clang/lib/Sema/TreeTransform.h (+2) 
- (modified) clang/test/SemaCXX/cxx2a-consteval.cpp (+20) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 45a9a79739a4eb..0efdcac3c4b8e1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -420,6 +420,9 @@ Bug Fixes in This Version
 - Fixed a regression in CTAD that a friend declaration that befriends itself 
may cause
   incorrect constraint substitution. (#GH86769).
 
+- Fixed bug in which the body of a consteval lambda within a template was not 
parsed as within an
+  immediate function context.
+
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 284c9173e68ed5..a3ddebb3ca5963 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -14044,6 +14044,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr 
*E) {
   // FIXME: Sema's lambda-building mechanism expects us to push an expression
   // evaluation context even if we're not transforming the function body.
   getSema().PushExpressionEvaluationContext(
+      E->getCallOperator()->isConsteval() ?
+      Sema::ExpressionEvaluationContext::ImmediateFunctionContext :
       Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
 
   Sema::CodeSynthesisContext C;
diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp 
b/clang/test/SemaCXX/cxx2a-consteval.cpp
index 192621225a543c..b19e25e26c214c 100644
--- a/clang/test/SemaCXX/cxx2a-consteval.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -260,6 +260,26 @@ int(*test)(int)  = l1;
 
 }
 
+namespace consteval_dependent_lambda {
+struct S {
+    int *value;
+    constexpr S(int v) : value(new int {v}) {}
+    constexpr ~S() { delete value; }
+};
+consteval S fn() { return S(5); }
+
+template <typename T>
+void fn2() {
+    (void)[]() consteval -> int {
+      return *(fn().value);  // OK, immediate context
+    };
+}
+
+void caller() {
+    fn2<int>();
+}
+}
+
 namespace std {
 
 template <typename T> struct remove_reference { using type = T; };

``````````

</details>


https://github.com/llvm/llvm-project/pull/89702
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to