Skip to content

Commit 1a25f02

Browse files
committed
[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. This is valid as per ``8.3`` in `Draft C++ Standard <https://eel.is/c++draft/dcl.init#general-8.3>`_. The ``allowConstDefaultInit`` member function in ``CXXRecordDecl`` needs special-case unions to handle the rule. (#GH95854). ``` struct A { union { int n = 0; int m; }; }; const A a; ``` -- As per https://eel.is/c++draft/dcl.init#general-8.3
1 parent 5c717d6 commit 1a25f02

File tree

4 files changed

+119
-2
lines changed

4 files changed

+119
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,94 @@ Bug Fixes in This Version
192192
- Fixed a crash when diagnosing format strings and encountering an empty
193193
delimited escape sequence (e.g., ``"\o{}"``). #GH102218
194194

195+
- Fixed missing warnings when comparing mismatched enumeration constants
196+
in C (#GH29217)
197+
198+
- Clang now accepts elaborated-type-specifiers that explicitly specialize
199+
a member class template for an implicit instantiation of a class template.
200+
201+
- Fixed missing warnings when doing bool-like conversions in C23 (#GH79435).
202+
- Clang's ``-Wshadow`` no longer warns when an init-capture is named the same as
203+
a class field unless the lambda can capture this.
204+
Fixes (#GH71976)
205+
206+
- Clang now accepts qualified partial/explicit specializations of variable templates that
207+
are not nominable in the lookup context of the specialization.
208+
209+
- Clang now doesn't produce false-positive warning `-Wconstant-logical-operand`
210+
for logical operators in C23.
211+
Fixes (#GH64356).
212+
213+
- ``__is_trivially_relocatable`` no longer returns ``false`` for volatile-qualified types.
214+
Fixes (#GH77091).
215+
216+
- Clang no longer produces a false-positive `-Wunused-variable` warning
217+
for variables created through copy initialization having side-effects in C++17 and later.
218+
Fixes (#GH64356) (#GH79518).
219+
220+
- Fix value of predefined macro ``__FUNCTION__`` in MSVC compatibility mode.
221+
Fixes (#GH66114).
222+
223+
- Clang now emits errors for explicit specializations/instatiations of lambda call
224+
operator.
225+
Fixes (#GH83267).
226+
227+
- Fix crash on ill-formed partial specialization with CRTP.
228+
Fixes (#GH89374).
229+
230+
- Clang now correctly generates overloads for bit-precise integer types for
231+
builtin operators in C++. Fixes #GH82998.
232+
233+
- Fix crash when destructor definition is preceded with an equals sign.
234+
Fixes (#GH89544).
235+
236+
- When performing mixed arithmetic between ``_Complex`` floating-point types and integers,
237+
Clang now correctly promotes the integer to its corresponding real floating-point
238+
type only rather than to the complex type (e.g. ``_Complex float / int`` is now evaluated
239+
as ``_Complex float / float`` rather than ``_Complex float / _Complex float``), as mandated
240+
by the C standard. This significantly improves codegen of `*` and `/` especially.
241+
Fixes #GH31205.
242+
243+
- Fixes an assertion failure on invalid code when trying to define member
244+
functions in lambdas.
245+
246+
- Fixed a regression in CTAD that a friend declaration that befriends itself may cause
247+
incorrect constraint substitution. (#GH86769).
248+
249+
- Fixed an assertion failure on invalid InitListExpr in C89 mode (#GH88008).
250+
251+
- Fixed missing destructor calls when we branch from middle of an expression.
252+
This could happen through a branch in stmt-expr or in an expression containing a coroutine
253+
suspension. Fixes (#GH63818) (#GH88478).
254+
255+
- Clang will no longer diagnose an erroneous non-dependent ``switch`` condition
256+
during instantiation, and instead will only diagnose it once, during checking
257+
of the function template.
258+
259+
- Clang now allows the value of unroll count to be zero in ``#pragma GCC unroll`` and ``#pragma unroll``.
260+
The values of 0 and 1 block any unrolling of the loop. This keeps the same behavior with GCC.
261+
Fixes (`#88624 <https://github.com/llvm/llvm-project/issues/88624>`_).
262+
263+
- Clang will no longer emit a duplicate -Wunused-value warning for an expression
264+
`(A, B)` which evaluates to glvalue `B` that can be converted to non ODR-use. (#GH45783)
265+
266+
- Clang now correctly disallows VLA type compound literals, e.g. ``(int[size]){}``,
267+
as the C standard mandates. (#GH89835)
268+
269+
- ``__is_array`` and ``__is_bounded_array`` no longer return ``true`` for
270+
zero-sized arrays. Fixes (#GH54705).
271+
272+
- Clang incorrectly considers a class with an anonymous union member to not be
273+
const-default-constructible even if a union member has a default member initializer.
274+
This is valid as per ``8.3`` in `Draft C++ Standard <https://eel.is/c++draft/dcl.init#general-8.3>`_.
275+
The ``allowConstDefaultInit`` member function in ``CXXRecordDecl`` needs
276+
special-case unions to handle the rule. (#GH95854).
277+
278+
- Correctly reject declarations where a statement is required in C.
279+
Fixes #GH92775
280+
281+
- Fixed `static_cast` to array of unknown bound. Fixes (#GH62863).
282+
195283
Bug Fixes to Compiler Builtins
196284
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
197285

clang/include/clang/AST/DeclCXX.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1395,7 +1395,8 @@ class CXXRecordDecl : public RecordDecl {
13951395
bool allowConstDefaultInit() const {
13961396
return !data().HasUninitializedFields ||
13971397
!(data().HasDefaultedDefaultConstructor ||
1398-
needsImplicitDefaultConstructor());
1398+
needsImplicitDefaultConstructor()) ||
1399+
(isUnion() && isEmpty());
13991400
}
14001401

14011402
/// Determine whether this class has a destructor which has no

clang/lib/AST/DeclCXX.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,9 @@ void CXXRecordDecl::addedMember(Decl *D) {
10571057
if (isUnion() && !Field->isAnonymousStructOrUnion())
10581058
data().HasVariantMembers = true;
10591059

1060+
if (isUnion() && IsFirstField)
1061+
data().HasUninitializedFields = true;
1062+
10601063
// C++0x [class]p9:
10611064
// A POD struct is a class that is both a trivial class and a
10621065
// standard-layout class, and has no non-static data members of type
@@ -1125,7 +1128,11 @@ void CXXRecordDecl::addedMember(Decl *D) {
11251128
data().DefaultedCopyConstructorIsDeleted = true;
11261129
}
11271130

1128-
if (!Field->hasInClassInitializer() && !Field->isMutable()) {
1131+
if (isUnion() && !Field->isMutable()) {
1132+
if (Field->hasInClassInitializer()) {
1133+
data().HasUninitializedFields = false;
1134+
}
1135+
} else if (!Field->hasInClassInitializer() && !Field->isMutable()) {
11291136
if (CXXRecordDecl *FieldType = T->getAsCXXRecordDecl()) {
11301137
if (FieldType->hasDefinition() && !FieldType->allowConstDefaultInit())
11311138
data().HasUninitializedFields = true;

clang/test/SemaCXX/GH95854.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
2+
//
3+
// -expected-no-diagnostics
4+
5+
struct A {
6+
union {
7+
int n = 0;
8+
int m;
9+
};
10+
};
11+
const A a;
12+
13+
struct B {
14+
union {
15+
struct {
16+
int n = 5;
17+
int m;
18+
};
19+
};
20+
};
21+
const B b; // expected-error {{default initialization of an object of const type 'const B' without a user-provided default constructor}}

0 commit comments

Comments
 (0)