[clang] Don't wrap immediate invocations in ConstantExprs within constexpr initializers (PR #89565)
Daniel M. Katz via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 23 12:55:53 PDT 2024
================
@@ -2554,16 +2554,27 @@ Decl *Parser::ParseDeclarationAfterDeclarator(
return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
}
+static bool isConstexprVariable(const Decl *D) {
+ if (const VarDecl *Var = dyn_cast_if_present<VarDecl>(D))
+ return Var->isConstexpr();
+
+ return false;
+}
+
Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
Declarator &D, const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
// RAII type used to track whether we're inside an initializer.
struct InitializerScopeRAII {
Parser &P;
Declarator &D;
Decl *ThisDecl;
+ EnterExpressionEvaluationContext EC;
InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
- : P(P), D(D), ThisDecl(ThisDecl) {
+ : P(P), D(D), ThisDecl(ThisDecl),
+ EC(P.Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated,
+ ThisDecl, Sema::ExpressionEvaluationContextRecord::EK_Other,
+ isConstexprVariable(ThisDecl)) {
----------------
katzdm wrote:
> if I'm understanding the rule, it's not supposed to be valid.
Agreed; MSVC appears to get this right:
```
<source>(8): error C7595: 'fn': call to immediate function is not a constant expression
```
Since `int a` is not usable in a constant expression, its initializer isn't manifestly constant-evaluated. Thus only the call to `fn()` is manifestly constant-evaluated, so the access to the heap-allocated memory is ill-formed.
...as far as I can tell 😅
https://github.com/llvm/llvm-project/pull/89565
More information about the cfe-commits
mailing list