[clang] 6fb23af - [C] Do not diagnose unions with -Wdefault-const-init (#140725)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 20 10:04:27 PDT 2025
Author: Aaron Ballman
Date: 2025-05-20T13:04:24-04:00
New Revision: 6fb23afb8dfa1c9244aa1f30df947ad201a1c934
URL: https://github.com/llvm/llvm-project/commit/6fb23afb8dfa1c9244aa1f30df947ad201a1c934
DIFF: https://github.com/llvm/llvm-project/commit/6fb23afb8dfa1c9244aa1f30df947ad201a1c934.diff
LOG: [C] Do not diagnose unions with -Wdefault-const-init (#140725)
A default-initialized union with a const member is generally reasonable
in C and isn't necessarily incompatible with C++, so we now silence the
diagnostic in that case. However, we do still diagnose a const-
qualified, default-initialized union as that is incompatible with C++.
Added:
Modified:
clang/lib/Sema/SemaInit.cpp
clang/test/Sema/warn-default-const-init.c
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 9ee8603ff7811..810cac889b98f 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -6602,8 +6602,10 @@ void InitializationSequence::InitializeFrom(Sema &S,
}
// If the record has any members which are const (recursively checked),
// then we want to diagnose those as being uninitialized if there is no
- // initializer present.
- if (!Initializer) {
+ // initializer present. However, we only do this for structure types, not
+ // union types, because an unitialized field in a union is generally
+ // reasonable, especially in C where unions can be used for type punning.
+ if (!Initializer && !Rec->isUnion()) {
if (const FieldDecl *FD = getConstField(Rec)) {
unsigned DiagID = diag::warn_default_init_const_field_unsafe;
if (Var->getStorageDuration() == SD_Static ||
diff --git a/clang/test/Sema/warn-default-const-init.c b/clang/test/Sema/warn-default-const-init.c
index e788d72899685..76b85abb6ade2 100644
--- a/clang/test/Sema/warn-default-const-init.c
+++ b/clang/test/Sema/warn-default-const-init.c
@@ -35,6 +35,8 @@ struct V { int i; const struct A a; }; // unsafe-field-note {{member 'a' declare
struct W { struct A a; const int j; }; // unsafe-field-note {{member 'j' declared 'const' here}} \
unsafe-field-compat-note {{member 'j' declared 'const' here}} \
cxx-note {{default constructor of 'W' is implicitly deleted because field 'j' of const-qualified type 'const int' would not be initialized}}
+union Z1 { int i; const int j; };
+union Z2 { int i; const struct A a; };
void f() {
struct S s1; // unsafe-field-warning {{default initialization of an object of type 'struct S' with const member leaves the object uninitialized}} \
@@ -66,6 +68,14 @@ void y() {
struct W w2 = { 0 };
struct W w3 = { { 0 }, 0 };
}
+void z() {
+ // Note, we explicitly do not diagnose default initialization of unions with
+ // a const member. Those can be reasonable, the only problematic case is if
+ // the only member of the union is const, but that's a very odd situation to
+ // begin with so we accept it as a false negative.
+ union Z1 z1;
+ union Z2 z2;
+}
// Test a tentative definition which does eventually get an initializer.
extern const int i;
@@ -77,6 +87,8 @@ const int k; // zero-init-var-warning {{default initialization of an obje
cxx-error {{default initialization of an object of const type 'const int'}}
const struct S s; // zero-init-var-warning {{default initialization of an object of type 'const struct S' is incompatible with C++}} \
cxx-error {{call to implicitly-deleted default constructor of 'const struct S'}}
+const union Z1 z3; // zero-init-var-warning {{default initialization of an object of type 'const union Z1' is incompatible with C++}} \
+ cxx-error {{default initialization of an object of const type 'const union Z1' without a user-provided default constructor}}
void func() {
const int a; // unsafe-var-warning {{default initialization of an object of type 'const int' leaves the object uninitialized}} \
More information about the cfe-commits
mailing list