diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b7a6ace8bb895..21f8d47cb3609 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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 ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 08615d4393f5d..34bb200e43360 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -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; diff --git a/clang/test/SemaCXX/GH95854.cpp b/clang/test/SemaCXX/GH95854.cpp new file mode 100644 index 0000000000000..aa470c6ac8e5b --- /dev/null +++ b/clang/test/SemaCXX/GH95854.cpp @@ -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;