llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Michael Buch (Michael137)

<details>
<summary>Changes</summary>

This is a follow-up from the conversation starting at 
https://github.com/llvm/llvm-project/pull/93809#issuecomment-2173729801

The root problem that motivated the change are external AST sources that 
compute `ASTRecordLayout`s themselves instead of letting Clang compute them 
from the AST. One such example is LLDB using DWARF to get the definitive 
offsets and sizes of C++ structures. Such layouts should be considered correct 
(modulo buggy DWARF), but various assertions and lowering logic around the 
`CGRecordLayoutBuilder` relies on the AST having `[[no_unique_address]]` 
attached to them. This is a layout-altering attribute which is not encoded in 
DWARF. This causes us LLDB to trip over the various LLVM&lt;-&gt;Clang layout 
consistency checks. There has been precedent for avoiding such layout-altering 
attributes from affecting lowering with externally-provided layouts (e.g., 
packed structs).

This patch proposes to replace the `isZeroSize` checks in 
`CGRecordLayoutBuilder` (which roughly means "empty field with 
[[no_unique_address]]") with checks for 
`CodeGen::isEmptyField`/`CodeGen::isEmptyRecord`.

**Details**
The main strategy here was to change the `isZeroSize` check in 
`CGRecordLowering::accumulateFields` and `CGRecordLowering::accumulateBases` to 
use the `isEmptyXXX` APIs instead, preventing empty fields from being added to 
the `Members` and `Bases` structures. The rest of the changes fall out from 
here, to prevent lookups into these structures (for field numbers or base 
indices) from failing.

Added `isEmptyRecordForLayout` and `isEmptyFieldForLayout` (open to better 
naming suggestions), which mostly just dispatch to the 
`isEmptyRecord`/`isEmptyField` respectively. The main difference is that 
`isEmptyFieldForLayout` doesn't treat `unnamed bitfields` as unconditionally 
empty (unlike `isEmptyField`).

---

Patch is 46.65 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/96422.diff


26 Files Affected:

- (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+20-3) 
- (modified) clang/lib/CodeGen/ABIInfoImpl.h (+12-3) 
- (modified) clang/lib/CodeGen/CGExpr.cpp (+2-1) 
- (modified) clang/lib/CodeGen/CGExprConstant.cpp (+6-3) 
- (modified) clang/lib/CodeGen/CGRecordLayoutBuilder.cpp (+8-7) 
- (modified) clang/test/CodeGen/X86/x86_64-vaarg.c (+2-1) 
- (modified) clang/test/CodeGen/debug-info-packed-struct.c (+1-1) 
- (modified) clang/test/CodeGen/paren-list-agg-init.cpp (+6-9) 
- (modified) clang/test/CodeGen/voidptr-vaarg.c (+2-1) 
- (modified) clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp (+3-3) 
- (modified) clang/test/CodeGenCXX/auto-var-init.cpp (+9-6) 
- (modified) clang/test/CodeGenCXX/bitfield-access-empty.cpp (+8-8) 
- (modified) clang/test/CodeGenCXX/class-layout.cpp (+1-1) 
- (modified) clang/test/CodeGenCXX/compound-literals.cpp (+1-1) 
- (modified) clang/test/CodeGenCXX/exceptions.cpp (+3-4) 
- (modified) clang/test/CodeGenCXX/lambda-deterministic-captures.cpp (+1-3) 
- (modified) clang/test/CodeGenCXX/ms_struct.cpp (+1-3) 
- (modified) clang/test/CodeGenCXX/partial-destruction.cpp (+4-7) 
- (modified) clang/test/CodeGenCXX/pr18962.cpp (+2-3) 
- (modified) clang/test/CodeGenCXX/references.cpp (+1-3) 
- (modified) clang/test/CodeGenCXX/temporaries.cpp (+6-6) 
- (modified) clang/test/CodeGenObjCXX/lambda-to-block.mm (+4-5) 
- (modified) clang/test/OpenMP/irbuilder_for_iterator.cpp (+4-6) 
- (modified) clang/test/OpenMP/irbuilder_for_rangefor.cpp (+6-8) 
- (modified) clang/test/OpenMP/task_member_call_codegen.cpp (+9-13) 
- (modified) clang/test/Sema/ms_class_layout.cpp (+2-12) 


``````````diff
diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp 
b/clang/lib/CodeGen/ABIInfoImpl.cpp
index e9a26abb77837..703e69e889967 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -248,7 +248,7 @@ Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address 
Addr1,
   return Address(PHI, Addr1.getElementType(), Align);
 }
 
-bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
+bool CodeGen::isEmptyField(const ASTContext &Context, const FieldDecl *FD,
                            bool AllowArrays, bool AsIfNoUniqueAddr) {
   if (FD->isUnnamedBitField())
     return true;
@@ -289,8 +289,20 @@ bool CodeGen::isEmptyField(ASTContext &Context, const 
FieldDecl *FD,
   return isEmptyRecord(Context, FT, AllowArrays, AsIfNoUniqueAddr);
 }
 
-bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
-                            bool AsIfNoUniqueAddr) {
+bool CodeGen::isEmptyFieldForLayout(const ASTContext &Context,
+                                    const FieldDecl *FD) {
+  if (FD->isZeroLengthBitField(Context))
+    return true;
+
+  if (FD->isUnnamedBitField())
+    return false;
+
+  return isEmptyField(Context, FD, /*AllowArrays=*/false,
+                      /*AsIfNoUniqueAddr=*/true);
+}
+
+bool CodeGen::isEmptyRecord(const ASTContext &Context, QualType T,
+                            bool AllowArrays, bool AsIfNoUniqueAddr) {
   const RecordType *RT = T->getAs<RecordType>();
   if (!RT)
     return false;
@@ -310,6 +322,11 @@ bool CodeGen::isEmptyRecord(ASTContext &Context, QualType 
T, bool AllowArrays,
   return true;
 }
 
+bool CodeGen::isEmptyRecordForLayout(const ASTContext &Context, QualType T) {
+  return isEmptyRecord(Context, T, /*AllowArrays=*/false,
+                       /*AsIfNoUniqueAddr=*/true);
+}
+
 const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) {
   const RecordType *RT = T->getAs<RecordType>();
   if (!RT)
diff --git a/clang/lib/CodeGen/ABIInfoImpl.h b/clang/lib/CodeGen/ABIInfoImpl.h
index 92986fb431646..ec5a5872462c7 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.h
+++ b/clang/lib/CodeGen/ABIInfoImpl.h
@@ -126,17 +126,26 @@ Address emitMergePHI(CodeGenFunction &CGF, Address Addr1,
 /// is an unnamed bit-field or an (array of) empty record(s). If
 /// AsIfNoUniqueAddr is true, then C++ record fields are considered empty if
 /// the [[no_unique_address]] attribute would have made them empty.
-bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays,
-                  bool AsIfNoUniqueAddr = false);
+bool isEmptyField(const ASTContext &Context, const FieldDecl *FD,
+                  bool AllowArrays, bool AsIfNoUniqueAddr = false);
+
+/// isEmptyFieldForLayout - Return true iff the field is "empty", that is,
+/// either a zero-width bit-field or an empty record.
+bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD);
 
 /// isEmptyRecord - Return true iff a structure contains only empty
 /// fields. Note that a structure with a flexible array member is not
 /// considered empty. If AsIfNoUniqueAddr is true, then C++ record fields are
 /// considered empty if the [[no_unique_address]] attribute would have made
 /// them empty.
-bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
+bool isEmptyRecord(const ASTContext &Context, QualType T, bool AllowArrays,
                    bool AsIfNoUniqueAddr = false);
 
+/// isEmptyRecordForLayout - Return true iff a structure contains only empty
+/// fields. Note, C++ record fields are considered empty if the
+/// [[no_unique_address]] attribute would have made them empty.
+bool isEmptyRecordForLayout(const ASTContext &Context, QualType T);
+
 /// isSingleElementStruct - Determine if a structure is a "single
 /// element struct", i.e. it has exactly one non-empty field or
 /// exactly one field which is itself a single element
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 534f46da74862..60a78e77f78c6 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -10,6 +10,7 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "ABIInfoImpl.h"
 #include "CGCUDARuntime.h"
 #include "CGCXXABI.h"
 #include "CGCall.h"
@@ -4756,7 +4757,7 @@ static Address emitAddrOfZeroSizeField(CodeGenFunction 
&CGF, Address Base,
 /// The resulting address doesn't necessarily have the right type.
 static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
                                       const FieldDecl *field) {
-  if (field->isZeroSize(CGF.getContext()))
+  if (isEmptyFieldForLayout(CGF.getContext(), field))
     return emitAddrOfZeroSizeField(CGF, base, field);
 
   const RecordDecl *rec = field->getParent();
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp 
b/clang/lib/CodeGen/CGExprConstant.cpp
index dffb8ce83b643..1c6f842081ada 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -10,6 +10,7 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "ABIInfoImpl.h"
 #include "CGCXXABI.h"
 #include "CGObjCRuntime.h"
 #include "CGRecordLayout.h"
@@ -2437,8 +2438,10 @@ static llvm::Constant *EmitNullConstant(CodeGenModule 
&CGM,
         cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
 
       // Ignore empty bases.
-      if (base->isEmpty() ||
-          CGM.getContext().getASTRecordLayout(base).getNonVirtualSize()
+      if (isEmptyRecordForLayout(CGM.getContext(), I.getType()) ||
+          CGM.getContext()
+              .getASTRecordLayout(base)
+              .getNonVirtualSize()
               .isZero())
         continue;
 
@@ -2474,7 +2477,7 @@ static llvm::Constant *EmitNullConstant(CodeGenModule 
&CGM,
         cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
 
       // Ignore empty bases.
-      if (base->isEmpty())
+      if (isEmptyRecordForLayout(CGM.getContext(), I.getType()))
         continue;
 
       unsigned fieldIndex = layout.getVirtualBaseIndex(base);
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp 
b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 5169be204c14d..c0f2e4e52f117 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -10,8 +10,9 @@
 //
 
//===----------------------------------------------------------------------===//
 
-#include "CGRecordLayout.h"
+#include "ABIInfoImpl.h"
 #include "CGCXXABI.h"
+#include "CGRecordLayout.h"
 #include "CodeGenTypes.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -384,7 +385,7 @@ void CGRecordLowering::accumulateFields(bool 
isNonVirtualBaseType) {
       Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd);
       assert((Field == FieldEnd || !Field->isBitField()) &&
              "Failed to accumulate all the bitfields");
-    } else if (Field->isZeroSize(Context)) {
+    } else if (isEmptyFieldForLayout(Context, *Field)) {
       // Empty fields have no storage.
       ++Field;
     } else {
@@ -634,7 +635,7 @@ CGRecordLowering::accumulateBitFields(bool 
isNonVirtualBaseType,
           // non-reusable tail padding.
           CharUnits LimitOffset;
           for (auto Probe = Field; Probe != FieldEnd; ++Probe)
-            if (!Probe->isZeroSize(Context)) {
+            if (!isEmptyFieldForLayout(Context, *Probe)) {
               // A member with storage sets the limit.
               assert((getFieldBitOffset(*Probe) % CharBits) == 0 &&
                      "Next storage is not byte-aligned");
@@ -732,7 +733,7 @@ void CGRecordLowering::accumulateBases() {
     // Bases can be zero-sized even if not technically empty if they
     // contain only a trailing array member.
     const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
-    if (!BaseDecl->isEmpty() &&
+    if (!isEmptyRecordForLayout(Context, Base.getType()) &&
         !Context.getASTRecordLayout(BaseDecl).getNonVirtualSize().isZero())
       Members.push_back(MemberInfo(Layout.getBaseClassOffset(BaseDecl),
           MemberInfo::Base, getStorageType(BaseDecl), BaseDecl));
@@ -880,7 +881,7 @@ CGRecordLowering::calculateTailClippingOffset(bool 
isNonVirtualBaseType) const {
   if (!isNonVirtualBaseType && isOverlappingVBaseABI())
     for (const auto &Base : RD->vbases()) {
       const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
-      if (BaseDecl->isEmpty())
+      if (isEmptyRecordForLayout(Context, Base.getType()))
         continue;
       // If the vbase is a primary virtual base of some base, then it doesn't
       // get its own storage location but instead lives inside of that base.
@@ -896,7 +897,7 @@ CGRecordLowering::calculateTailClippingOffset(bool 
isNonVirtualBaseType) const {
 void CGRecordLowering::accumulateVBases() {
   for (const auto &Base : RD->vbases()) {
     const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
-    if (BaseDecl->isEmpty())
+    if (isEmptyRecordForLayout(Context, Base.getType()))
       continue;
     CharUnits Offset = Layout.getVBaseClassOffset(BaseDecl);
     // If the vbase is a primary virtual base of some base, then it doesn't
@@ -1162,7 +1163,7 @@ CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, 
llvm::StructType *Ty) {
     const FieldDecl *FD = *it;
 
     // Ignore zero-sized fields.
-    if (FD->isZeroSize(getContext()))
+    if (isEmptyFieldForLayout(getContext(), FD))
       continue;
 
     // For non-bit-fields, just check that the LLVM struct offset matches the
diff --git a/clang/test/CodeGen/X86/x86_64-vaarg.c 
b/clang/test/CodeGen/X86/x86_64-vaarg.c
index d6b885d9fb18c..7d5102f93ca6f 100644
--- a/clang/test/CodeGen/X86/x86_64-vaarg.c
+++ b/clang/test/CodeGen/X86/x86_64-vaarg.c
@@ -56,7 +56,8 @@ typedef struct {
 // CHECK:       vaarg.end:
 // CHECK-NEXT:    [[VAARG_ADDR:%.*]] = phi ptr [ [[TMP1]], [[VAARG_IN_REG]] ], 
[ [[OVERFLOW_ARG_AREA]], [[VAARG_IN_MEM]] ]
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr 
align 8 [[VAARG_ADDR]], i64 8, i1 false)
-// CHECK-NEXT:    [[TMP3:%.*]] = load double, ptr [[RETVAL]], align 8
+// CHECK-NEXT:    [[COERCE:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr 
[[RETVAL]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP3:%.*]] = load double, ptr [[COERCE]], align 8
 // CHECK-NEXT:    ret double [[TMP3]]
 //
 s1 f(int z, ...) {
diff --git a/clang/test/CodeGen/debug-info-packed-struct.c 
b/clang/test/CodeGen/debug-info-packed-struct.c
index 676cdb38b396f..33b8b4c7e13fb 100644
--- a/clang/test/CodeGen/debug-info-packed-struct.c
+++ b/clang/test/CodeGen/debug-info-packed-struct.c
@@ -2,7 +2,7 @@
 
 // CHECK: %struct.layout3 = type <{ i8, [3 x i8], %struct.size8_pack4, i8, [3 
x i8] }>
 // CHECK: %struct.layout0 = type { i8, %struct.size8, i8 }
-// CHECK: %struct.layout1 = type <{ i8, %struct.size8_anon, i8, [2 x i8] }>
+// CHECK: %struct.layout1 = type { i8, [8 x i8], i8, [2 x i8] }
 // CHECK: %struct.layout2 = type <{ i8, %struct.size8_pack1, i8 }>
 
 // ---------------------------------------------------------------------
diff --git a/clang/test/CodeGen/paren-list-agg-init.cpp 
b/clang/test/CodeGen/paren-list-agg-init.cpp
index 88b1834d42d87..16cfe772a4ae5 100644
--- a/clang/test/CodeGen/paren-list-agg-init.cpp
+++ b/clang/test/CodeGen/paren-list-agg-init.cpp
@@ -48,14 +48,13 @@ struct E {
   ~E() {};
 };
 
-// CHECK-DAG: [[STRUCT_F:%.*]] = type { i8 }
 struct F {
   F (int i = 1);
   F (const F &f) = delete;
   F (F &&f) = default;
 };
 
-// CHECK-DAG: [[STRUCT_G:%.*]] = type <{ i32, [[STRUCT_F]], [3 x i8] }>
+// CHECK-DAG: [[STRUCT_G:%.*]] = type <{ i32, [4 x i8] }>
 struct G {
   int a;
   F f;
@@ -78,12 +77,12 @@ namespace gh61145 {
     ~Vec();
   };
 
-  // CHECK-DAG: [[STRUCT_S1:%.*]] = type { [[STRUCT_VEC]] }
+  // CHECK-DAG: [[STRUCT_S1:%.*]] = type { i8 }
   struct S1 {
     Vec v;
   };
 
-  // CHECK-DAG: [[STRUCT_S2:%.*]] = type { [[STRUCT_VEC]], i8 }
+  // CHECK-DAG: [[STRUCT_S2:%.*]] = type { i8, i8 }
   struct S2 {
     Vec v;
     char c;
@@ -377,7 +376,7 @@ void foo18() {
 // CHECK-NEXT: [[G:%.*g.*]] = alloca [[STRUCT_G]], align 4
 // CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_G]], ptr [[G]], 
i32 0, i32 0
 // CHECK-NEXT: store i32 2, ptr [[A]], align 4
-// CHECK-NEXT: [[F:%.*f.*]] = getelementptr inbounds [[STRUCT_G]], ptr [[G]], 
i32 0, i32 1
+// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds i8, ptr [[G]], i64 4
 // CHECk-NEXT: call void @{{.*F.*}}(ptr noundef nonnull align 1 
dereferenceable(1)) [[F]], ie32 noundef 1)
 // CHECK: ret void
 void foo19() {
@@ -392,9 +391,8 @@ namespace gh61145 {
   // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca 
[[STRUCT_S1]], align 1
   // a.k.a. Vec::Vec()
   // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 
dereferenceable(1) [[V]])
-  // CHECK-NEXT: [[V1:%.*v1.*]] = getelementptr inbounds [[STRUCT_S1]], ptr 
[[AGG_TMP_ENSURED]], i32 0, i32 0
   // a.k.a. Vec::Vec(Vec&&)
-  // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 
dereferenceable(1) [[V1]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+  // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 
dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 
dereferenceable(1) [[V]])
   // a.k.a. S1::~S1()
   // CHECK-NEXT: call void @_ZN7gh611452S1D1Ev(ptr noundef nonnull align 1 
dereferenceable(1) [[AGG_TMP_ENSURED]])
   // a.k.a.Vec::~Vec()
@@ -413,9 +411,8 @@ namespace gh61145 {
   // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca 
[[STRUCT_S2]], align 1
   // a.k.a. Vec::Vec()
   // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 
dereferenceable(1) [[V]])
-  // CHECK-NEXT: [[V1:%.*v1.*]] = getelementptr inbounds [[STRUCT_S2]], ptr 
[[AGG_TMP_ENSURED]], i32 0, i32 0
   // a.k.a. Vec::Vec(Vec&&)
-  // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 
dereferenceable(1) [[V1]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+  // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 
dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 
dereferenceable(1) [[V]])
   // CHECK-NEXT: [[C:%.*c.*]] = getelementptr inbounds [[STRUCT_S2]], ptr 
[[AGG_TMP_ENSURED]], i32 0, i32
   // CHECK-NEXT: store i8 0, ptr [[C]], align 1
   // a.k.a. S2::~S2()
diff --git a/clang/test/CodeGen/voidptr-vaarg.c 
b/clang/test/CodeGen/voidptr-vaarg.c
index d023ddf0fb5d2..4f008fd85115a 100644
--- a/clang/test/CodeGen/voidptr-vaarg.c
+++ b/clang/test/CodeGen/voidptr-vaarg.c
@@ -245,7 +245,8 @@ typedef struct {
 // CHECK-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i32 4
 // CHECK-NEXT:    store ptr [[ARGP_NEXT]], ptr [[LIST_ADDR]], align 4
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[RETVAL]], ptr 
align 4 [[ARGP_CUR]], i32 4, i1 false)
-// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[RETVAL]], align 4
+// CHECK-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds 
[[STRUCT_EMPTY_INT_T]], ptr [[RETVAL]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[COERCE_DIVE]], align 4
 // CHECK-NEXT:    ret i32 [[TMP0]]
 //
 empty_int_t empty_int(__builtin_va_list list) {
diff --git a/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp 
b/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
index 14557829268ef..3efb8c449c8fa 100644
--- a/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
+++ b/clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
@@ -19,8 +19,8 @@ struct S {
 };
 
 // CHECK: store i32 0, ptr @arr
-// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds 
(%struct.S, ptr @arr, i32 0, i32 1), ptr noundef @.str)
+// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (i8, ptr 
@arr, i64 4), ptr noundef @.str)
 // CHECK: store i32 1, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 1)
-// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds 
(%struct.S, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 1), i32 0, i32 
1), ptr noundef @.str.1)
+// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (i8, ptr 
getelementptr inbounds (%struct.S, ptr @arr, i64 1), i64 4), ptr noundef 
@.str.1)
 // CHECK: store i32 2, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 2)
-// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds 
(%struct.S, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 2), i32 0, i32 
1), ptr noundef @.str.2)
+// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (i8, ptr 
getelementptr inbounds (%struct.S, ptr @arr, i64 2), i64 4), ptr noundef 
@.str.2)
diff --git a/clang/test/CodeGenCXX/auto-var-init.cpp 
b/clang/test/CodeGenCXX/auto-var-init.cpp
index e1568bee136e5..b0fc4946040b7 100644
--- a/clang/test/CodeGenCXX/auto-var-init.cpp
+++ b/clang/test/CodeGenCXX/auto-var-init.cpp
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks %s 
-emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,CHECK-O0
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks 
-ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s 
-check-prefixes=CHECK-O0,PATTERN,PATTERN-O0
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks 
-ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s 
-check-prefixes=CHECK-O0,PATTERN,PATTERN-O0,PATTERN-64-O0
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks 
-ftrivial-auto-var-init=pattern %s -O1 -emit-llvm -o - | FileCheck %s 
-check-prefixes=PATTERN,PATTERN-O1
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks 
-ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s 
-check-prefixes=CHECK-O0,ZERO,ZERO-O0
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks 
-ftrivial-auto-var-init=zero %s -O1 -emit-llvm -o - | FileCheck %s 
-check-prefixes=ZERO,ZERO-O1
-// RUN: %clang_cc1 -std=c++14 -triple i386-unknown-unknown -fblocks 
-ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s 
-check-prefixes=CHECK-O0,PATTERN,PATTERN-O0
+// RUN: %clang_cc1 -std=c++14 -triple i386-unknown-unknown -fblocks 
-ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s 
-check-prefixes=CHECK-O0,PATTERN,PATTERN-O0,PATTERN-32-O0
 
 #pragma clang diagnostic ignored "-Winaccessible-base"
 
@@ -174,14 +174,17 @@ struct semivolatileinit { int i = 0x11111111; volatile 
int vi = 0x11111111; };
 // PATTERN-O0: @__const.test_base_braces.braces = private unnamed_addr 
constant %struct.base { ptr inttoptr ([[IPTRT]] [[IPTR]] to ptr) }, align
 // PATTERN-O1-NOT: @__const.test_base_braces.braces
 struct base { virtual ~base(); };
-// PATTERN-O0: @__const.test_derived_uninit.uninit = private unnamed_addr 
constant %struct.derived { %struct.base { ptr inttoptr ([[IPTRT]] [[IPTR]] to 
ptr) } }, align
+// PATTERN-32-O0: @__const.test_derived_uninit.uninit = private unnamed_addr 
constant %struct.derived { [4 x i8] c"\FF\FF\FF\FF" }, align 4
+// PATTERN-64-O0: @__const.test_derived_uninit.uninit = private unnamed_addr 
constant %struct.derived { [8 x i8] c"\AA\AA\AA\AA\AA\AA\AA\AA" }, align 8
 // PATTERN-O1-NOT: @__const.test_derived_uninit.uninit
-// PATTERN-O0: @__const.test_derived_braces.braces = private unnamed_addr 
constant %struct.derived { %struct.base { ptr inttoptr ([[IPTRT]] [[IPTR]] to 
ptr) } }, align
+// PATTERN-32-O0: @__const.test_derived_braces.braces = private unnamed_addr 
constant %struct.derived { [4 x i8] c"\FF\FF\FF\FF" }, align 4
+// PATTERN-64-O0: @__const.test_derived_braces.braces = private unnamed_addr 
constant %struct.derived { [8 x i8] c"\AA\AA\AA\AA\AA\AA\AA\AA" }, align 8
 // PATTERN-O1-NOT: @__const.test_derived_braces.braces
 struct derived : public base {};
-// PATTERN-O0: @__const.test_virtualderived_uninit.uninit = private 
unnamed_addr constant %struct.virtualderived { %struct.base { ptr inttoptr 
([[IPTRT]] [[IPTR]] to ptr) }, %struct.derived { %struct.base { ptr inttoptr 
([[IPTRT]] [[IPTR]] to ptr) } } }, align
+// PATERN-O0: @__const.test_virtualderived_uninit.uninit = private 
unnamed_addr constant %struct.virtualderived { %struct.base { ptr inttoptr (i64 
-6148914691236517206 to ptr) }, [8 x i8] c"\AA\AA\AA\AA\AA\AA\AA\AA" }, align 8
 // PATTERN-O1-NOT: @__const.test_virtualderived_uninit.uninit
-// PATTERN-O0: @__const.test_virtualderived_braces.braces = private unnam...
[truncated]

``````````

</details>


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

Reply via email to