[all-commits] [llvm/llvm-project] 2e4df2: [Clang][CWG1815] Initialize aggregate default memb...
Yuxuan Chen via All-commits
all-commits at lists.llvm.org
Sat May 30 14:24:20 PDT 2026
Branch: refs/heads/users/yuxuanchen1997/cwg1815-aggregate-dmi-lifetime
Home: https://github.com/llvm/llvm-project
Commit: 2e4df2a1b895e9749fc98b48bd345529f4f8d53d
https://github.com/llvm/llvm-project/commit/2e4df2a1b895e9749fc98b48bd345529f4f8d53d
Author: Yuxuan Chen <ych at meta.com>
Date: 2026-05-29 (Fri, 29 May 2026)
Changed paths:
M clang/include/clang/Sema/Sema.h
M clang/lib/Sema/SemaDeclCXX.cpp
M clang/lib/Sema/SemaExpr.cpp
M clang/lib/Sema/SemaInit.cpp
M clang/test/AST/ast-dump-default-init-json.cpp
M clang/test/AST/ast-dump-default-init.cpp
A clang/test/CodeGenCXX/gh196469-default-member-init-lambda-cleanup.cpp
A clang/test/SemaCXX/cwg1815-aggregate-dmi-lifetime.cpp
Log Message:
-----------
[Clang][CWG1815] Initialize aggregate default member initializers against the enclosing object
Fixes https://github.com/llvm/llvm-project/issues/196469
A default member initializer is used two ways with different full-expression
and lifetime rules: in a constructor each member initializer is its own
full-expression and its temporaries are anchored to the object being
constructed; in aggregate initialization the initializer is part of the
enclosing full-expression and its temporaries are anchored to the enclosing
object (a variable, or an enclosing temporary).
BuildCXXDefaultInitExpr handled both the same way: it re-ran the initializer
through a TreeTransform and then finished a separate full-expression with a
parentless InitializeMemberFromDefaultMemberInitializer entity. That produced
two defects in aggregate initialization:
- The ExprWithCleanups was nested inside the CXXDefaultInitExpr instead of
covering the enclosing full-expression, and the TreeTransform dropped the
CXXBindTemporaryExpr of an ordinary temporary (e.g. a closure with an
init-capture), so its destructor was never run (#196469).
- getEntityLifetime saw a parentless default-member entity and lifetime-
extended the temporary to the Field. For a temporary aggregate the correct
lifetime is the full-expression, but checkInitializerLifetime is a no-op
for LK_FullExpression and never demoted it. The constant evaluator then
failed to destroy the temporary (the CWG1815 "variations" in #85601).
Fork the two cases. Thread the enclosing parented member entity from the
aggregate initializer through BuildCXXDefaultInitExpr into
ConvertMemberDefaultInitExpression, so lifetime is computed against the
enclosing object by construction (extended to a variable, or full-expression
duration for a temporary aggregate). In that case, do not finish a separate
full-expression; the cleanup state merges into the enclosing context so its
ExprWithCleanups covers the temporaries. Preserve the CXXBindTemporaryExpr
that the rebuild transform strips so ordinary temporaries are still destroyed.
The constructor path is unchanged (parentless entity, Field anchoring).
Update the default-member-initializer AST dump tests for the corrected
ExprWithCleanups placement and add CodeGenCXX and constexpr regression tests.
Assisted By: OpenAI Codex
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list