Add SIL verification to ensure we don't return local addresses

This commit is contained in:
Meghana Gupta
2025-11-05 12:42:23 -08:00
parent 32cd86f719
commit 778ad0dfb5
3 changed files with 44 additions and 1 deletions

View File

@@ -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) {

View 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
}

View File

@@ -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