Skip to content

Commit 1b5796c

Browse files
committed
SILGen: Treat projections from non-implicitly-copyable parameters as borrow bases.
1 parent 1dcf271 commit 1b5796c

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2935,10 +2935,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
29352935
SILGenBorrowedBaseVisitor(SILGenLValue &SGL, SILGenFunction &SGF)
29362936
: SGL(SGL), SGF(SGF) {}
29372937

2938-
/// Returns the subexpr
29392938
static bool isNonCopyableBaseBorrow(SILGenFunction &SGF, Expr *e) {
2940-
if (auto *le = dyn_cast<LoadExpr>(e))
2941-
return le->getType()->isNoncopyable();
29422939
if (auto *m = dyn_cast<MemberRefExpr>(e)) {
29432940
// If our m is a pure noncopyable type or our base is, we need to perform
29442941
// a noncopyable base borrow.
@@ -2949,8 +2946,39 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
29492946
return m->getType()->isNoncopyable() ||
29502947
m->getBase()->getType()->isNoncopyable();
29512948
}
2952-
if (auto *d = dyn_cast<DeclRefExpr>(e))
2953-
return e->getType()->isNoncopyable();
2949+
2950+
if (auto *le = dyn_cast<LoadExpr>(e)) {
2951+
// Noncopyable type is obviously noncopyable.
2952+
if (le->getType()->isNoncopyable()) {
2953+
return true;
2954+
}
2955+
// Otherwise, check if the thing we're loading from is a noncopyable
2956+
// param decl.
2957+
e = le->getSubExpr();
2958+
// fall through...
2959+
}
2960+
2961+
if (auto *de = dyn_cast<DeclRefExpr>(e)) {
2962+
// Noncopyable type is obviously noncopyable.
2963+
if (de->getType()->isNoncopyable()) {
2964+
return true;
2965+
}
2966+
// If the decl ref refers to a parameter with an explicit ownership
2967+
// modifier, it is not implicitly copyable.
2968+
if (auto pd = dyn_cast<ParamDecl>(de->getDecl())) {
2969+
switch (pd->getSpecifier()) {
2970+
case ParamSpecifier::Borrowing:
2971+
case ParamSpecifier::Consuming:
2972+
return true;
2973+
case ParamSpecifier::Default:
2974+
case ParamSpecifier::InOut:
2975+
case ParamSpecifier::LegacyShared:
2976+
case ParamSpecifier::LegacyOwned:
2977+
return false;
2978+
}
2979+
llvm_unreachable("unhandled switch case");
2980+
}
2981+
}
29542982
return false;
29552983
}
29562984

0 commit comments

Comments
 (0)