llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Aaron Ballman (AaronBallman)

<details>
<summary>Changes</summary>

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++.

---
Full diff: https://github.com/llvm/llvm-project/pull/140725.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaInit.cpp (+4-2) 
- (modified) clang/test/Sema/warn-default-const-init.c (+12) 


``````````diff
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}} \

``````````

</details>


https://github.com/llvm/llvm-project/pull/140725
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to