@@ -3064,23 +3064,33 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
30643064 forGuaranteedReturn (forGuaranteedReturn),
30653065 forGuaranteedAddressReturn(forGuaranteedAddressReturn) {}
30663066
3067- static bool isNonCopyableBaseBorrow (SILGenFunction &SGF, Expr *e) {
3067+ static bool isNonCopyableBaseBorrow (SILGenFunction &SGF, Expr *e,
3068+ LValueOptions options) {
30683069 if (auto *m = dyn_cast<MemberRefExpr>(e)) {
30693070 // If our m is a pure noncopyable type or our base is, we need to perform
30703071 // a noncopyable base borrow.
30713072 //
30723073 // DISCUSSION: We can have a noncopyable member_ref_expr with a copyable
30733074 // base if the noncopyable member_ref_expr is from a computed method. In
30743075 // 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+ }
30773084 }
30783085
30793086 if (auto *le = dyn_cast<LoadExpr>(e)) {
30803087 // Noncopyable type is obviously noncopyable.
30813088 if (le->getType ()->isNoncopyable ()) {
30823089 return true ;
30833090 }
3091+ if (options.ForGuaranteedAddressReturn || options.ForGuaranteedReturn ) {
3092+ return true ;
3093+ }
30843094 // Otherwise, check if the thing we're loading from is a noncopyable
30853095 // param decl.
30863096 e = le->getSubExpr ();
@@ -3092,6 +3102,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
30923102 if (de->getType ()->isNoncopyable ()) {
30933103 return true ;
30943104 }
3105+ if (options.ForGuaranteedAddressReturn || options.ForGuaranteedReturn ) {
3106+ return true ;
3107+ }
30953108 // If the decl ref refers to a parameter with an explicit ownership
30963109 // modifier, it is not implicitly copyable.
30973110 if (auto pd = dyn_cast<ParamDecl>(de->getDecl ())) {
@@ -3115,7 +3128,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
31153128 // / define a visitor stub, defer back to SILGenLValue's visitRec as it is
31163129 // / most-likely a non-lvalue root expression.
31173130 LValue visitExpr (Expr *e, SGFAccessKind accessKind, LValueOptions options) {
3118- assert (!isNonCopyableBaseBorrow (SGF, e)
3131+ assert (!isNonCopyableBaseBorrow (SGF, e, options )
31193132 && " unexpected recursion in SILGenLValue::visitRec!" );
31203133
31213134 return SGL.visitRec (e, accessKind, options, Orig);
@@ -3172,8 +3185,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
31723185 ManagedValue mv =
31733186 SGF.emitRValueAsSingleValue (e, SGFContext::AllowImmediatePlusZero);
31743187
3175- if (forGuaranteedReturn && mv.getValue ()->getType ().isMoveOnly () &&
3176- !mv.getValue ()->getType ().isAddress ()) {
3188+ if (forGuaranteedReturn && mv.getValue ()->getType ().isMoveOnly ()) {
31773189 // SILGen eagerly generates copy_value +
31783190 // mark_unresolved_non_copyable_value for ~Copyable base values. The
31793191 // generated mark_unresolved_non_copyable_value instructions drive
@@ -3286,11 +3298,14 @@ LValue SILGenLValue::visitRec(Expr *e, SGFAccessKind accessKind,
32863298 // a `borrow x` operator, the operator is used on the base here), we want to
32873299 // apply the lvalue within a formal access to the original value instead of
32883300 // an actual loaded copy.
3289- if (SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow (SGF, e) ||
3290- options.ForGuaranteedReturn ) {
3301+ if (SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow (SGF, e, options)) {
32913302 SILGenBorrowedBaseVisitor visitor (*this , SGF, orig,
3292- options.ForGuaranteedReturn );
3303+ options.ForGuaranteedReturn ,
3304+ options.ForGuaranteedAddressReturn );
32933305 auto accessKind = SGFAccessKind::BorrowedObjectRead;
3306+ if (options.ForGuaranteedAddressReturn ) {
3307+ accessKind = SGFAccessKind::BorrowedAddressRead;
3308+ }
32943309 assert (!e->getType ()->is <LValueType>()
32953310 && " maybe need SGFAccessKind::BorrowedAddressRead ?" );
32963311 return visitor.visit (e, accessKind, options);
0 commit comments