mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 18:56:43 +00:00
[clang] Allow class with anonymous union member to be const-default-constructible even if a union member has a default member initializer (#95854) (#96301)
Resolves #95854 -- As per https://eel.is/c++draft/dcl.init#general-8.3
This commit is contained in:
parent
4614b80c49
commit
73057349a2
@ -539,6 +539,9 @@ Bug Fixes to C++ Support
|
||||
- Fix erroneous templated array size calculation leading to crashes in generated code. (#GH41441)
|
||||
- During the lookup for a base class name, non-type names are ignored. (#GH16855)
|
||||
- Fix a crash when recovering an invalid expression involving an explicit object member conversion operator. (#GH112559)
|
||||
- Clang incorrectly considered a class with an anonymous union member to not be
|
||||
const-default-constructible even if a union member has a default member initializer.
|
||||
(#GH95854).
|
||||
|
||||
Bug Fixes to AST Handling
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1060,6 +1060,9 @@ void CXXRecordDecl::addedMember(Decl *D) {
|
||||
if (isUnion() && !Field->isAnonymousStructOrUnion())
|
||||
data().HasVariantMembers = true;
|
||||
|
||||
if (isUnion() && IsFirstField)
|
||||
data().HasUninitializedFields = true;
|
||||
|
||||
// C++0x [class]p9:
|
||||
// A POD struct is a class that is both a trivial class and a
|
||||
// standard-layout class, and has no non-static data members of type
|
||||
@ -1128,7 +1131,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
|
||||
data().DefaultedCopyConstructorIsDeleted = true;
|
||||
}
|
||||
|
||||
if (!Field->hasInClassInitializer() && !Field->isMutable()) {
|
||||
if (isUnion() && !Field->isMutable()) {
|
||||
if (Field->hasInClassInitializer())
|
||||
data().HasUninitializedFields = false;
|
||||
} else if (!Field->hasInClassInitializer() && !Field->isMutable()) {
|
||||
if (CXXRecordDecl *FieldType = T->getAsCXXRecordDecl()) {
|
||||
if (FieldType->hasDefinition() && !FieldType->allowConstDefaultInit())
|
||||
data().HasUninitializedFields = true;
|
||||
|
51
clang/test/SemaCXX/GH95854.cpp
Normal file
51
clang/test/SemaCXX/GH95854.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
|
||||
|
||||
struct A {
|
||||
union {
|
||||
int n = 0;
|
||||
int m;
|
||||
};
|
||||
};
|
||||
const A a;
|
||||
|
||||
struct B {
|
||||
union {
|
||||
struct {
|
||||
int n = 5;
|
||||
int m;
|
||||
};
|
||||
};
|
||||
};
|
||||
const B b; // expected-error {{default initialization of an object of const type 'const B' without a user-provided default constructor}}
|
||||
|
||||
struct S {
|
||||
int i;
|
||||
int j;
|
||||
};
|
||||
|
||||
struct T {
|
||||
T() = default;
|
||||
};
|
||||
|
||||
struct C {
|
||||
union {
|
||||
S s;
|
||||
};
|
||||
};
|
||||
|
||||
struct D {
|
||||
union {
|
||||
T s;
|
||||
};
|
||||
};
|
||||
|
||||
const C c; // expected-error {{default initialization of an object of const type 'const C' without a user-provided default constructor}}
|
||||
const D d; // expected-error {{default initialization of an object of const type 'const D' without a user-provided default constructor}}
|
||||
|
||||
struct E {
|
||||
union {
|
||||
int n;
|
||||
int m=0;
|
||||
};
|
||||
};
|
||||
const E e;
|
Loading…
x
Reference in New Issue
Block a user