Skip to content

Commit 297a5b3

Browse files
committed
Add SIL verification to ensure we don't return local addresses
1 parent e5c43ab commit 297a5b3

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5344,6 +5344,17 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
53445344
instResultType.dump(););
53455345
requireSameType(functionResultType, instResultType,
53465346
"return value type does not match return type of function");
5347+
5348+
// If the result type is an address, ensure it's base address is from a
5349+
// function argument.
5350+
if (F.getModule().getStage() >= SILStage::Canonical &&
5351+
functionResultType.isAddress()) {
5352+
auto base = getAccessBase(RI->getOperand());
5353+
require(!base->getType().isAddress() || isa<SILFunctionArgument>(base) ||
5354+
isa<ApplyInst>(base) &&
5355+
cast<ApplyInst>(base)->hasAddressResult(),
5356+
"unidentified address return");
5357+
}
53475358
}
53485359

53495360
void checkThrowInst(ThrowInst *TI) {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %target-sil-opt -dont-abort-on-memory-lifetime-errors -verify-continue-on-failure -enable-sil-verify-all=0 %s 2>&1 | %FileCheck %s
2+
3+
sil_stage canonical
4+
5+
public struct GenWrapper<T> {
6+
@_hasStorage var _prop: T { get set }
7+
public var prop: T
8+
}
9+
10+
sil [ossa] @borrow_addressonly_prop : $@convention(method) <T> (@in_guaranteed GenWrapper<T>) -> @guaranteed_address T {
11+
bb0(%0 : $*GenWrapper<T>):
12+
%2 = struct_element_addr %0, #GenWrapper._prop
13+
return %2
14+
}
15+
16+
// CHECK: Begin Error in function test_address_of_temp
17+
// CHECK: SIL verification failed: unidentified address return: !base->getType().isAddress() || isa<SILFunctionArgument>(base) || isa<ApplyInst>(base) && cast<ApplyInst>(base)->hasAddressResult()
18+
// CHECK: Verifying instruction:
19+
// CHECK: %4 = apply %3<T>(%1) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
20+
// CHECK: -> return %4 : $*T
21+
// CHECK: End Error in function test_address_of_temp
22+
sil [ossa] @test_address_of_temp : $@convention(thin) <T> (@in_guaranteed GenWrapper<T>) -> @guaranteed_address T {
23+
bb0(%0 : $*GenWrapper<T>):
24+
%stk = alloc_stack $GenWrapper<T>
25+
copy_addr %0 to [init] %stk
26+
%1 = function_ref @borrow_addressonly_prop : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
27+
%2 = apply %1<T>(%stk) : $@convention(method) <τ_0_0> (@in_guaranteed GenWrapper<τ_0_0>) -> @guaranteed_address τ_0_0
28+
destroy_addr %stk
29+
dealloc_stack %stk
30+
return %2
31+
}
32+

test/SILGen/borrow_accessor_failues.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN:%target-swift-frontend -emit-silgen %s -verify -enable-experimental-feature BorrowAndMutateAccessors
1+
// RUN:%target-swift-frontend -emit-silgen %s -enable-experimental-feature BorrowAndMutateAccessors -sil-verify-none -verify
22

33
// REQUIRES: swift_feature_BorrowAndMutateAccessors
44

0 commit comments

Comments
 (0)