Skip to content

Commit 262c7b2

Browse files
committed
TempRValueOpt: don't allow copy_addr [take] from a projection of the temporary.
This fixes a memory lifetime failure.
1 parent 4557f15 commit 262c7b2

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

lib/SILOptimizer/Transforms/TempRValueElimination.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@ collectLoads(Operand *addressUse, CopyAddrInst *originalCopy,
282282
LLVM_DEBUG(llvm::dbgs() << " Temp written or taken" << *user);
283283
return false;
284284
}
285+
// As with load [take], only accept copy_addr [take] if it takes the whole
286+
// temporary object.
287+
if (copyFromTmp->isTakeOfSrc() && address != originalCopy->getDest())
288+
return false;
285289
loadInsts.insert(copyFromTmp);
286290
return true;
287291
}

test/SILOptimizer/temp_rvalue_opt_ossa.sil

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ struct GS<Base> {
1616

1717
class Klass {}
1818

19+
struct Two {
20+
var a: Klass
21+
var b: Klass
22+
}
23+
1924
sil @unknown : $@convention(thin) () -> ()
2025

2126
sil [ossa] @guaranteed_user : $@convention(thin) (@guaranteed Klass) -> ()
@@ -208,6 +213,26 @@ bb0(%0 : $*Builtin.NativeObject):
208213
%v = tuple ()
209214
return %v : $()
210215
}
216+
217+
// CHECK-LABEL: sil [ossa] @dont_allow_copy_take_from_projection
218+
// CHECK: [[STK:%[0-9]+]] = alloc_stack
219+
// CHECK: copy_addr [take] %1 to [initialization] [[STK]]
220+
// CHECK: } // end sil function 'dont_allow_copy_take_from_projection'
221+
sil [ossa] @dont_allow_copy_take_from_projection : $@convention(thin) (@in Two) -> @out Two {
222+
bb0(%0 : $*Two, %1 : $*Two):
223+
%a0 = struct_element_addr %0 : $*Two, #Two.a
224+
%b0 = struct_element_addr %0 : $*Two, #Two.b
225+
%s = alloc_stack $Two
226+
copy_addr [take] %1 to [initialization] %s : $*Two
227+
%as = struct_element_addr %s : $*Two, #Two.a
228+
%bs = struct_element_addr %s : $*Two, #Two.b
229+
copy_addr [take] %as to [initialization] %a0 : $*Klass
230+
copy_addr [take] %bs to [initialization] %b0 : $*Klass
231+
dealloc_stack %s : $*Two
232+
%r = tuple ()
233+
return %r : $()
234+
}
235+
211236
// CHECK-LABEL: sil [ossa] @load_in_wrong_block
212237
// CHECK: bb0(%0 : $*GS<B>):
213238
// CHECK-NEXT: alloc_stack

0 commit comments

Comments
 (0)