Author: Daniel M. Katz Date: 2024-04-25T09:41:25+02:00 New Revision: 5e767bd7d16dcdfc1ad8b32ba399f969dd940f57
URL: https://github.com/llvm/llvm-project/commit/5e767bd7d16dcdfc1ad8b32ba399f969dd940f57 DIFF: https://github.com/llvm/llvm-project/commit/5e767bd7d16dcdfc1ad8b32ba399f969dd940f57.diff LOG: Push immediate function context while transforming lambdas in templates. (#89702) The following program is [accepted](https://godbolt.org/z/oEc34Trh4) by Clang, EDG, and MSVC, but rejected by Clang: ```cpp #include <vector> consteval auto fn() { return std::vector {1,2,3}; } template <typename T = int> void fn2() { (void)[]() consteval { for (auto e : fn()) {} }; } void caller() { fn2(); } ``` The stated diagnostic is: ```cpp <source>: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`. Co-authored-by: cor3ntin <corentinja...@gmail.com> Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/TreeTransform.h clang/test/SemaCXX/cxx2a-consteval.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7bea43ec64f062..0bad03eda8cb54 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -564,6 +564,8 @@ Bug Fixes to C++ Support - Fixed a crash when trying to evaluate a user-defined ``static_assert`` message whose ``size()`` function returns a large or negative value. Fixes (#GH89407). - Fixed a use-after-free bug in parsing of type constraints with default arguments that involve lambdas. (#GH67235) +- 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 AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 9404be5a46f3f7..1d30ba31e17940 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -14186,6 +14186,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..e198074372072d 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_lambda_in_template { +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; }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits