Skip to content

Commit f8bb4f9

Browse files
authored
[HLSL] Enable InitList code to handle zero sized structs (#160355)
Enable InitList code to handle zero sized structs; this includes structs with no fields and those with only unnamed bitfields. Closes #157920
1 parent 88aab08 commit f8bb4f9

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4283,6 +4283,9 @@ bool SemaHLSL::transformInitList(const InitializedEntity &Entity,
42834283
}
42844284
size_t ExpectedSize = ILT.DestTypes.size();
42854285
size_t ActualSize = ILT.ArgExprs.size();
4286+
if (ExpectedSize == 0 && ActualSize == 0)
4287+
return true;
4288+
42864289
// For incomplete arrays it is completely arbitrary to choose whether we think
42874290
// the user intended fewer or more elements. This implementation assumes that
42884291
// the user intended more, and errors that there are too few initializers to

clang/test/CodeGenHLSL/BasicFeatures/InitLists.hlsl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,22 @@ struct Unnamed {
5050
int : 8;
5151
};
5252

53+
struct Empty {
54+
};
55+
56+
struct UnnamedOnly {
57+
int : 8;
58+
};
59+
60+
struct EmptyDerived : Empty {};
61+
62+
struct UnnamedDerived : UnnamedOnly {};
63+
64+
// CHECK-DAG: [[ConstE:@.*]] = private unnamed_addr constant %struct.Empty undef, align 1
65+
// CHECK-DAG: [[ConstUO:@.*]] = private unnamed_addr constant %struct.UnnamedOnly undef, align 1
66+
// CHECK-DAG: [[ConstED:@.*]] = private unnamed_addr constant %struct.EmptyDerived undef, align 1
67+
// CHECK-DAG: [[ConstUD:@.*]] = private unnamed_addr constant %struct.UnnamedDerived undef, align 1
68+
5369
// Case 1: Extraneous braces get ignored in literal instantiation.
5470
// CHECK-LABEL: define hidden void @_Z5case1v(
5571
// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 1 [[AGG_RESULT:%.*]]) #[[ATTR0:[0-9]+]] {
@@ -985,3 +1001,57 @@ void case18() {
9851001
void case19(Unnamed U) {
9861002
TwoInts TI = {U, 1};
9871003
}
1004+
1005+
// InitList with Empty Struct on LHS
1006+
// CHECK-LABEL: case20
1007+
// CHECK: [[E:%.*]] = alloca %struct.Empty, align 1
1008+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[E]], ptr align 1 [[ConstE]], i32 1, i1 false)
1009+
void case20() {
1010+
Empty E = {};
1011+
}
1012+
1013+
// InitList with Empty Struct on RHS
1014+
// CHECK-LABEL: case21
1015+
// CHECK: [[TI:%.*]] = alloca %struct.TwoInts, align 1
1016+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 %TI, ptr align 1 {{.*}}, i32 8, i1 false)
1017+
void case21(Empty E) {
1018+
TwoInts TI = {E, 1, 2};
1019+
}
1020+
1021+
// InitList with Struct with only unnamed bitfield on LHS
1022+
// CHECK-LABEL: case22
1023+
// CHECK: [[UO:%.*]] = alloca %struct.UnnamedOnly, align 1
1024+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[UO]], ptr align 1 [[ConstUO]], i32 1, i1 false)
1025+
void case22() {
1026+
UnnamedOnly UO = {};
1027+
}
1028+
1029+
// InitList with Struct with only unnamed bitfield on RHS
1030+
// CHECK-LABEL: case23
1031+
// CHECK: [[TI:%.*]] = alloca %struct.TwoInts, align 1
1032+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[TI]], ptr align 1 {{.*}}, i32 8, i1 false)
1033+
void case23(UnnamedOnly UO) {
1034+
TwoInts TI = {UO, 1, 2};
1035+
}
1036+
1037+
// InitList with Derived empty struct on LHS
1038+
// InitList with Derived unnamed bitfield on LHS
1039+
// CHECK-LABEL: case24
1040+
// CHECK: [[ED:%.*]] = alloca %struct.EmptyDerived, align 1
1041+
// CHECK-NEXT: [[UD:%.*]] = alloca %struct.UnnamedDerived, align 1
1042+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 %ED, ptr align 1 [[ConstED]], i32 1, i1 false)
1043+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 %UD, ptr align 1 [[ConstUD]], i32 1, i1 false)
1044+
void case24() {
1045+
EmptyDerived ED = {};
1046+
UnnamedDerived UD = {};
1047+
}
1048+
1049+
// CHECK-LABEL: case25
1050+
// CHECK: [[TI1:%.*]] = alloca %struct.TwoInts, align 1
1051+
// CHECK-NEXT: [[TI2:%.*]] = alloca %struct.TwoInts, align 1
1052+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 %TI1, ptr align 1 {{.*}}, i32 8, i1 false)
1053+
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 %TI2, ptr align 1 {{.*}}, i32 8, i1 false)
1054+
void case25(EmptyDerived ED, UnnamedDerived UD) {
1055+
TwoInts TI1 = {ED, 1, 2};
1056+
TwoInts TI2 = {UD, 1, 2};
1057+
}

0 commit comments

Comments
 (0)