@@ -3064,23 +3064,33 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
3064
3064
forGuaranteedReturn (forGuaranteedReturn),
3065
3065
forGuaranteedAddressReturn(forGuaranteedAddressReturn) {}
3066
3066
3067
- static bool isNonCopyableBaseBorrow (SILGenFunction &SGF, Expr *e) {
3067
+ static bool isNonCopyableBaseBorrow (SILGenFunction &SGF, Expr *e,
3068
+ LValueOptions options) {
3068
3069
if (auto *m = dyn_cast<MemberRefExpr>(e)) {
3069
3070
// If our m is a pure noncopyable type or our base is, we need to perform
3070
3071
// a noncopyable base borrow.
3071
3072
//
3072
3073
// DISCUSSION: We can have a noncopyable member_ref_expr with a copyable
3073
3074
// base if the noncopyable member_ref_expr is from a computed method. In
3074
3075
// such a case, we want to ensure that we wrap things the right way.
3075
- return m->getType ()->isNoncopyable () ||
3076
- m->getBase ()->getType ()->isNoncopyable ();
3076
+ if (m->getType ()->isNoncopyable () ||
3077
+ m->getBase ()->getType ()->isNoncopyable ()) {
3078
+ return true ;
3079
+ }
3080
+
3081
+ if (options.ForGuaranteedAddressReturn || options.ForGuaranteedReturn ) {
3082
+ return true ;
3083
+ }
3077
3084
}
3078
3085
3079
3086
if (auto *le = dyn_cast<LoadExpr>(e)) {
3080
3087
// Noncopyable type is obviously noncopyable.
3081
3088
if (le->getType ()->isNoncopyable ()) {
3082
3089
return true ;
3083
3090
}
3091
+ if (options.ForGuaranteedAddressReturn || options.ForGuaranteedReturn ) {
3092
+ return true ;
3093
+ }
3084
3094
// Otherwise, check if the thing we're loading from is a noncopyable
3085
3095
// param decl.
3086
3096
e = le->getSubExpr ();
@@ -3092,6 +3102,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
3092
3102
if (de->getType ()->isNoncopyable ()) {
3093
3103
return true ;
3094
3104
}
3105
+ if (options.ForGuaranteedAddressReturn || options.ForGuaranteedReturn ) {
3106
+ return true ;
3107
+ }
3095
3108
// If the decl ref refers to a parameter with an explicit ownership
3096
3109
// modifier, it is not implicitly copyable.
3097
3110
if (auto pd = dyn_cast<ParamDecl>(de->getDecl ())) {
@@ -3115,7 +3128,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
3115
3128
// / define a visitor stub, defer back to SILGenLValue's visitRec as it is
3116
3129
// / most-likely a non-lvalue root expression.
3117
3130
LValue visitExpr (Expr *e, SGFAccessKind accessKind, LValueOptions options) {
3118
- assert (!isNonCopyableBaseBorrow (SGF, e)
3131
+ assert (!isNonCopyableBaseBorrow (SGF, e, options )
3119
3132
&& " unexpected recursion in SILGenLValue::visitRec!" );
3120
3133
3121
3134
return SGL.visitRec (e, accessKind, options, Orig);
@@ -3172,8 +3185,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
3172
3185
ManagedValue mv =
3173
3186
SGF.emitRValueAsSingleValue (e, SGFContext::AllowImmediatePlusZero);
3174
3187
3175
- if (forGuaranteedReturn && mv.getValue ()->getType ().isMoveOnly () &&
3176
- !mv.getValue ()->getType ().isAddress ()) {
3188
+ if (forGuaranteedReturn && mv.getValue ()->getType ().isMoveOnly ()) {
3177
3189
// SILGen eagerly generates copy_value +
3178
3190
// mark_unresolved_non_copyable_value for ~Copyable base values. The
3179
3191
// generated mark_unresolved_non_copyable_value instructions drive
@@ -3286,11 +3298,14 @@ LValue SILGenLValue::visitRec(Expr *e, SGFAccessKind accessKind,
3286
3298
// a `borrow x` operator, the operator is used on the base here), we want to
3287
3299
// apply the lvalue within a formal access to the original value instead of
3288
3300
// an actual loaded copy.
3289
- if (SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow (SGF, e) ||
3290
- options.ForGuaranteedReturn ) {
3301
+ if (SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow (SGF, e, options)) {
3291
3302
SILGenBorrowedBaseVisitor visitor (*this , SGF, orig,
3292
- options.ForGuaranteedReturn );
3303
+ options.ForGuaranteedReturn ,
3304
+ options.ForGuaranteedAddressReturn );
3293
3305
auto accessKind = SGFAccessKind::BorrowedObjectRead;
3306
+ if (options.ForGuaranteedAddressReturn ) {
3307
+ accessKind = SGFAccessKind::BorrowedAddressRead;
3308
+ }
3294
3309
assert (!e->getType ()->is <LValueType>()
3295
3310
&& " maybe need SGFAccessKind::BorrowedAddressRead ?" );
3296
3311
return visitor.visit (e, accessKind, options);
0 commit comments