@@ -18545,15 +18545,6 @@ void Sema::ActOnPureSpecifier(Decl *D, SourceLocation ZeroLoc) {
1854518545 Diag(D->getLocation(), diag::err_illegal_initializer);
1854618546}
1854718547
18548- /// Determine whether the given declaration is a global variable or
18549- /// static data member.
18550- static bool isNonlocalVariable(const Decl *D) {
18551- if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(D))
18552- return Var->hasGlobalStorage();
18553-
18554- return false;
18555- }
18556-
1855718548/// Invoked when we are about to parse an initializer for the declaration
1855818549/// 'Dcl'.
1855918550///
@@ -18562,9 +18553,7 @@ static bool isNonlocalVariable(const Decl *D) {
1856218553/// class X. If the declaration had a scope specifier, a scope will have
1856318554/// been created and passed in for this purpose. Otherwise, S will be null.
1856418555void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
18565- // If there is no declaration, there was an error parsing it.
18566- if (!D || D->isInvalidDecl())
18567- return;
18556+ assert(D && !D->isInvalidDecl());
1856818557
1856918558 // We will always have a nested name specifier here, but this declaration
1857018559 // might not be out of line if the specifier names the current namespace:
@@ -18573,25 +18562,35 @@ void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
1857318562 if (S && D->isOutOfLine())
1857418563 EnterDeclaratorContext(S, D->getDeclContext());
1857518564
18576- // If we are parsing the initializer for a static data member, push a
18577- // new expression evaluation context that is associated with this static
18578- // data member.
18579- if (isNonlocalVariable(D))
18580- PushExpressionEvaluationContext(
18581- ExpressionEvaluationContext::PotentiallyEvaluated, D);
18565+ PushExpressionEvaluationContext(
18566+ ExpressionEvaluationContext::PotentiallyEvaluated, D);
1858218567}
1858318568
1858418569/// Invoked after we are finished parsing an initializer for the declaration D.
1858518570void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) {
18586- // If there is no declaration, there was an error parsing it.
18587- if (!D || D->isInvalidDecl())
18588- return;
18589-
18590- if (isNonlocalVariable(D))
18591- PopExpressionEvaluationContext();
18571+ assert(D);
1859218572
1859318573 if (S && D->isOutOfLine())
1859418574 ExitDeclaratorContext(S);
18575+
18576+ if (getLangOpts().CPlusPlus23) {
18577+ // An expression or conversion is 'manifestly constant-evaluated' if it is:
18578+ // [...]
18579+ // - the initializer of a variable that is usable in constant expressions or
18580+ // has constant initialization.
18581+ if (auto *VD = dyn_cast<VarDecl>(D);
18582+ VD && (VD->isUsableInConstantExpressions(Context) ||
18583+ VD->hasConstantInitialization())) {
18584+ // An expression or conversion is in an 'immediate function context' if it
18585+ // is potentially evaluated and either:
18586+ // [...]
18587+ // - it is a subexpression of a manifestly constant-evaluated expression or
18588+ // conversion.
18589+ ExprEvalContexts.back().InImmediateFunctionContext = true;
18590+ }
18591+ }
18592+
18593+ PopExpressionEvaluationContext();
1859518594}
1859618595
1859718596/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
0 commit comments