@@ -2935,10 +2935,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
2935
2935
SILGenBorrowedBaseVisitor (SILGenLValue &SGL, SILGenFunction &SGF)
2936
2936
: SGL(SGL), SGF(SGF) {}
2937
2937
2938
- // / Returns the subexpr
2939
2938
static bool isNonCopyableBaseBorrow (SILGenFunction &SGF, Expr *e) {
2940
- if (auto *le = dyn_cast<LoadExpr>(e))
2941
- return le->getType ()->isNoncopyable ();
2942
2939
if (auto *m = dyn_cast<MemberRefExpr>(e)) {
2943
2940
// If our m is a pure noncopyable type or our base is, we need to perform
2944
2941
// a noncopyable base borrow.
@@ -2949,8 +2946,39 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
2949
2946
return m->getType ()->isNoncopyable () ||
2950
2947
m->getBase ()->getType ()->isNoncopyable ();
2951
2948
}
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
+ }
2954
2982
return false ;
2955
2983
}
2956
2984
0 commit comments