https://github.com/AaronBallman created https://github.com/llvm/llvm-project/pull/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++. >From ccb8cd6ab2949dd3b92923c01180cb24915b9fde Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Tue, 20 May 2025 08:59:38 -0400 Subject: [PATCH] [C] Do not diagnose unions with -Wdefault-const-init 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++. --- clang/lib/Sema/SemaInit.cpp | 6 ++++-- clang/test/Sema/warn-default-const-init.c | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) 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}} \ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits