https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/96301
>From 7e0b2c0a08c63a01309991980d30c64bcea325fe Mon Sep 17 00:00:00 2001 From: Rajveer <rajveer.develo...@icloud.com> Date: Fri, 21 Jun 2024 18:26:36 +0530 Subject: [PATCH] [clang] Allow class with anonymous union member to be const-default-constructible even if a union member has a default member initializer (#95854) Resolves #95854 Clang incorrectly considers a class with an anonymous union member to not be const-default-constructible even if a union member has a default member initializer. ``` struct A { union { int n = 0; int m; }; }; const A a; ``` -- As per https://eel.is/c++draft/dcl.init#general-8.3 --- clang/docs/ReleaseNotes.rst | 5 ++++- clang/include/clang/AST/DeclCXX.h | 2 +- clang/lib/AST/DeclCXX.cpp | 9 ++++++++- clang/test/SemaCXX/GH95854.cpp | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCXX/GH95854.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 39e1b0fcb09bbd..d95577b0649059 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -217,8 +217,11 @@ Bug Fixes to C++ Support - Clang now preserves the unexpanded flag in a lambda transform used for pack expansion. (#GH56852), (#GH85667), (#GH99877). - Fixed a bug when diagnosing ambiguous explicit specializations of constrained member functions. -- Fixed an assertion failure when selecting a function from an overload set that includes a +- Fixed an assertion failure when selecting a function from an overload set that includes a specialization of a conversion function template. +- Clang incorrectly considers 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/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 0d72cc6a08dcb4..7157caa8e2ab2d 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1162,7 +1162,7 @@ class CXXRecordDecl : public RecordDecl { /// value-initialization of an entity of reference type is ill-formed. bool hasUninitializedReferenceMember() const { return !isUnion() && !hasUserDeclaredConstructor() && - data().HasUninitializedReferenceMember; + data().HasUninitializedReferenceMember || needsImplicitDefaultConstructor(); } /// Whether this class is a POD-type (C++ [class]p4) diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 9a3ede426e9143..e8597adcf6fd4a 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1057,6 +1057,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 @@ -1125,7 +1128,11 @@ 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 00000000000000..68fcf1397dd901 --- /dev/null +++ b/clang/test/SemaCXX/GH95854.cpp @@ -0,0 +1,19 @@ +// 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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits