[clang] [clang][CodeGen] Zero init unspecified fields in initializers in C (PR #97121)

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 2 18:19:58 PDT 2024


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff 12189f800585ab459afa20b4f159db93ae474b57 e1d75774c554a5125428b3f3a6304a921c81c5f0 --extensions h,cpp,c -- clang/test/CodeGen/linux-kernel-struct-union-initializer.c clang/test/CodeGen/linux-kernel-struct-union-initializer2.c clang/lib/CodeGen/CGDecl.cpp clang/lib/CodeGen/CGExprAgg.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h clang/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c clang/test/CodeGen/2008-08-07-AlignPadding1.c clang/test/CodeGen/2009-06-14-anonymous-union-init.c clang/test/CodeGen/64bit-swiftcall.c clang/test/CodeGen/arm-swiftcall.c clang/test/CodeGen/const-init.c clang/test/CodeGen/decl.c clang/test/CodeGen/designated-initializers.c clang/test/CodeGen/ext-int.c clang/test/CodeGen/flexible-array-init.c clang/test/CodeGen/global-init.c clang/test/CodeGen/init.c clang/test/CodeGen/mingw-long-double.c clang/test/CodeGen/mms-bitfields.c clang/test/CodeGen/union-init2.c clang/test/CodeGen/windows-swiftcall.c
``````````

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 47620ebaf3..c29b7f2372 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -371,44 +371,53 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
   if (!getLangOpts().CPlusPlus) {
     // In C23 (N3096) $6.7.10:
     // """
-    // If any object is initialized with an empty iniitializer, then it is subject to default
-    // initialization:
-    //  - if it is an aggregate, every member is initialized (recursively) according to these rules,
+    // If any object is initialized with an empty iniitializer, then it is
+    // subject to default initialization:
+    //  - if it is an aggregate, every member is initialized (recursively)
+    //  according to these rules,
     //    and any padding is initialized to zero bits;
-    //  - if it is a union, the first named member is initialized (recursively) according to these
+    //  - if it is a union, the first named member is initialized (recursively)
+    //  according to these
     //    rules, and any padding is initialized to zero bits.
     //
-    // If the aggregate or union contains elements or members that are aggregates or unions, these
-    // rules apply recursively to the subaggregates or contained unions.
+    // If the aggregate or union contains elements or members that are
+    // aggregates or unions, these rules apply recursively to the subaggregates
+    // or contained unions.
     //
-    // If there are fewer initializers in a brace-enclosed list than there are elements or members
-    // of an aggregate, or fewer characters in a string literal used to initialize an array of
-    // known size than there are elements in the array, the remainder of the aggregate is subject
-    // to default initialization.
+    // If there are fewer initializers in a brace-enclosed list than there are
+    // elements or members of an aggregate, or fewer characters in a string
+    // literal used to initialize an array of known size than there are elements
+    // in the array, the remainder of the aggregate is subject to default
+    // initialization.
     // """
     //
-    // From my understanding, the standard is ambiguous in the following two areas:
-    // 1. For a union type with empty initializer, if the first named member is not the largest
-    // member, then the bytes comes after the first named member but before padding are left
-    // unspecified. An example is:
+    // From my understanding, the standard is ambiguous in the following two
+    // areas:
+    // 1. For a union type with empty initializer, if the first named member is
+    // not the largest member, then the bytes comes after the first named member
+    // but before padding are left unspecified. An example is:
     //    union U { int a; long long b;};
-    //    union U u = {};  // The first 4 bytes are 0, but 4-8 bytes are left unspecified.
+    //    union U u = {};  // The first 4 bytes are 0, but 4-8 bytes are left
+    //    unspecified.
     //
-    // 2. It only mentions padding for empty initializer, but doesn't mention padding for a
-    // non empty initialization list. And if the aggregation or union contains elements or members
-    // that are aggregates or unions, and some are non empty initializers, while others are empty
-    // initiailizers, the padding initialization is unclear. An example is:
+    // 2. It only mentions padding for empty initializer, but doesn't mention
+    // padding for a non empty initialization list. And if the aggregation or
+    // union contains elements or members that are aggregates or unions, and
+    // some are non empty initializers, while others are empty initiailizers,
+    // the padding initialization is unclear. An example is:
     //    struct S1 { int a; long long b; };
     //    struct S2 { char c; struct S1 s1; };
-    //    // The values for paddings between s2.c and s2.s1.a, between s2.s1.a and s2.s1.b are
+    //    // The values for paddings between s2.c and s2.s1.a, between s2.s1.a
+    //    and s2.s1.b are
     //    // unclear.
     //    struct S2 s2 = { 'c' };
     //
-    // Here we choose to zero initiailize left bytes of a union type. Because projects like the
-    // Linux kernel are relying on this behavior. If we don't explicitly zero initialize them, the
-    // undef values can be optimized to return gabage data.
-    // We also choose to zero initialize paddings for aggregates and unions, no matter they are
-    // initialized by empty initializers or non empty initializers. This can provide a consistent
+    // Here we choose to zero initiailize left bytes of a union type. Because
+    // projects like the Linux kernel are relying on this behavior. If we don't
+    // explicitly zero initialize them, the undef values can be optimized to
+    // return gabage data. We also choose to zero initialize paddings for
+    // aggregates and unions, no matter they are initialized by empty
+    // initializers or non empty initializers. This can provide a consistent
     // behavior. So projects like the Linux kernel can rely on it.
     Init = constWithPadding(CGM, IsPattern::No,
                             replaceUndef(CGM, IsPattern::No, Init));
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index f2e15f3af8..73a1ec062d 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -1752,14 +1752,19 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
       EmitNullInitializationToLValue(FieldLoc);
     }
     if (ZeroInitPadding) {
-      CharUnits TotalSize = Dest.getPreferredSize(CGF.getContext(), DestLV.getType());
-      CharUnits FieldSize = CGF.getContext().getTypeSizeInChars(FieldLoc.getType());
+      CharUnits TotalSize =
+          Dest.getPreferredSize(CGF.getContext(), DestLV.getType());
+      CharUnits FieldSize =
+          CGF.getContext().getTypeSizeInChars(FieldLoc.getType());
       if (FieldSize < TotalSize) {
         CharUnits LeftSize = TotalSize - FieldSize;
-        llvm::Constant *LeftSizeVal = CGF.Builder.getInt64(LeftSize.getQuantity());
+        llvm::Constant *LeftSizeVal =
+            CGF.Builder.getInt64(LeftSize.getQuantity());
         Address BaseLoc = Dest.getAddress().withElementType(CGF.Int8Ty);
-        Address LeftLoc = CGF.Builder.CreateConstGEP(BaseLoc, LeftSize.getQuantity());
-        CGF.Builder.CreateMemSet(LeftLoc, CGF.Builder.getInt8(0), LeftSizeVal, false);
+        Address LeftLoc =
+            CGF.Builder.CreateConstGEP(BaseLoc, LeftSize.getQuantity());
+        CGF.Builder.CreateMemSet(LeftLoc, CGF.Builder.getInt8(0), LeftSizeVal,
+                                 false);
       }
     }
 
@@ -1774,13 +1779,17 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
   for (const auto *field : record->fields()) {
     if (ZeroInitPadding) {
       unsigned FieldIndex = field->getFieldIndex();
-      uint64_t CurOff = Layout.getFieldOffset(FieldIndex) / CGF.getContext().getCharWidth();
+      uint64_t CurOff =
+          Layout.getFieldOffset(FieldIndex) / CGF.getContext().getCharWidth();
       if (SizeSoFar < CurOff) {
-        llvm::Constant* PaddingSizeVal = CGF.Builder.getInt64(CurOff - SizeSoFar);
+        llvm::Constant *PaddingSizeVal =
+            CGF.Builder.getInt64(CurOff - SizeSoFar);
         Address PaddingLoc = CGF.Builder.CreateConstGEP(BaseLoc, SizeSoFar);
-        CGF.Builder.CreateMemSet(PaddingLoc, CGF.Builder.getInt8(0), PaddingSizeVal, false);
+        CGF.Builder.CreateMemSet(PaddingLoc, CGF.Builder.getInt8(0),
+                                 PaddingSizeVal, false);
       }
-      CharUnits FieldSize = CGF.getContext().getTypeSizeInChars(field->getType());
+      CharUnits FieldSize =
+          CGF.getContext().getTypeSizeInChars(field->getType());
       SizeSoFar = CurOff + FieldSize.getQuantity();
     }
     // We're done once we hit the flexible array member.
@@ -1825,11 +1834,14 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
     }
   }
   if (ZeroInitPadding) {
-    uint64_t TotalSize = Dest.getPreferredSize(CGF.getContext(), DestLV.getType()).getQuantity();
+    uint64_t TotalSize =
+        Dest.getPreferredSize(CGF.getContext(), DestLV.getType()).getQuantity();
     if (SizeSoFar < TotalSize) {
-      llvm::Constant* PaddingSizeVal = CGF.Builder.getInt64(TotalSize - SizeSoFar);
+      llvm::Constant *PaddingSizeVal =
+          CGF.Builder.getInt64(TotalSize - SizeSoFar);
       Address PaddingLoc = CGF.Builder.CreateConstGEP(BaseLoc, SizeSoFar);
-      CGF.Builder.CreateMemSet(PaddingLoc, CGF.Builder.getInt8(0), PaddingSizeVal, false);
+      CGF.Builder.CreateMemSet(PaddingLoc, CGF.Builder.getInt8(0),
+                               PaddingSizeVal, false);
     }
   }
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/97121


More information about the cfe-commits mailing list