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