[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
Mon Apr 29 06:11:46 PDT 2024


================
@@ -18562,9 +18553,7 @@ static bool isNonlocalVariable(const Decl *D) {
 /// class X. If the declaration had a scope specifier, a scope will have
 /// been created and passed in for this purpose. Otherwise, S will be null.
 void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
-  // If there is no declaration, there was an error parsing it.
-  if (!D || D->isInvalidDecl())
-    return;
----------------
katzdm wrote:

Ah, I see how it could look that way; it's not in fact unrelated.

Prior this PR, `InitializerScopeRAII::pop()` was called _before_ attaching the initializer to the `VarDecl`. This gave an invariant that if the `VarDecl` was valid when the scope was entered, it would continue to be valid when it was exited.

With this PR, the `VarDecl` can invalidated when the initializer is attached; `D->isInvalidDecl()` might be false when calling `ActOnCXXEnterDeclInitializer`, but might be true when calling `ActOnCXXExitDeclInitializer`. We therefore can't just no-op in `ActOnCXXExitDeclInitializer` when the variable is invalid, or else we'll never pop the expression evaluation context (leading to assert-failures from scope entity mismatch, etc).

This is what motivates adding an `Entered` field to `InitializerScopeRAII` (`false` if `!D` or `D->isInvalidDecl` at scope-entry time) to remember whether `ActOnCXXExitDeclInitializer` needs to be called at scope-exit time. So this check is still present, but it's been lifted from this callsite to `InitializerScopeRAII`; I figured it couldn't hurt to leave some assertions to ensure the expected preconditions continue to be met going forward.

Let me know if that seems reasonable, or if there's another way you'd rather see this done.

https://github.com/llvm/llvm-project/pull/89565


More information about the cfe-commits mailing list