From abe7f558cc1e770fdf00b2b84e590526eda6c877 Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Mon, 19 Feb 2024 22:45:00 +0100 Subject: [PATCH] [Clang] Fixes to immediate-escalating functions * Consider that immediate escalating function can appear at global scope, fixing a crash * Lambda conversion to function pointer was sometimes not performed in an immediate function context when it should be. Fixes #82258 --- clang/docs/ReleaseNotes.rst | 4 +++ clang/include/clang/Sema/Sema.h | 4 ++- clang/lib/Sema/SemaExpr.cpp | 4 +-- .../SemaCXX/cxx2b-consteval-propagate.cpp | 26 +++++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 649ad655905af2..7524741e8ed0ab 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -267,6 +267,10 @@ Bug Fixes to C++ Support was only accepted at namespace scope but not at local function scope. - Clang no longer tries to call consteval constructors at runtime when they appear in a member initializer. (`#782154 `_`) +- Fix crash when using an immediate-escalated function at global scope. + (`#82258 `_) +- Correctly immediate-escalate lambda conversion functions. + (`#82258 `_) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e9cd42ae777df5..6a71fc9a0bf87c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1158,7 +1158,9 @@ class Sema final { if (FD) { FD->setWillHaveBody(true); S.ExprEvalContexts.back().InImmediateFunctionContext = - FD->isImmediateFunction(); + FD->isImmediateFunction() || + S.ExprEvalContexts[S.ExprEvalContexts.size() - 2] + .isConstantEvaluated(); S.ExprEvalContexts.back().InImmediateEscalatingFunctionContext = S.getLangOpts().CPlusPlus20 && FD->isImmediateEscalating(); } else diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 37a7db889a6eac..816ee9e281359a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -18311,7 +18311,6 @@ void Sema::CheckUnusedVolatileAssignment(Expr *E) { } void Sema::MarkExpressionAsImmediateEscalating(Expr *E) { - assert(!FunctionScopes.empty() && "Expected a function scope"); assert(getLangOpts().CPlusPlus20 && ExprEvalContexts.back().InImmediateEscalatingFunctionContext && "Cannot mark an immediate escalating expression outside of an " @@ -18328,7 +18327,8 @@ void Sema::MarkExpressionAsImmediateEscalating(Expr *E) { } else { assert(false && "expected an immediately escalating expression"); } - getCurFunction()->FoundImmediateEscalatingExpression = true; + if (FunctionScopeInfo *FI = getCurFunction()) + FI->FoundImmediateEscalatingExpression = true; } ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) { diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp index 531a6262287335..4a75392045d05a 100644 --- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp +++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp @@ -368,3 +368,29 @@ vector v{}; // expected-note@-2 {{in call to 'vector()'}} } + + +namespace GH82258 { + +template +constexpr auto none_of(R&& r, Pred pred) -> bool { return true; } + +struct info { int value; }; +consteval auto is_invalid(info i) -> bool { return false; } +constexpr info types[] = { {1}, {3}, {5}}; + +static_assert(none_of( + types, + +[](info i) consteval { + return is_invalid(i); + } +)); + +static_assert(none_of( + types, + []{ + return is_invalid; + }() +)); + +}