Skip to content

Commit 222e33d

Browse files
authored
Merge pull request #69907 from kavon/noncopyable-statics-117082469
[SILGen] handle TypeExpr in BorrowedBaseVisitor
2 parents f6e8fd2 + 3a533b6 commit 222e33d

File tree

3 files changed

+70
-7
lines changed

3 files changed

+70
-7
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2931,9 +2931,12 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
29312931
public:
29322932
SILGenLValue &SGL;
29332933
SILGenFunction &SGF;
2934+
AbstractionPattern Orig;
29342935

2935-
SILGenBorrowedBaseVisitor(SILGenLValue &SGL, SILGenFunction &SGF)
2936-
: SGL(SGL), SGF(SGF) {}
2936+
SILGenBorrowedBaseVisitor(SILGenLValue &SGL,
2937+
SILGenFunction &SGF,
2938+
AbstractionPattern Orig)
2939+
: SGL(SGL), SGF(SGF), Orig(Orig) {}
29372940

29382941
static bool isNonCopyableBaseBorrow(SILGenFunction &SGF, Expr *e) {
29392942
if (auto *m = dyn_cast<MemberRefExpr>(e)) {
@@ -2982,9 +2985,14 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
29822985
return false;
29832986
}
29842987

2988+
/// For any other Expr's that this SILGenBorrowedBaseVisitor doesn't already
2989+
/// define a visitor stub, defer back to SILGenLValue's visitRec as it is
2990+
/// most-likely a non-lvalue root expression.
29852991
LValue visitExpr(Expr *e, SGFAccessKind accessKind, LValueOptions options) {
2986-
e->dump(llvm::errs());
2987-
llvm::report_fatal_error("Unimplemented node!");
2992+
assert(!isNonCopyableBaseBorrow(SGF, e)
2993+
&& "unexpected recursion in SILGenLValue::visitRec!");
2994+
2995+
return SGL.visitRec(e, accessKind, options, Orig);
29882996
}
29892997

29902998
LValue visitMemberRefExpr(MemberRefExpr *e, SGFAccessKind accessKind,
@@ -3074,10 +3082,10 @@ LValue SILGenLValue::visitRec(Expr *e, SGFAccessKind accessKind,
30743082
// apply the lvalue within a formal access to the original value instead of
30753083
// an actual loaded copy.
30763084
if (SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow(SGF, e)) {
3077-
SILGenBorrowedBaseVisitor visitor(*this, SGF);
3085+
SILGenBorrowedBaseVisitor visitor(*this, SGF, orig);
30783086
auto accessKind = SGFAccessKind::BorrowedObjectRead;
3079-
if (e->getType()->is<LValueType>())
3080-
accessKind = SGFAccessKind::BorrowedAddressRead;
3087+
assert(!e->getType()->is<LValueType>()
3088+
&& "maybe need SGFAccessKind::BorrowedAddressRead ?");
30813089
return visitor.visit(e, accessKind, options);
30823090
}
30833091

test/Interpreter/moveonly.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,29 @@ Tests.test("AddressOnly") {
133133
}
134134
}
135135

136+
// coverage for rdar://117082469
137+
Tests.test("global borrowing access") {
138+
class Retainable { var data = 0 }
139+
140+
struct HasStatic : ~Copyable {
141+
var x = 1
142+
var y = Retainable()
143+
144+
static let a = HasStatic()
145+
static var b = HasStatic()
146+
}
147+
148+
// test the let 'a'
149+
expectEqual(HasStatic.a.x, 1)
150+
expectEqual(HasStatic.a.y.data, 0)
151+
152+
// test the var 'b'
153+
expectEqual(HasStatic.b.x, 1)
154+
HasStatic.b.x += 10
155+
expectEqual(HasStatic.b.x, 11)
156+
157+
expectEqual(HasStatic.b.y.data, 0)
158+
HasStatic.b.y.data += 121
159+
expectEqual(HasStatic.b.y.data, 121)
160+
}
161+

test/SILGen/moveonly_basics.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-swift-emit-silgen -module-name test %s | %FileCheck %s --enable-var-scope
2+
3+
class Retainable {}
4+
5+
struct HasStatic : ~Copyable {
6+
var x = 1
7+
var y = Retainable()
8+
static let b = HasStatic()
9+
}
10+
11+
// coverage for rdar://117082469
12+
// CHECK-LABEL: sil hidden [ossa] @$s4test0A11HasStatic_1yyF : $@convention(thin) () -> () {
13+
// CHECK: [[ADDRESSOR:%.*]] = function_ref @$s4test9HasStaticV1bACvau : $@convention(thin) () -> Builtin.RawPointer
14+
// CHECK: [[PTR:%.*]] = apply [[ADDRESSOR]]() : $@convention(thin) () -> Builtin.RawPointer
15+
// CHECK: [[ADDR:%.*]] = pointer_to_address [[PTR]] : $Builtin.RawPointer to [strict] $*HasStatic
16+
// CHECK: [[MARK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[ADDR]] : $*HasStatic
17+
// CHECK: [[X_ADDR:%.*]] = struct_element_addr [[MARK]] : $*HasStatic, #HasStatic.x
18+
// CHECK: = load [trivial] [[X_ADDR]] : $*Int
19+
func testHasStatic_1() {
20+
_ = HasStatic.b.x
21+
}
22+
23+
// CHECK-LABEL: sil hidden [ossa] @$s4test0A11HasStatic_2yyF : $@convention(thin) () -> () {
24+
// CHECK: [[MARK:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] {{%.*}} : $*HasStatic
25+
// CHECK: [[Y_ADDR:%.*]] = struct_element_addr [[MARK]] : $*HasStatic, #HasStatic.y
26+
// CHECK: = load [copy] [[Y_ADDR]] : $*Retainable
27+
func testHasStatic_2() {
28+
_ = HasStatic.b.y
29+
}

0 commit comments

Comments
 (0)