Skip to content

Commit e7a3802

Browse files
authored
[BoundsSafety] Don't bind lvalues with temporary locations (#10969)
* [BoundsSafety] Don't bind lvalues with temporary locations This should fix a miscompilation bug found during adoption. When a base is lvalue and is wrapped in OVE, the compiler incorrectly creates a temporary and maps its address to the lvalue instead of the actual address of the lvalue. The solution is to emit lvalue directly instead of creating extra temporary. rdar://146329029 * [BoundsSafety][NFC] Don't emit wide pointer indexing in argument passing in order to avoid non-determinism The execution order of arguments is unspecified in C++. Directly passing calls that emit code as arguments caused non-deterministic order in the generated instructions and test failures in different platforms. * [BoundsSafety][NFC] Adjust BoundsSafety-legacy codegen tests
1 parent 0b39479 commit e7a3802

29 files changed

+1069
-503
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7070,14 +7070,8 @@ LValue CodeGenFunction::EmitMaterializeSequenceExprLValue(
70707070
const MaterializeSequenceExpr *MSE) {
70717071
if (MSE->isBinding()) {
70727072
for (auto *OVE : MSE->opaquevalues()) {
7073-
if (CodeGenFunction::OpaqueValueMappingData::shouldBindAsLValue(OVE)) {
7074-
RValue PtrRV = EmitAnyExpr(OVE->getSourceExpr());
7075-
LValue LV = MakeAddrLValue(PtrRV.getAggregateAddress(), OVE->getType());
7076-
CodeGenFunction::OpaqueValueMappingData::bind(*this, OVE, LV);
7077-
} else {
7078-
CodeGenFunction::OpaqueValueMappingData::bind(
7079-
*this, OVE, OVE->getSourceExpr());
7080-
}
7073+
CodeGenFunction::OpaqueValueMappingData::bind(
7074+
*this, OVE, OVE->getSourceExpr());
70817075
}
70827076
}
70837077

clang/lib/CodeGen/CGExprAgg.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -441,13 +441,13 @@ void AggExprEmitter::EmitWidePointerBitCast(CastExpr *E) {
441441
RValue SrcRV = CGF.EmitAnyExpr(E->getSubExpr());
442442
assert(SrcRV.isAggregate());
443443
Address SrcAddr = SrcRV.getAggregateAddress();
444-
EmitWidePointerToDest(E->getType(),
445-
CGF.GetWidePointerElement(SrcAddr, WPIndex::Pointer),
446-
CGF.GetWidePointerElement(SrcAddr, WPIndex::Upper),
447-
E->getType()->isBidiIndexablePointerType()
444+
llvm::Value *Ptr = CGF.GetWidePointerElement(SrcAddr, WPIndex::Pointer);
445+
llvm::Value *Upper = CGF.GetWidePointerElement(SrcAddr, WPIndex::Upper);
446+
llvm::Value *Lower = E->getType()->isBidiIndexablePointerType()
448447
? CGF.GetWidePointerElement(SrcAddr, WPIndex::Lower)
449-
: nullptr,
450-
ElemBitCast);
448+
: nullptr;
449+
450+
EmitWidePointerToDest(E->getType(), Ptr, Upper, Lower, ElemBitCast);
451451
}
452452

453453
void AggExprEmitter::EmitWidePointer(LValue DestLV, llvm::Value *Ptr,
@@ -596,13 +596,7 @@ void AggExprEmitter::VisitPredefinedBoundsCheckExpr(
596596
void AggExprEmitter::VisitMaterializeSequenceExpr(MaterializeSequenceExpr *MSE) {
597597
if (MSE->isBinding()) {
598598
for (auto *OVE : MSE->opaquevalues()) {
599-
if (CodeGenFunction::OpaqueValueMappingData::shouldBindAsLValue(OVE)) {
600-
RValue PtrRV = CGF.EmitAnyExpr(OVE->getSourceExpr());
601-
LValue LV = CGF.MakeAddrLValue(PtrRV.getAggregateAddress(), OVE->getType());
602-
CodeGenFunction::OpaqueValueMappingData::bind(CGF, OVE, LV);
603-
} else {
604-
CodeGenFunction::OpaqueValueMappingData::bind(CGF, OVE, OVE->getSourceExpr());
605-
}
599+
CodeGenFunction::OpaqueValueMappingData::bind(CGF, OVE, OVE->getSourceExpr());
606600
}
607601
}
608602

clang/test/BoundsSafety-legacy-checks/CodeGen/constant-eval-count-static-init.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@ const Item oidRsa = { _oidRsa, sizeof(_oidRsa)};
1717
// CHECK-NEXT: entry:
1818
// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
1919
// CHECK-NEXT: [[AGG_TEMP:%.*]] = alloca %"__bounds_safety::wide_ptr.bidi_indexable", align 8
20-
// CHECK-NEXT: [[AGG_TEMP1:%.*]] = alloca [[STRUCT_ITEM:%.*]], align 8
2120
// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4
22-
// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TEMP1]], ptr align 8 @oidRsa, i64 16, i1 false)
23-
// CHECK-NEXT: [[LENGTH:%.*]] = getelementptr inbounds nuw [[STRUCT_ITEM]], ptr [[AGG_TEMP1]], i32 0, i32 1
24-
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[LENGTH]], align 8
25-
// CHECK-NEXT: [[DATA:%.*]] = getelementptr inbounds nuw [[STRUCT_ITEM]], ptr [[AGG_TEMP1]], i32 0, i32 0
26-
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[DATA]], align 8
21+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds nuw ([[STRUCT_ITEM:%.*]], ptr @oidRsa, i32 0, i32 1), align 8
22+
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr @oidRsa, align 8
2723
// CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[TMP0]] to i64
2824
// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i64 [[IDX_EXT]]
2925
// CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw %"__bounds_safety::wide_ptr.bidi_indexable", ptr [[AGG_TEMP]], i32 0, i32 0
@@ -46,11 +42,11 @@ const Item oidRsa = { _oidRsa, sizeof(_oidRsa)};
4642
// CHECK-NEXT: unreachable
4743
// CHECK: cont:
4844
// CHECK-NEXT: [[TMP7:%.*]] = icmp uge ptr [[TMP5]], [[WIDE_PTR_LB]], {{!annotation ![0-9]+}}
49-
// CHECK-NEXT: br i1 [[TMP7]], label [[CONT3:%.*]], label [[TRAP2:%.*]], {{!annotation ![0-9]+}}
50-
// CHECK: trap2:
45+
// CHECK-NEXT: br i1 [[TMP7]], label %[[CONT3:.*]], label %[[TRAP2:.*]], {{!prof ![0-9]+}}, {{!annotation ![0-9]+}}
46+
// CHECK: [[TRAP2]]:
5147
// CHECK-NEXT: call void @llvm.ubsantrap(i8 25) #[[ATTR3]], {{!annotation ![0-9]+}}
5248
// CHECK-NEXT: unreachable
53-
// CHECK: cont3:
49+
// CHECK: [[CONT3]]:
5450
// CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP5]], align 4
5551
// CHECK-NEXT: ret i32 [[TMP8]]
5652
//

clang/test/BoundsSafety-legacy-checks/CodeGen/count-dependent-assignment-checks/count-attr-fields-assign-2-oob2.c

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,8 @@ struct S {
2727
// CHECK-O0-NEXT: [[AGG_TEMP33:%.*]] = alloca %"__bounds_safety::wide_ptr.bidi_indexable", align 8
2828
// CHECK-O0-NEXT: [[I:%.*]] = alloca i32, align 4
2929
// CHECK-O0-NEXT: [[AGG_TEMP42:%.*]] = alloca %"__bounds_safety::wide_ptr.bidi_indexable", align 8
30-
// CHECK-O0-NEXT: [[AGG_TEMP43:%.*]] = alloca [[STRUCT_S]], align 8
3130
// CHECK-O0-NEXT: [[AGG_TEMP56:%.*]] = alloca %"__bounds_safety::wide_ptr.bidi_indexable", align 8
32-
// CHECK-O0-NEXT: [[AGG_TEMP57:%.*]] = alloca [[STRUCT_S]], align 8
3331
// CHECK-O0-NEXT: [[AGG_TEMP73:%.*]] = alloca %"__bounds_safety::wide_ptr.bidi_indexable", align 8
34-
// CHECK-O0-NEXT: [[AGG_TEMP74:%.*]] = alloca [[STRUCT_S]], align 8
3532
// CHECK-O0-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [10 x i32], ptr [[ARR]], i64 0, i64 0
3633
// CHECK-O0-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[ARRAYDECAY]], i64 10
3734
// CHECK-O0-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw %"__bounds_safety::wide_ptr.bidi_indexable", ptr [[TMP]], i32 0, i32 0
@@ -149,10 +146,9 @@ struct S {
149146
// CHECK-O0-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
150147
// CHECK-O0: for.body:
151148
// CHECK-O0-NEXT: [[TMP24:%.*]] = load i32, ptr [[I]], align 4
152-
// CHECK-O0-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TEMP43]], ptr align 8 [[S]], i64 24, i1 false)
153-
// CHECK-O0-NEXT: [[L44:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[AGG_TEMP43]], i32 0, i32 2
149+
// CHECK-O0-NEXT: [[L44:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 2
154150
// CHECK-O0-NEXT: [[TMP25:%.*]] = load i32, ptr [[L44]], align 8
155-
// CHECK-O0-NEXT: [[BP45:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[AGG_TEMP43]], i32 0, i32 0
151+
// CHECK-O0-NEXT: [[BP45:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 0
156152
// CHECK-O0-NEXT: [[TMP26:%.*]] = load ptr, ptr [[BP45]], align 8
157153
// CHECK-O0-NEXT: [[IDX_EXT:%.*]] = sext i32 [[TMP25]] to i64
158154
// CHECK-O0-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[TMP26]], i64 [[IDX_EXT]]
@@ -172,17 +168,17 @@ struct S {
172168
// CHECK-O0-NEXT: [[WIDE_PTR_LB_ADDR50:%.*]] = getelementptr inbounds nuw %"__bounds_safety::wide_ptr.bidi_indexable", ptr [[AGG_TEMP42]], i32 0, i32 2
173169
// CHECK-O0-NEXT: [[WIDE_PTR_LB51:%.*]] = load ptr, ptr [[WIDE_PTR_LB_ADDR50]], align 8
174170
// CHECK-O0-NEXT: [[TMP31:%.*]] = icmp ult ptr [[ARRAYIDX]], [[WIDE_PTR_UB49]], {{!annotation ![0-9]+}}
175-
// CHECK-O0-NEXT: br i1 [[TMP31]], label [[CONT53:%.*]], label [[TRAP52:%.*]], {{!annotation ![0-9]+}}
176-
// CHECK-O0: trap52:
171+
// CHECK-O0-NEXT: br i1 [[TMP31]], label %[[CONT53:.*]], label %[[TRAP52:.*]], {{!prof ![0-9]+}}, {{!annotation ![0-9]+}}
172+
// CHECK-O0: [[TRAP52]]:
177173
// CHECK-O0-NEXT: call void @llvm.ubsantrap(i8 25) #[[ATTR4]], {{!annotation ![0-9]+}}
178174
// CHECK-O0-NEXT: unreachable, {{!annotation ![0-9]+}}
179-
// CHECK-O0: cont53:
175+
// CHECK-O0: [[CONT53]]:
180176
// CHECK-O0-NEXT: [[TMP32:%.*]] = icmp uge ptr [[ARRAYIDX]], [[WIDE_PTR_LB51]], {{!annotation ![0-9]+}}
181-
// CHECK-O0-NEXT: br i1 [[TMP32]], label [[CONT55:%.*]], label [[TRAP54:%.*]], {{!annotation ![0-9]+}}
182-
// CHECK-O0: trap54:
177+
// CHECK-O0-NEXT: br i1 [[TMP32]], label %[[CONT55:.*]], label %[[TRAP54:.*]], {{!prof ![0-9]+}}, {{!annotation ![0-9]+}}
178+
// CHECK-O0: [[TRAP54]]:
183179
// CHECK-O0-NEXT: call void @llvm.ubsantrap(i8 25) #[[ATTR4]], {{!annotation ![0-9]+}}
184180
// CHECK-O0-NEXT: unreachable, {{!annotation ![0-9]+}}
185-
// CHECK-O0: cont55:
181+
// CHECK-O0: [[CONT55]]:
186182
// CHECK-O0-NEXT: store i32 [[TMP24]], ptr [[ARRAYIDX]], align 4
187183
// CHECK-O0-NEXT: br label [[FOR_INC:%.*]]
188184
// CHECK-O0: for.inc:
@@ -191,10 +187,9 @@ struct S {
191187
// CHECK-O0-NEXT: store i32 [[INC]], ptr [[I]], align 4
192188
// CHECK-O0-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP5:![0-9]+]]
193189
// CHECK-O0: for.end:
194-
// CHECK-O0-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TEMP57]], ptr align 8 [[S]], i64 24, i1 false)
195-
// CHECK-O0-NEXT: [[L58:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[AGG_TEMP57]], i32 0, i32 2
190+
// CHECK-O0-NEXT: [[L58:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 2
196191
// CHECK-O0-NEXT: [[TMP34:%.*]] = load i32, ptr [[L58]], align 8
197-
// CHECK-O0-NEXT: [[BP259:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[AGG_TEMP57]], i32 0, i32 1
192+
// CHECK-O0-NEXT: [[BP259:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 1
198193
// CHECK-O0-NEXT: [[TMP35:%.*]] = load ptr, ptr [[BP259]], align 8
199194
// CHECK-O0-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP34]], 1
200195
// CHECK-O0-NEXT: [[IDX_EXT60:%.*]] = sext i32 [[ADD]] to i64
@@ -213,22 +208,21 @@ struct S {
213208
// CHECK-O0-NEXT: [[WIDE_PTR_LB_ADDR67:%.*]] = getelementptr inbounds nuw %"__bounds_safety::wide_ptr.bidi_indexable", ptr [[AGG_TEMP56]], i32 0, i32 2
214209
// CHECK-O0-NEXT: [[WIDE_PTR_LB68:%.*]] = load ptr, ptr [[WIDE_PTR_LB_ADDR67]], align 8
215210
// CHECK-O0-NEXT: [[TMP39:%.*]] = icmp ult ptr [[ARRAYIDX64]], [[WIDE_PTR_UB66]], {{!annotation ![0-9]+}}
216-
// CHECK-O0-NEXT: br i1 [[TMP39]], label [[CONT70:%.*]], label [[TRAP69:%.*]], {{!annotation ![0-9]+}}
217-
// CHECK-O0: trap69:
211+
// CHECK-O0-NEXT: br i1 [[TMP39]], label %[[CONT70:.*]], label %[[TRAP69:.*]], {{!prof ![0-9]+}}, {{!annotation ![0-9]+}}
212+
// CHECK-O0: [[TRAP69]]:
218213
// CHECK-O0-NEXT: call void @llvm.ubsantrap(i8 25) #[[ATTR4]], {{!annotation ![0-9]+}}
219214
// CHECK-O0-NEXT: unreachable, {{!annotation ![0-9]+}}
220-
// CHECK-O0: cont70:
215+
// CHECK-O0: [[CONT70]]:
221216
// CHECK-O0-NEXT: [[TMP40:%.*]] = icmp uge ptr [[ARRAYIDX64]], [[WIDE_PTR_LB68]], {{!annotation ![0-9]+}}
222-
// CHECK-O0-NEXT: br i1 [[TMP40]], label [[CONT72:%.*]], label [[TRAP71:%.*]], {{!annotation ![0-9]+}}
223-
// CHECK-O0: trap71:
217+
// CHECK-O0-NEXT: br i1 [[TMP40]], label %[[CONT72:.*]], label %[[TRAP71:.*]], {{!prof ![0-9]+}}, {{!annotation ![0-9]+}}
218+
// CHECK-O0: [[TRAP71]]:
224219
// CHECK-O0-NEXT: call void @llvm.ubsantrap(i8 25) #[[ATTR4]], {{!annotation ![0-9]+}}
225220
// CHECK-O0-NEXT: unreachable, {{!annotation ![0-9]+}}
226-
// CHECK-O0: cont72:
221+
// CHECK-O0: [[CONT72]]:
227222
// CHECK-O0-NEXT: [[TMP41:%.*]] = load i32, ptr [[ARRAYIDX64]], align 4
228-
// CHECK-O0-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TEMP74]], ptr align 8 [[S]], i64 24, i1 false)
229-
// CHECK-O0-NEXT: [[L75:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[AGG_TEMP74]], i32 0, i32 2
223+
// CHECK-O0-NEXT: [[L75:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 2
230224
// CHECK-O0-NEXT: [[TMP42:%.*]] = load i32, ptr [[L75]], align 8
231-
// CHECK-O0-NEXT: [[BP76:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[AGG_TEMP74]], i32 0, i32 0
225+
// CHECK-O0-NEXT: [[BP76:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 0
232226
// CHECK-O0-NEXT: [[TMP43:%.*]] = load ptr, ptr [[BP76]], align 8
233227
// CHECK-O0-NEXT: [[IDX_EXT77:%.*]] = sext i32 [[TMP42]] to i64
234228
// CHECK-O0-NEXT: [[ADD_PTR78:%.*]] = getelementptr inbounds i32, ptr [[TMP43]], i64 [[IDX_EXT77]]
@@ -246,17 +240,17 @@ struct S {
246240
// CHECK-O0-NEXT: [[WIDE_PTR_LB_ADDR84:%.*]] = getelementptr inbounds nuw %"__bounds_safety::wide_ptr.bidi_indexable", ptr [[AGG_TEMP73]], i32 0, i32 2
247241
// CHECK-O0-NEXT: [[WIDE_PTR_LB85:%.*]] = load ptr, ptr [[WIDE_PTR_LB_ADDR84]], align 8
248242
// CHECK-O0-NEXT: [[TMP47:%.*]] = icmp ult ptr [[ARRAYIDX81]], [[WIDE_PTR_UB83]], {{!annotation ![0-9]+}}
249-
// CHECK-O0-NEXT: br i1 [[TMP47]], label [[CONT87:%.*]], label [[TRAP86:%.*]], {{!annotation ![0-9]+}}
250-
// CHECK-O0: trap86:
243+
// CHECK-O0-NEXT: br i1 [[TMP47]], label %[[CONT87:.*]], label %[[TRAP86:.*]], {{!prof ![0-9]+}}, {{!annotation ![0-9]+}}
244+
// CHECK-O0: [[TRAP86]]:
251245
// CHECK-O0-NEXT: call void @llvm.ubsantrap(i8 25) #[[ATTR4]], {{!annotation ![0-9]+}}
252246
// CHECK-O0-NEXT: unreachable, {{!annotation ![0-9]+}}
253-
// CHECK-O0: cont87:
247+
// CHECK-O0: [[CONT87]]:
254248
// CHECK-O0-NEXT: [[TMP48:%.*]] = icmp uge ptr [[ARRAYIDX81]], [[WIDE_PTR_LB85]], {{!annotation ![0-9]+}}
255-
// CHECK-O0-NEXT: br i1 [[TMP48]], label [[CONT89:%.*]], label [[TRAP88:%.*]], {{!annotation ![0-9]+}}
256-
// CHECK-O0: trap88:
249+
// CHECK-O0-NEXT: br i1 [[TMP48]], label %[[CONT89:.*]], label %[[TRAP88:.*]], {{!prof ![0-9]+}}, {{!annotation ![0-9]+}}
250+
// CHECK-O0: [[TRAP88]]:
257251
// CHECK-O0-NEXT: call void @llvm.ubsantrap(i8 25) #[[ATTR4]], {{!annotation ![0-9]+}}
258252
// CHECK-O0-NEXT: unreachable, {{!annotation ![0-9]+}}
259-
// CHECK-O0: cont89:
253+
// CHECK-O0: [[CONT89]]:
260254
// CHECK-O0-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARRAYIDX81]], align 4
261255
// CHECK-O0-NEXT: [[ADD90:%.*]] = add nsw i32 [[TMP41]], [[TMP49]]
262256
// CHECK-O0-NEXT: ret i32 [[ADD90]]

clang/test/BoundsSafety-legacy-checks/CodeGen/count-dependent-assignment-checks/dep-count-init-list-basic-O2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ void TestAccessFail() {
102102
// CHECK-NEXT: [[TMP0:%.*]] = icmp ult ptr [[ARRAYIDX]], [[UPPER]], {{!annotation ![0-9]+}}
103103
// CHECK-NEXT: [[TMP1:%.*]] = icmp uge ptr [[ARRAYIDX]], [[ARR]], {{!annotation ![0-9]+}}
104104
// CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[TMP0]], [[TMP1]], {{!annotation ![0-9]+}}
105-
// CHECK-NEXT: br i1 [[OR_COND]], label [[CONT47:%.*]], label [[TRAP:%.*]], {{!annotation ![0-9]+}}
105+
// CHECK-NEXT: br i1 [[OR_COND]], label %[[CONT47:.*]], label [[TRAP:%.*]], {{!annotation ![0-9]+}}
106106
// CHECK: trap:
107107
// CHECK-NEXT: call void @llvm.ubsantrap(i8 25) #[[ATTR5]], {{!annotation ![0-9]+}}
108108
// CHECK-NEXT: unreachable, {{!annotation ![0-9]+}}
109-
// CHECK: cont47:
109+
// CHECK: [[CONT47]]:
110110
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 36, ptr nonnull [[ARR]]) #[[ATTR6]]
111111
// CHECK-NEXT: ret void
112112
//

0 commit comments

Comments
 (0)