Skip to content

Commit 9b4faa1

Browse files
committed
[clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization
Before this patch, initialized class members would have the LifetimeKind LK_MemInitializer, which does not allow for binding a temporary to a reference. Binding to a temporary however is allowed in parenthesized aggregate initialization, even if it leads to a dangling reference. To fix this, we create a new EntityKind, EK_ParenAggInitMember, which has LifetimeKind LK_FullExpression. This patch does *not* attempt to diagnose dangling references as a result of using this feature. This patch also refactors TryOrBuildParenListInitialization(...) to accomodate creating different InitializedEntity objects. Fixes llvm#61567 [0]: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0960r3.html Reviewed By: shafik Differential Revision: https://reviews.llvm.org/D148274
1 parent 266d65c commit 9b4faa1

File tree

7 files changed

+347
-146
lines changed

7 files changed

+347
-146
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,15 @@ Bug Fixes to C++ Support
373373
- Fix bug in the computation of the ``__has_unique_object_representations``
374374
builtin for types with unnamed bitfields.
375375
(`#61336 <https://github.com/llvm/llvm-project/issues/61336>`_)
376+
<<<<<<< HEAD
376377
- Fix default member initializers sometimes being ignored when performing
377378
parenthesized aggregate initialization of templated types.
378379
(`#62266 <https://github.com/llvm/llvm-project/issues/62266>`_)
380+
=======
381+
- Fix overly aggressive lifetime checks for parenthesized aggregate
382+
initialization.
383+
(`#61567 <https://github.com/llvm/llvm-project/issues/61567>`_)
384+
>>>>>>> c7422b289522 ([clang] Fix overly aggressive lifetime checks for parenthesized aggregate initialization)
379385

380386
Bug Fixes to AST Handling
381387
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2126,7 +2126,8 @@ def err_init_conversion_failed : Error<
21262126
"exception object|a member subobject|an array element|a new value|a value|a "
21272127
"base class|a constructor delegation|a vector element|a block element|a "
21282128
"block element|a complex element|a lambda capture|a compound literal "
2129-
"initializer|a related result|a parameter of CF audited function}0 "
2129+
"initializer|a related result|a parameter of CF audited function|a "
2130+
"structured binding|a member subobject}0 "
21302131
"%diff{of type $ with an %select{rvalue|lvalue}2 of type $|"
21312132
"with an %select{rvalue|lvalue}2 of incompatible type}1,3"
21322133
"%select{|: different classes%diff{ ($ vs $)|}5,6"

clang/include/clang/Sema/Initialization.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ class alignas(8) InitializedEntity {
123123
/// decomposition declaration.
124124
EK_Binding,
125125

126+
/// The entity being initialized is a non-static data member subobject of an
127+
/// object initialized via parenthesized aggregate initialization.
128+
EK_ParenAggInitMember,
129+
126130
// Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this
127131
// enum as an index for its first %select. When modifying this list,
128132
// that diagnostic text needs to be updated as well.
@@ -227,8 +231,10 @@ class alignas(8) InitializedEntity {
227231

228232
/// Create the initialization entity for a member subobject.
229233
InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
230-
bool Implicit, bool DefaultMemberInit)
231-
: Kind(EK_Member), Parent(Parent), Type(Member->getType()),
234+
bool Implicit, bool DefaultMemberInit,
235+
bool IsParenAggInit = false)
236+
: Kind(IsParenAggInit ? EK_ParenAggInitMember : EK_Member),
237+
Parent(Parent), Type(Member->getType()),
232238
Variable{Member, Implicit, DefaultMemberInit} {}
233239

234240
/// Create the initialization entity for an array element.
@@ -388,6 +394,14 @@ class alignas(8) InitializedEntity {
388394
return InitializedEntity(Member->getAnonField(), Parent, Implicit, false);
389395
}
390396

397+
/// Create the initialization entity for a member subobject initialized via
398+
/// parenthesized aggregate init.
399+
static InitializedEntity InitializeMemberFromParenAggInit(FieldDecl *Member) {
400+
return InitializedEntity(Member, /*Parent=*/nullptr, /*Implicit=*/false,
401+
/*DefaultMemberInit=*/false,
402+
/*IsParenAggInit=*/true);
403+
}
404+
391405
/// Create the initialization entity for a default member initializer.
392406
static InitializedEntity
393407
InitializeMemberFromDefaultMemberInitializer(FieldDecl *Member) {

clang/lib/Sema/SemaAccess.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1651,7 +1651,8 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
16511651
<< Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
16521652
break;
16531653

1654-
case InitializedEntity::EK_Member: {
1654+
case InitializedEntity::EK_Member:
1655+
case InitializedEntity::EK_ParenAggInitMember: {
16551656
const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
16561657
PD = PDiag(diag::err_access_field_ctor);
16571658
PD << Field->getType() << getSpecialMember(Constructor);

0 commit comments

Comments
 (0)