@@ -2266,12 +2266,41 @@ SILGenFunction::enterLocalVariableAddressableBufferScope(VarDecl *decl,
2266
2266
Cleanups.pushCleanup <DeallocateLocalVariableAddressableBuffer>(decl, destroyCleanup);
2267
2267
}
2268
2268
2269
+ static bool isFullyAbstractedLowering (SILGenFunction &SGF,
2270
+ Type formalType, SILType loweredType) {
2271
+ return SGF.getLoweredType (AbstractionPattern::getOpaque (), formalType)
2272
+ .getASTType ()
2273
+ == loweredType.getASTType ();
2274
+ }
2275
+
2276
+ static bool isNaturallyFullyAbstractedType (SILGenFunction &SGF,
2277
+ Type formalType) {
2278
+ return isFullyAbstractedLowering (SGF, formalType, SGF.getLoweredType (formalType));
2279
+ }
2280
+
2269
2281
SILValue
2270
- SILGenFunction::getLocalVariableAddressableBuffer (VarDecl *decl,
2271
- SILLocation curLoc,
2272
- ValueOwnership ownership) {
2282
+ SILGenFunction::getVariableAddressableBuffer (VarDecl *decl,
2283
+ SILLocation curLoc,
2284
+ ValueOwnership ownership) {
2285
+ // For locals, we might be able to retroactively produce a local addressable
2286
+ // representation.
2273
2287
auto foundVarLoc = VarLocs.find (decl);
2274
2288
if (foundVarLoc == VarLocs.end ()) {
2289
+ // If it's not local, is it at least a global stored variable?
2290
+ if (decl->isGlobalStorage ()) {
2291
+ // Is the global immutable?
2292
+ if (!decl->isLet ()) {
2293
+ return SILValue ();
2294
+ }
2295
+
2296
+ // Does the storage naturally have a fully abstracted representation?
2297
+ if (!isNaturallyFullyAbstractedType (*this , decl->getTypeInContext ())) {
2298
+ return SILValue ();
2299
+ }
2300
+
2301
+ // We can get the stable address via the addressor.
2302
+ return emitGlobalVariableRef (curLoc, decl, std::nullopt ).getUnmanagedValue ();
2303
+ }
2275
2304
return SILValue ();
2276
2305
}
2277
2306
@@ -2285,7 +2314,8 @@ SILGenFunction::getLocalVariableAddressableBuffer(VarDecl *decl,
2285
2314
// Check whether the bound value is inherently suitable for addressability.
2286
2315
// It must already be in memory and fully abstracted.
2287
2316
if (value->getType ().isAddress ()
2288
- && fullyAbstractedTy.getASTType () == value->getType ().getASTType ()) {
2317
+ && isFullyAbstractedLowering (*this , decl->getTypeInContext ()->getRValueType (),
2318
+ value->getType ())) {
2289
2319
SILValue address = value;
2290
2320
// Begin an access if the address is mutable.
2291
2321
if (access != SILAccessEnforcement::Unknown) {
0 commit comments