Skip to content

Commit 07e603f

Browse files
committed
[clang][CGRecordLayout] Remove dependency on isZeroSize
This is a follow-up from the conversation starting at llvm#93809 (comment) 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 examples 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<->Clang layout consistency checks. There has been precedent for avoiding such layout-altering attributes to affect 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`.
1 parent f4c7811 commit 07e603f

24 files changed

+85
-116
lines changed

clang/lib/CodeGen/ABIInfoImpl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address Addr1,
248248
return Address(PHI, Addr1.getElementType(), Align);
249249
}
250250

251-
bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
251+
bool CodeGen::isEmptyField(const ASTContext &Context, const FieldDecl *FD,
252252
bool AllowArrays, bool AsIfNoUniqueAddr) {
253253
if (FD->isUnnamedBitField())
254254
return true;
@@ -289,8 +289,8 @@ bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
289289
return isEmptyRecord(Context, FT, AllowArrays, AsIfNoUniqueAddr);
290290
}
291291

292-
bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
293-
bool AsIfNoUniqueAddr) {
292+
bool CodeGen::isEmptyRecord(const ASTContext &Context, QualType T,
293+
bool AllowArrays, bool AsIfNoUniqueAddr) {
294294
const RecordType *RT = T->getAs<RecordType>();
295295
if (!RT)
296296
return false;

clang/lib/CodeGen/ABIInfoImpl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,15 @@ Address emitMergePHI(CodeGenFunction &CGF, Address Addr1,
126126
/// is an unnamed bit-field or an (array of) empty record(s). If
127127
/// AsIfNoUniqueAddr is true, then C++ record fields are considered empty if
128128
/// the [[no_unique_address]] attribute would have made them empty.
129-
bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays,
130-
bool AsIfNoUniqueAddr = false);
129+
bool isEmptyField(const ASTContext &Context, const FieldDecl *FD,
130+
bool AllowArrays, bool AsIfNoUniqueAddr = false);
131131

132132
/// isEmptyRecord - Return true iff a structure contains only empty
133133
/// fields. Note that a structure with a flexible array member is not
134134
/// considered empty. If AsIfNoUniqueAddr is true, then C++ record fields are
135135
/// considered empty if the [[no_unique_address]] attribute would have made
136136
/// them empty.
137-
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
137+
bool isEmptyRecord(const ASTContext &Context, QualType T, bool AllowArrays,
138138
bool AsIfNoUniqueAddr = false);
139139

140140
/// isSingleElementStruct - Determine if a structure is a "single

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "ABIInfoImpl.h"
1314
#include "CGCUDARuntime.h"
1415
#include "CGCXXABI.h"
1516
#include "CGCall.h"
@@ -4749,7 +4750,7 @@ static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base,
47494750
/// The resulting address doesn't necessarily have the right type.
47504751
static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
47514752
const FieldDecl *field) {
4752-
if (field->isZeroSize(CGF.getContext()))
4753+
if (isEmptyField(CGF.getContext(), field, false, true))
47534754
return emitAddrOfZeroSizeField(CGF, base, field);
47544755

47554756
const RecordDecl *rec = field->getParent();

clang/lib/CodeGen/CGRecordLayoutBuilder.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#include "CGRecordLayout.h"
13+
#include "ABIInfoImpl.h"
1414
#include "CGCXXABI.h"
1515
#include "CodeGenTypes.h"
1616
#include "clang/AST/ASTContext.h"
@@ -384,7 +384,7 @@ void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) {
384384
Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd);
385385
assert((Field == FieldEnd || !Field->isBitField()) &&
386386
"Failed to accumulate all the bitfields");
387-
} else if (Field->isZeroSize(Context)) {
387+
} else if (isEmptyField(Context, *Field, false, true)) {
388388
// Empty fields have no storage.
389389
++Field;
390390
} else {
@@ -634,7 +634,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
634634
// non-reusable tail padding.
635635
CharUnits LimitOffset;
636636
for (auto Probe = Field; Probe != FieldEnd; ++Probe)
637-
if (!Probe->isZeroSize(Context)) {
637+
if (!isEmptyField(Context, *Probe, false, true)) {
638638
// A member with storage sets the limit.
639639
assert((getFieldBitOffset(*Probe) % CharBits) == 0 &&
640640
"Next storage is not byte-aligned");
@@ -732,7 +732,7 @@ void CGRecordLowering::accumulateBases() {
732732
// Bases can be zero-sized even if not technically empty if they
733733
// contain only a trailing array member.
734734
const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
735-
if (!BaseDecl->isEmpty() &&
735+
if (!isEmptyRecord(Context, Base.getType(), false, true) &&
736736
!Context.getASTRecordLayout(BaseDecl).getNonVirtualSize().isZero())
737737
Members.push_back(MemberInfo(Layout.getBaseClassOffset(BaseDecl),
738738
MemberInfo::Base, getStorageType(BaseDecl), BaseDecl));
@@ -880,7 +880,7 @@ CGRecordLowering::calculateTailClippingOffset(bool isNonVirtualBaseType) const {
880880
if (!isNonVirtualBaseType && isOverlappingVBaseABI())
881881
for (const auto &Base : RD->vbases()) {
882882
const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
883-
if (BaseDecl->isEmpty())
883+
if (isEmptyRecord(Context, Base.getType(), false, true))
884884
continue;
885885
// If the vbase is a primary virtual base of some base, then it doesn't
886886
// get its own storage location but instead lives inside of that base.
@@ -896,7 +896,7 @@ CGRecordLowering::calculateTailClippingOffset(bool isNonVirtualBaseType) const {
896896
void CGRecordLowering::accumulateVBases() {
897897
for (const auto &Base : RD->vbases()) {
898898
const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
899-
if (BaseDecl->isEmpty())
899+
if (isEmptyRecord(Context, Base.getType(), false, true))
900900
continue;
901901
CharUnits Offset = Layout.getVBaseClassOffset(BaseDecl);
902902
// If the vbase is a primary virtual base of some base, then it doesn't
@@ -1162,7 +1162,7 @@ CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty) {
11621162
const FieldDecl *FD = *it;
11631163

11641164
// Ignore zero-sized fields.
1165-
if (FD->isZeroSize(getContext()))
1165+
if (isEmptyField(Context, FD, false, true))
11661166
continue;
11671167

11681168
// For non-bit-fields, just check that the LLVM struct offset matches the

clang/test/CodeGen/X86/x86_64-vaarg.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ typedef struct {
5656
// CHECK: vaarg.end:
5757
// CHECK-NEXT: [[VAARG_ADDR:%.*]] = phi ptr [ [[TMP1]], [[VAARG_IN_REG]] ], [ [[OVERFLOW_ARG_AREA]], [[VAARG_IN_MEM]] ]
5858
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[RETVAL]], ptr align 8 [[VAARG_ADDR]], i64 8, i1 false)
59-
// CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[RETVAL]], align 8
59+
// CHECK-NEXT: [[COERCE:%.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[RETVAL]], i32 0, i32 0
60+
// CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[COERCE]], align 8
6061
// CHECK-NEXT: ret double [[TMP3]]
6162
//
6263
s1 f(int z, ...) {

clang/test/CodeGen/debug-info-packed-struct.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// CHECK: %struct.layout3 = type <{ i8, [3 x i8], %struct.size8_pack4, i8, [3 x i8] }>
44
// CHECK: %struct.layout0 = type { i8, %struct.size8, i8 }
5-
// CHECK: %struct.layout1 = type <{ i8, %struct.size8_anon, i8, [2 x i8] }>
5+
// CHECK: %struct.layout1 = type { i8, [8 x i8], i8, [2 x i8] }
66
// CHECK: %struct.layout2 = type <{ i8, %struct.size8_pack1, i8 }>
77

88
// ---------------------------------------------------------------------

clang/test/CodeGen/paren-list-agg-init.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,13 @@ struct E {
4848
~E() {};
4949
};
5050

51-
// CHECK-DAG: [[STRUCT_F:%.*]] = type { i8 }
5251
struct F {
5352
F (int i = 1);
5453
F (const F &f) = delete;
5554
F (F &&f) = default;
5655
};
5756

58-
// CHECK-DAG: [[STRUCT_G:%.*]] = type <{ i32, [[STRUCT_F]], [3 x i8] }>
57+
// CHECK-DAG: [[STRUCT_G:%.*]] = type <{ i32, [4 x i8] }>
5958
struct G {
6059
int a;
6160
F f;
@@ -78,12 +77,12 @@ namespace gh61145 {
7877
~Vec();
7978
};
8079

81-
// CHECK-DAG: [[STRUCT_S1:%.*]] = type { [[STRUCT_VEC]] }
80+
// CHECK-DAG: [[STRUCT_S1:%.*]] = type { i8 }
8281
struct S1 {
8382
Vec v;
8483
};
8584

86-
// CHECK-DAG: [[STRUCT_S2:%.*]] = type { [[STRUCT_VEC]], i8 }
85+
// CHECK-DAG: [[STRUCT_S2:%.*]] = type { i8, i8 }
8786
struct S2 {
8887
Vec v;
8988
char c;
@@ -377,7 +376,7 @@ void foo18() {
377376
// CHECK-NEXT: [[G:%.*g.*]] = alloca [[STRUCT_G]], align 4
378377
// CHECK-NEXT: [[A:%.*a.*]] = getelementptr inbounds [[STRUCT_G]], ptr [[G]], i32 0, i32 0
379378
// CHECK-NEXT: store i32 2, ptr [[A]], align 4
380-
// CHECK-NEXT: [[F:%.*f.*]] = getelementptr inbounds [[STRUCT_G]], ptr [[G]], i32 0, i32 1
379+
// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds i8, ptr [[G]], i64 4
381380
// CHECk-NEXT: call void @{{.*F.*}}(ptr noundef nonnull align 1 dereferenceable(1)) [[F]], ie32 noundef 1)
382381
// CHECK: ret void
383382
void foo19() {
@@ -392,9 +391,8 @@ namespace gh61145 {
392391
// CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S1]], align 1
393392
// a.k.a. Vec::Vec()
394393
// CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
395-
// CHECK-NEXT: [[V1:%.*v1.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
396394
// a.k.a. Vec::Vec(Vec&&)
397-
// CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[V1]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
395+
// CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
398396
// a.k.a. S1::~S1()
399397
// CHECK-NEXT: call void @_ZN7gh611452S1D1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]])
400398
// a.k.a.Vec::~Vec()
@@ -413,9 +411,8 @@ namespace gh61145 {
413411
// CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S2]], align 1
414412
// a.k.a. Vec::Vec()
415413
// CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
416-
// CHECK-NEXT: [[V1:%.*v1.*]] = getelementptr inbounds [[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
417414
// a.k.a. Vec::Vec(Vec&&)
418-
// CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[V1]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
415+
// CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
419416
// CHECK-NEXT: [[C:%.*c.*]] = getelementptr inbounds [[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32
420417
// CHECK-NEXT: store i8 0, ptr [[C]], align 1
421418
// a.k.a. S2::~S2()

clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ struct S {
1919
};
2020

2121
// CHECK: store i32 0, ptr @arr
22-
// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (%struct.S, ptr @arr, i32 0, i32 1), ptr noundef @.str)
22+
// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (i8, ptr @arr, i64 4), ptr noundef @.str)
2323
// CHECK: store i32 1, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 1)
24-
// 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)
24+
// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (i8, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 1), i64 4), ptr noundef @.str.1)
2525
// CHECK: store i32 2, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 2)
26-
// 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)
26+
// CHECK: call void @_ZN1AC1EPKc(ptr {{[^,]*}} getelementptr inbounds (i8, ptr getelementptr inbounds (%struct.S, ptr @arr, i64 2), i64 4), ptr noundef @.str.2)

clang/test/CodeGenCXX/auto-var-init.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// 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
44
// 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
55
// 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
6-
// 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
6+
// TODO %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
77

88
#pragma clang diagnostic ignored "-Winaccessible-base"
99

@@ -166,14 +166,14 @@ struct semivolatileinit { int i = 0x11111111; volatile int vi = 0x11111111; };
166166
// PATTERN-O0: @__const.test_base_braces.braces = private unnamed_addr constant %struct.base { ptr inttoptr ([[IPTRT]] [[IPTR]] to ptr) }, align
167167
// PATTERN-O1-NOT: @__const.test_base_braces.braces
168168
struct base { virtual ~base(); };
169-
// PATTERN-O0: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { ptr inttoptr ([[IPTRT]] [[IPTR]] to ptr) } }, align
169+
// PATTERN-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
170170
// PATTERN-O1-NOT: @__const.test_derived_uninit.uninit
171-
// PATTERN-O0: @__const.test_derived_braces.braces = private unnamed_addr constant %struct.derived { %struct.base { ptr inttoptr ([[IPTRT]] [[IPTR]] to ptr) } }, align
171+
// PATTERN-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
172172
// PATTERN-O1-NOT: @__const.test_derived_braces.braces
173173
struct derived : public base {};
174-
// 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
174+
// 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
175175
// PATTERN-O1-NOT: @__const.test_virtualderived_uninit.uninit
176-
// PATTERN-O0: @__const.test_virtualderived_braces.braces = 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
176+
// PATTERN-O0: @__const.test_virtualderived_braces.braces = 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
177177
// PATTERN-O1-NOT: @__const.test_virtualderived_braces.braces
178178
struct virtualderived : public virtual base, public virtual derived {};
179179
// PATTERN-O0: @__const.test_matching_uninit.uninit = private unnamed_addr constant %union.matching { i32 [[I32]] }, align 4

clang/test/CodeGenCXX/bitfield-access-empty.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ struct P3 {
8484
unsigned b : 16;
8585
} p3;
8686
// CHECK-LABEL: LLVMType:%struct.P3 =
87-
// LAYOUT-SAME: type { i16, %struct.Empty, i16, [2 x i8] }
88-
// LAYOUT-DWN32-SAME: type <{ i16, %struct.Empty, i16 }>
87+
// LAYOUT-SAME: type { i16, [2 x i8], i16, [2 x i8] }
88+
// LAYOUT-DWN32-SAME: type <{ i16, i8, i16 }>
8989
// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P3 =
9090
// CHECK: BitFields:[
9191
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:0 StorageSize:16 StorageOffset:0
@@ -138,13 +138,13 @@ struct P7 {
138138
unsigned c;
139139
} p7;
140140
// CHECK-LABEL: LLVMType:%struct.P7 =
141-
// LAYOUT-SAME: type { i16, i8, %struct.Empty, i32 }
142-
// LAYOUT-DWN32-SAME: type { i16, i8, %struct.Empty, i32 }
141+
// LAYOUT-SAME: type { i32, i32 }
142+
// LAYOUT-DWN32-SAME: type { i32, i32 }
143143
// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P7 =
144144
// CHECK: BitFields:[
145-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:0 StorageSize:16 StorageOffset:0
146-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:0 StorageSize:8 StorageOffset:2
145+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:0 StorageSize:32 StorageOffset:0
146+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:0 StorageSize:32 StorageOffset:0
147147

148-
// LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:0 StorageSize:16 StorageOffset:0
149-
// LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:0 StorageSize:8 StorageOffset:2
148+
// LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:0 StorageSize:32 StorageOffset:0
149+
// LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:0 StorageSize:32 StorageOffset:0
150150
// CHECK-NEXT: ]>

clang/test/CodeGenCXX/class-layout.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ namespace Test6 {
8383
namespace Test7 {
8484
#pragma pack (1)
8585
class A {};
86-
// CHECK: %"class.Test7::B" = type <{ ptr, %"class.Test7::A" }>
86+
// CHECK: %"class.Test7::B" = type <{ ptr, i8 }>
8787
class B {
8888
virtual ~B();
8989
A a;

clang/test/CodeGenCXX/compound-literals.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ int f() {
2020
// CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca
2121
// CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}}, ptr [[LVALUE]], i32 0, i32 0
2222
// CHECK-NEXT: store i32 17, ptr [[I]]
23-
// CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 1
23+
// CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 4
2424
// CHECK-NEXT: call noundef ptr @_ZN1XC1EPKc({{.*}}[[X]]
2525
// CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 0
2626
// CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = load i32, ptr

clang/test/CodeGenCXX/exceptions.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,7 @@ namespace test11 {
513513
// CHECK-LABEL: define{{.*}} void @_ZN6test111CC2Ev(
514514
// CHECK: [[THIS:%.*]] = load ptr, ptr {{%.*}}
515515
// Construct single.
516-
// CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[C:%.*]], ptr [[THIS]], i32 0, i32 0
517-
// CHECK-NEXT: call void @_ZN6test111AC1Ev(ptr {{[^,]*}} [[SINGLE]])
516+
// CHECK-NEXT: call void @_ZN6test111AC1Ev(ptr {{[^,]*}} [[THIS]])
518517
// Construct array.
519518
// CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[C:%.*]], ptr [[THIS]], i32 0, i32 1
520519
// CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A:%.*]]]], ptr [[ARRAY]], i32 0, i32 0, i32 0
@@ -560,8 +559,8 @@ namespace test11 {
560559
// CHECK: br label
561560
// Finally, the cleanup for single.
562561

563-
// CHECK98: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[SINGLE]])
564-
// CHECK11: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[SINGLE]])
562+
// CHECK98: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[THIS]])
563+
// CHECK11: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[THIS]])
565564

566565
// CHECK: br label
567566
// CHECK: resume

clang/test/CodeGenCXX/lambda-deterministic-captures.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ void foo() {
1616
}
1717

1818
// CHECK: define{{.*}} void @_Z3foov
19-
// CHECK: getelementptr inbounds %{{.+}}, ptr %{{.+}}, i32 0, i32 0
20-
// CHECK-NEXT: getelementptr inbounds %{{.+}}, ptr %{{.+}}, i32 0, i32 1
19+
// CHECK: getelementptr inbounds %{{.+}}, ptr %{{.+}}, i32 0, i32 1
2120
// CHECK-NEXT: store float 0.000
2221
// CHECK-NEXT: getelementptr inbounds %{{.+}}, ptr %{{.+}}, i32 0, i32 2
2322
// CHECK-NEXT: store float 1.000
@@ -27,7 +26,6 @@ void foo() {
2726
// The lambda body. Reverse iteration when the captures aren't deterministic
2827
// causes these to be laid out differently in the lambda.
2928
// CHECK: define internal void
30-
// CHECK: getelementptr inbounds %{{.+}}, ptr %{{.+}}, i32 0, i32 0
3129
// CHECK: getelementptr inbounds %{{.+}}, ptr %{{.+}}, i32 0, i32 1
3230
// CHECK: getelementptr inbounds %{{.+}}, ptr %{{.+}}, i32 0, i32 2
3331
// CHECK: getelementptr inbounds %{{.+}}, ptr %{{.+}}, i32 0, i32 3

clang/test/CodeGenCXX/ms_struct.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ struct ATTR Derived : Base {
1818
int value;
1919
};
2020

21-
// CHECK: [[DERIVED:%.*]] = type <{ [[BASE:%.*]], i32, [4 x i8] }>
22-
// CHECK: [[BASE]] = type { [[VBASE:%.*]] }
23-
// CHECK: [[VBASE]] = type { ptr }
21+
// CHECK: [[DERIVED:%.*]] = type { [8 x i8], i32, [4 x i8] }
2422

2523
// CHECK: define{{.*}} void @_ZN7DerivedC2Ev
2624
// CHECK: [[SELF:%.*]] = load ptr

0 commit comments

Comments
 (0)