@@ -477,6 +477,29 @@ static ManagedValue emitBuiltinUnprotectedAddressOf(SILGenFunction &SGF,
477477 /* stackProtected=*/ false );
478478}
479479
480+ // Like `tryEmitAddressableParameterAsAddress`, but also handles struct element projections.
481+ static SILValue emitAddressOf (Expr *e, SILGenFunction &SGF, SILLocation loc) {
482+
483+ if (auto *memberRef = dyn_cast<MemberRefExpr>(e)) {
484+ VarDecl *fieldDecl = dyn_cast<VarDecl>(memberRef->getDecl ().getDecl ());
485+ if (!fieldDecl)
486+ return SILValue ();
487+ SILValue addr = emitAddressOf (memberRef->getBase (), SGF, loc);
488+ if (!addr)
489+ return SILValue ();
490+ if (addr->getType ().getStructOrBoundGenericStruct () != fieldDecl->getDeclContext ())
491+ return SILValue ();
492+ return SGF.B .createStructElementAddr (loc, addr, fieldDecl);
493+ }
494+
495+ if (auto addressableAddr = SGF.tryEmitAddressableParameterAsAddress (
496+ ArgumentSource (e),
497+ ValueOwnership::Shared)) {
498+ return addressableAddr.getValue ();
499+ }
500+ return SILValue ();
501+ }
502+
480503// / Specialized emitter for Builtin.addressOfBorrow.
481504static ManagedValue emitBuiltinAddressOfBorrowBuiltins (SILGenFunction &SGF,
482505 SILLocation loc,
@@ -491,15 +514,11 @@ static ManagedValue emitBuiltinAddressOfBorrowBuiltins(SILGenFunction &SGF,
491514
492515 auto argument = (*argsOrError)[0 ];
493516
494- SILValue addr;
495517 // Try to borrow the argument at +0 indirect.
496518 // If the argument is a reference to a borrowed addressable parameter, then
497519 // use that parameter's stable address.
498- if (auto addressableAddr = SGF.tryEmitAddressableParameterAsAddress (
499- ArgumentSource (argument),
500- ValueOwnership::Shared)) {
501- addr = addressableAddr.getValue ();
502- } else {
520+ SILValue addr = emitAddressOf (argument, SGF, loc);
521+ if (!addr) {
503522 // We otherwise only support the builtin applied to values that
504523 // are naturally emitted borrowed in memory. (But it would probably be good
505524 // to phase this out since it's not really well-defined how long
0 commit comments