mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Add SIL verification to ensure we don't return local addresses
This commit is contained in:
@@ -5359,6 +5359,17 @@ public:
|
||||
instResultType.dump(););
|
||||
requireSameType(functionResultType, instResultType,
|
||||
"return value type does not match return type of function");
|
||||
|
||||
// If the result type is an address, ensure it's base address is from a
|
||||
// function argument.
|
||||
if (F.getModule().getStage() >= SILStage::Canonical &&
|
||||
functionResultType.isAddress()) {
|
||||
auto base = getAccessBase(RI->getOperand());
|
||||
require(!base->getType().isAddress() || isa<SILFunctionArgument>(base) ||
|
||||
isa<ApplyInst>(base) &&
|
||||
cast<ApplyInst>(base)->hasAddressResult(),
|
||||
"unidentified address return");
|
||||
}
|
||||
}
|
||||
|
||||
void checkThrowInst(ThrowInst *TI) {
|
||||
|
||||
32
test/SIL/borrow_accessor_verify_errors.sil
Normal file
32
test/SIL/borrow_accessor_verify_errors.sil
Normal file
@@ -0,0 +1,32 @@
|
||||
// RUN: %target-sil-opt -dont-abort-on-memory-lifetime-errors -verify-continue-on-failure -enable-sil-verify-all=0 %s 2>&1 | %FileCheck %s
|
||||
|
||||
sil_stage canonical
|
||||
|
||||
public struct GenWrapper<T> {
|
||||
@_hasStorage var _prop: T { get set }
|
||||
public var prop: T
|
||||
}
|
||||
|
||||
sil [ossa] @borrow_addressonly_prop : $@convention(method) <T> (@in_guaranteed GenWrapper<T>) -> @guaranteed_address T {
|
||||
bb0(%0 : $*GenWrapper<T>):
|
||||
%2 = struct_element_addr %0, #GenWrapper._prop
|
||||
return %2
|
||||
}
|
||||
|
||||
// CHECK: Begin Error in function test_address_of_temp
|
||||
// CHECK: SIL verification failed: unidentified address return: !base->getType().isAddress() || isa<SILFunctionArgument>(base) || isa<ApplyInst>(base) && cast<ApplyInst>(base)->hasAddressResult()
|
||||
// CHECK: Verifying instruction:
|
||||
// CHECK: %4 = apply %3<T>(%1) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
|
||||
// CHECK: -> return %4 : $*T
|
||||
// CHECK: End Error in function test_address_of_temp
|
||||
sil [ossa] @test_address_of_temp : $@convention(thin) <T> (@in_guaranteed GenWrapper<T>) -> @guaranteed_address T {
|
||||
bb0(%0 : $*GenWrapper<T>):
|
||||
%stk = alloc_stack $GenWrapper<T>
|
||||
copy_addr %0 to [init] %stk
|
||||
%1 = function_ref @borrow_addressonly_prop : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
|
||||
%2 = apply %1<T>(%stk) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
|
||||
destroy_addr %stk
|
||||
dealloc_stack %stk
|
||||
return %2
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN:%target-swift-frontend -emit-silgen %s -verify -enable-experimental-feature BorrowAndMutateAccessors
|
||||
// RUN:%target-swift-frontend -emit-silgen %s -enable-experimental-feature BorrowAndMutateAccessors -sil-verify-none -verify
|
||||
|
||||
// REQUIRES: swift_feature_BorrowAndMutateAccessors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user