Skip to content

Commit af565e7

Browse files
committed
[sil-parser] Fix harmless bug when parsing ossa.
Specifically, we were preferring the always correct ownership kind specified by the FunctionType and ignoring what we parsed from the argument. This PR changes ossa to give a nice error when this is detected and fixes the places where this tests were written incorrectly.
1 parent 40c9e26 commit af565e7

18 files changed

+74
-26
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
//===--- DiagnosticsParse.def - Diagnostics Text ----------------*- C++ -*-===//
32
//
43
// This source file is part of the Swift.org open source project
@@ -485,6 +484,10 @@ ERROR(referenced_value_no_accessor,none,
485484
"referenced declaration has no %select{getter|setter}0", (unsigned))
486485
ERROR(expected_sil_value_ownership_kind,none,
487486
"expected value ownership kind in SIL code", ())
487+
ERROR(silfunc_and_silarg_have_incompatible_sil_value_ownership,none,
488+
"SILFunction and SILArgument have mismatching ValueOwnershipKinds. "
489+
"Function type specifies: '@%0'. SIL argument specifies: '@%1'.",
490+
(StringRef, StringRef))
488491
ERROR(expected_sil_colon,none,
489492
"expected ':' before %0", (StringRef))
490493
ERROR(expected_sil_tuple_index,none,

include/swift/SIL/SILValue.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ struct ValueOwnershipKind {
197197
return acc.getValue().merge(x);
198198
});
199199
}
200+
201+
StringRef asString() const;
200202
};
201203

202204
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, ValueOwnershipKind Kind);

lib/ParseSIL/ParseSIL.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,8 @@ namespace {
395395
bool parseSILOwnership(ValueOwnershipKind &OwnershipKind) {
396396
// We parse here @ <identifier>.
397397
if (!P.consumeIf(tok::at_sign)) {
398-
// If we fail, we must have @any ownership.
398+
// If we fail, we must have @any ownership. We check elsewhere in the
399+
// parser that this matches what the function signature wants.
399400
OwnershipKind = ValueOwnershipKind::Any;
400401
return false;
401402
}
@@ -5339,6 +5340,18 @@ bool SILParser::parseSILBasicBlock(SILBuilder &B) {
53395340
SILArgument *Arg;
53405341
if (IsEntry) {
53415342
Arg = BB->createFunctionArgument(Ty);
5343+
// Today, we construct the ownership kind straight from the function
5344+
// type. Make sure they are in sync, otherwise bail. We want this to
5345+
// be an exact check rather than a compatibility check since we do not
5346+
// want incompatibilities in between @any and other types of ownership
5347+
// to be ignored.
5348+
if (F->hasOwnership() && Arg->getOwnershipKind() != OwnershipKind) {
5349+
auto diagID =
5350+
diag::silfunc_and_silarg_have_incompatible_sil_value_ownership;
5351+
P.diagnose(NameLoc, diagID, Arg->getOwnershipKind().asString(),
5352+
OwnershipKind.asString());
5353+
return true;
5354+
}
53425355
} else {
53435356
Arg = BB->createPhiArgument(Ty, OwnershipKind);
53445357
}

lib/SIL/SILValue.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,22 +188,25 @@ ValueOwnershipKind::ValueOwnershipKind(const SILFunction &F, SILType Type,
188188
}
189189
}
190190

191-
llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os,
192-
ValueOwnershipKind Kind) {
193-
switch (Kind) {
191+
StringRef ValueOwnershipKind::asString() const {
192+
switch (Value) {
194193
case ValueOwnershipKind::Unowned:
195-
return os << "unowned";
194+
return "unowned";
196195
case ValueOwnershipKind::Owned:
197-
return os << "owned";
196+
return "owned";
198197
case ValueOwnershipKind::Guaranteed:
199-
return os << "guaranteed";
198+
return "guaranteed";
200199
case ValueOwnershipKind::Any:
201-
return os << "any";
200+
return "any";
202201
}
203-
204202
llvm_unreachable("Unhandled ValueOwnershipKind in switch.");
205203
}
206204

205+
llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &os,
206+
ValueOwnershipKind kind) {
207+
return os << kind.asString();
208+
}
209+
207210
Optional<ValueOwnershipKind>
208211
ValueOwnershipKind::merge(ValueOwnershipKind RHS) const {
209212
auto LHSVal = Value;

test/SIL/Parser/apply_with_conformance.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ sil @_TFV4test1S3foofS0_US_1P__FQ_T_ : $@convention(method) <T where T : P> (@in
2222
// CHECK: call
2323
// test.bar (test.S, test.X) -> ()
2424
sil [ossa] @_TF4test3barFTVS_1SVS_1X_T_ : $@convention(thin) (S, X) -> () {
25-
bb0(%0 : @unowned $S, %1 : @unowned $X):
25+
bb0(%0 : $S, %1 : $X):
2626
debug_value %0 : $S // let s // id: %2
2727
debug_value %1 : $X // let x // id: %3
2828
// function_ref test.S.foo (test.S)<A : test.P>(A) -> ()
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: not %sil-opt -verify %s
2+
3+
// Make sure that we error if ossa functions do not parse unless the argument
4+
// has the proper ownership specifier on it.
5+
6+
import Builtin
7+
8+
sil [ossa] @test1 : $@convention(thin) (@owned Builtin.NativeObject) -> () {
9+
bb0(%0 : $Builtin.NativeObject): // {{expected-error: SILFunction and SILArgument have mismatching ValueOwnershipKinds. Function type specifies: '@owned'. SIL argument specifies: '@any'.}}
10+
destroy_value %0 : $Builtin.NativeObject
11+
%9999 = tuple()
12+
return %9999 : $()
13+
}
14+
15+
sil [ossa] @test2 : $@convention(thin) (Builtin.Int32) -> () {
16+
bb0(%0 : @owned $Builtin.Int32): // {{expected-error: SILFunction and SILArgument have mismatching ValueOwnershipKinds. Function type specifies: '@any'. SIL argument specifies: '@owned'.}}
17+
%9999 = tuple()
18+
return %9999 : $()
19+
}

test/SIL/Parser/overloaded_member.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class B {
5252
}
5353

5454
sil [ossa] @test_overloaded_subscript : $@convention(thin) (@guaranteed B, B.Index) -> () {
55-
bb0(%0 : $B, %1 : $B.Index):
55+
bb0(%0 : @guaranteed $B, %1 : $B.Index):
5656
%reader = class_method %0 : $B, #B.subscript!read.1 : (B) -> (B.Index) -> (), $@convention(method) @yield_once (B.Index, @guaranteed B) -> @yields @guaranteed B.Element
5757
(%element, %token) = begin_apply %reader(%1, %0) : $@convention(method) @yield_once (B.Index, @guaranteed B) -> @yields @guaranteed B.Element
5858
end_apply %token

test/SIL/Parser/unmanaged.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ bb0(%0 : $*Optional<U>):
1616
}
1717

1818
sil [ossa] @retain_release : $@convention(thin) (@sil_unmanaged Optional<C>) -> () {
19-
bb0(%0 : @unowned $@sil_unmanaged Optional<C>):
19+
bb0(%0 : $@sil_unmanaged Optional<C>):
2020
%1 = unmanaged_to_ref %0 : $@sil_unmanaged Optional<C> to $Optional<C>
2121
unmanaged_retain_value %1 : $Optional<C>
2222
unmanaged_autorelease_value %1 : $Optional<C>
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11

2-
struct X {}
2+
sil_stage raw
3+
4+
import Builtin
5+
6+
struct X {
7+
let x: Builtin.NativeObject
8+
}
39

410
// Make sure that we can deserialize an apply with various parameter calling
511
// conventions.
612
sil [serialized] [ossa] @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X {
713
bb0(%0 : $*X, %1 : $*X, %2 : $*X, %3 : $*X, %4 : @owned $X, %5 : @unowned $X, %6 : @guaranteed $X):
14+
copy_addr [take] %1 to [initialization] %0 : $*X
15+
destroy_value %4 : $X
816
%9999 = tuple()
917
return %9999 : $()
1018
}

test/SIL/Serialization/Recovery/function.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Types
1313
// CHECK-LABEL: sil @missingParam : $@convention(thin) (SoonToBeMissing) -> () {
1414
// CHECK-RECOVERY-NEGATIVE-NOT: sil [ossa] @missingParam
1515
sil [ossa] @missingParam : $@convention(thin) (SoonToBeMissing) -> () {
16-
entry(%arg : @unowned $SoonToBeMissing):
16+
entry(%arg : $SoonToBeMissing):
1717
%9999 = tuple()
1818
return %9999 : $()
1919
}

0 commit comments

Comments
 (0)