Merge pull request #85608 from kavon/opaque-values/fixes-5

OpaqueValues: fixes for distributed actors + introduce AccessControls
This commit is contained in:
Kavon Farvardin
2025-11-20 06:48:24 -08:00
committed by GitHub
15 changed files with 249 additions and 98 deletions

View File

@@ -0,0 +1,81 @@
//===--- AccessControls.h ---------------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines macros that help control access to APIs.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_ACCESSCONTROLS_H
#define SWIFT_ACCESSCONTROLS_H
/// Deprecation warnings
#if defined(__clang__) || defined(__GNUC__)
#if !defined(SWIFT_DEPRECATED)
#define SWIFT_DEPRECATED __attribute__((deprecated))
#endif
#if !defined(SWIFT_DEPRECATED_MSG)
#define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
#endif
#else
#if !defined(SWIFT_DEPRECATED)
#define SWIFT_DEPRECATED
#endif
#if !defined(SWIFT_DEPRECATED_MSG)
#define SWIFT_DEPRECATED_MSG(...)
#endif
#endif
/// Unavailable errors
#if defined(__clang__) || defined(__GNUC__)
#if !defined(SWIFT_UNAVAILABLE)
#define SWIFT_UNAVAILABLE __attribute__((unavailable))
#endif
#if !defined(SWIFT_UNAVAILABLE_MSG)
#define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
#endif
#else
#if !defined(SWIFT_UNAVAILABLE)
#define SWIFT_UNAVAILABLE
#endif
#if !defined(SWIFT_UNAVAILABLE_MSG)
#define SWIFT_UNAVAILABLE_MSG(msg)
#endif
#endif
// Access controls that are only active when included in SILGen sources.
#if defined(SWIFT_INCLUDED_IN_SILGEN_SOURCES)
// Override any prior definitions with these.
#define SWIFT_DEPRECATED_IN_SILGEN SWIFT_DEPRECATED
#define SWIFT_DEPRECATED_IN_SILGEN_MSG(...) SWIFT_DEPRECATED_MSG(__VA_ARGS__)
#define SWIFT_UNAVAILABLE_IN_SILGEN SWIFT_UNAVAILABLE
#define SWIFT_UNAVAILABLE_IN_SILGEN_MSG(MSG) SWIFT_UNAVAILABLE_MSG(MSG)
#else
#if !defined(SWIFT_DEPRECATED_IN_SILGEN)
#define SWIFT_DEPRECATED_IN_SILGEN
#endif
#if !defined(SWIFT_DEPRECATED_IN_SILGEN_MSG)
#define SWIFT_DEPRECATED_IN_SILGEN_MSG(...)
#endif
#if !defined(SWIFT_UNAVAILABLE_IN_SILGEN)
#define SWIFT_UNAVAILABLE_IN_SILGEN
#endif
#if !defined(SWIFT_UNAVAILABLE_IN_SILGEN_MSG)
#define SWIFT_UNAVAILABLE_IN_SILGEN_MSG(MSG)
#endif
#endif // SWIFT_INCLUDED_IN_SILGEN_SOURCES
#endif // SWIFT_ACCESSCONTROLS_H

View File

@@ -31,6 +31,7 @@
#define SWIFT_SIL_FUNCTIONCONVENTIONS_H #define SWIFT_SIL_FUNCTIONCONVENTIONS_H
#include "swift/AST/Types.h" #include "swift/AST/Types.h"
#include "swift/Basic/AccessControls.h"
#include "swift/SIL/SILArgumentConvention.h" #include "swift/SIL/SILArgumentConvention.h"
#include "swift/SIL/SILType.h" #include "swift/SIL/SILType.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
@@ -526,11 +527,9 @@ public:
- getNumIndirectSILErrorResults()]; - getNumIndirectSILErrorResults()];
} }
/// WARNING: Do not use this from SILGen!
/// Use methods such as `isSILIndirect` or query the ParameterInfo instead.
///
/// Return the SIL argument convention of apply/entry argument at /// Return the SIL argument convention of apply/entry argument at
/// the given argument index. /// the given argument index.
SWIFT_UNAVAILABLE_IN_SILGEN_MSG("Use methods such as `isSILIndirect` or query the ParameterInfo instead.")
SILArgumentConvention getSILArgumentConvention(unsigned index) const; SILArgumentConvention getSILArgumentConvention(unsigned index) const;
/// Return the SIL type of the apply/entry argument at the given index. /// Return the SIL type of the apply/entry argument at the given index.

View File

@@ -0,0 +1,17 @@
//
// Created by Kavon Farvardin on 11/19/25.
//
#ifndef SWIFT_SILGENUTILS_H
#define SWIFT_SILGENUTILS_H
#include "swift/SIL/SILValue.h"
namespace swift {
// Unsafe access may have invalid storage (e.g. a RawPointer).
bool isPossibleUnsafeAccessInvalidStorage(SILValue access, SILFunction *F);
} // namespace swift
#endif // SWIFT_SILGENUTILS_H

View File

@@ -15,6 +15,7 @@
#include "swift/AST/Decl.h" #include "swift/AST/Decl.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "swift/SIL/SILValue.h"
#include <optional> #include <optional>
#include <utility> #include <utility>
@@ -30,7 +31,6 @@ class SILArgument;
class SILFunction; class SILFunction;
class SILLocation; class SILLocation;
class SILType; class SILType;
class SILValue;
/// Creates a reference to the distributed actor's \p actorSystem /// Creates a reference to the distributed actor's \p actorSystem
/// stored property. /// stored property.
@@ -46,11 +46,16 @@ SILValue refDistributedActorSystem(SILBuilder &B,
/// \param actorType If non-empty, the type of the distributed actor that is /// \param actorType If non-empty, the type of the distributed actor that is
/// provided as one of the arguments. /// provided as one of the arguments.
/// \param args The arguments provided to the call, not including the base. /// \param args The arguments provided to the call, not including the base.
/// \param indirectResult If the result is known to be returned indirect,
/// this is the temporary storage for it.
/// \param tryTargets For a call that can throw, the normal and error basic /// \param tryTargets For a call that can throw, the normal and error basic
/// blocks that the call will branch to. /// blocks that the call will branch to.
void emitDistributedActorSystemWitnessCall( /// \returns If the apply result is known to be returned directly,
/// and there are no tryTargets, then the result is returned.
std::optional<SILValue> emitDistributedActorSystemWitnessCall(
SILBuilder &B, SILLocation loc, DeclName methodName, SILValue base, SILBuilder &B, SILLocation loc, DeclName methodName, SILValue base,
SILType actorType, llvm::ArrayRef<SILValue> args, SILType actorType, llvm::ArrayRef<SILValue> args,
std::optional<SILValue> indirectResult = std::nullopt,
std::optional<std::pair<SILBasicBlock *, SILBasicBlock *>> tryTargets = std::optional<std::pair<SILBasicBlock *, SILBasicBlock *>> tryTargets =
std::nullopt); std::nullopt);

View File

@@ -87,8 +87,6 @@ SILParameterInfo SILFunctionArgument::getKnownParameterInfo() const {
return getFunction()->getConventions().getParamInfoForSILArg(getIndex()); return getFunction()->getConventions().getParamInfoForSILArg(getIndex());
} }
/// WARNING: Do not use this from SILGen!
/// Use methods such as `isSILIndirect` or query the ParameterInfo instead.
SILArgumentConvention SILArgumentConvention
SILFunctionConventions::getSILArgumentConvention(unsigned index) const { SILFunctionConventions::getSILArgumentConvention(unsigned index) const {
assert(index < getNumSILArguments()); assert(index < getNumSILArguments());

View File

@@ -22,6 +22,7 @@
#include "swift/SIL/SILBridging.h" #include "swift/SIL/SILBridging.h"
#include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILModule.h" #include "swift/SIL/SILModule.h"
#include "swift/SIL/SILGenUtils.h"
#include "swift/SIL/SILUndef.h" #include "swift/SIL/SILUndef.h"
#include "swift/SIL/Test.h" #include "swift/SIL/Test.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
@@ -2485,6 +2486,12 @@ void swift::checkSwitchEnumBlockArg(SILPhiArgument *arg) {
} }
} }
bool swift::isPossibleUnsafeAccessInvalidStorage(SILValue address,
SILFunction *F) {
auto storage = AccessStorage::compute(address);
return storage && !isPossibleFormalAccessStorage(storage, F);
}
bool swift::isPossibleFormalAccessStorage(const AccessStorage &storage, bool swift::isPossibleFormalAccessStorage(const AccessStorage &storage,
SILFunction *F) { SILFunction *F) {
switch (storage.getKind()) { switch (storage.getKind()) {

View File

@@ -17,6 +17,8 @@
#ifndef SWIFT_SILGEN_CLEANUP_H #ifndef SWIFT_SILGEN_CLEANUP_H
#define SWIFT_SILGEN_CLEANUP_H #define SWIFT_SILGEN_CLEANUP_H
#define SWIFT_INCLUDED_IN_SILGEN_SOURCES
#include "swift/Basic/Assertions.h" #include "swift/Basic/Assertions.h"
#include "swift/Basic/Debug.h" #include "swift/Basic/Debug.h"
#include "swift/Basic/DiverseStack.h" #include "swift/Basic/DiverseStack.h"

View File

@@ -20,6 +20,8 @@
#ifndef SWIFT_LOWERING_MANAGEDVALUE_H #ifndef SWIFT_LOWERING_MANAGEDVALUE_H
#define SWIFT_LOWERING_MANAGEDVALUE_H #define SWIFT_LOWERING_MANAGEDVALUE_H
#define SWIFT_INCLUDED_IN_SILGEN_SOURCES
#include "Cleanup.h" #include "Cleanup.h"
#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerIntPair.h"
#include "swift/Basic/Assertions.h" #include "swift/Basic/Assertions.h"

View File

@@ -13,6 +13,8 @@
#ifndef SILGEN_H #ifndef SILGEN_H
#define SILGEN_H #define SILGEN_H
#define SWIFT_INCLUDED_IN_SILGEN_SOURCES
#include "ASTVisitor.h" #include "ASTVisitor.h"
#include "Cleanup.h" #include "Cleanup.h"
#include "swift/AST/ASTContext.h" #include "swift/AST/ASTContext.h"

View File

@@ -63,14 +63,17 @@ static void initializeProperty(SILGenFunction &SGF, SILLocation loc,
auto fieldAddr = emitActorPropertyReference(SGF, loc, actorSelf, prop); auto fieldAddr = emitActorPropertyReference(SGF, loc, actorSelf, prop);
if (loweredType.isAddressOnly(SGF.F)) { if (loweredType.isAddressOnly(SGF.F) && SGF.useLoweredAddresses()) {
SGF.B.createCopyAddr(loc, value, fieldAddr, isTake, IsInitialization); SGF.B.createCopyAddr(loc, value, fieldAddr, isTake, IsInitialization);
} else { } else {
if (value->getType().isAddress()) { if (value->getType().isAddress()) {
SGF.emitSemanticLoadInto(loc, value, SGF.F.getTypeLowering(value->getType()), SGF.emitSemanticLoadInto(loc, value, SGF.F.getTypeLowering(value->getType()),
fieldAddr, SGF.getTypeLowering(loweredType), isTake, IsInitialization); fieldAddr, SGF.getTypeLowering(loweredType), isTake, IsInitialization);
} else { } else {
value = SGF.B.emitCopyValueOperation(loc, value); // If it's not semantically a take, copy it.
if (isTake == IsNotTake)
value = SGF.B.emitCopyValueOperation(loc, value);
SGF.B.emitStoreValueOperation( SGF.B.emitStoreValueOperation(
loc, value, fieldAddr, StoreOwnershipQualifier::Init); loc, value, fieldAddr, StoreOwnershipQualifier::Init);
} }
@@ -204,20 +207,31 @@ void SILGenFunction::emitDistActorIdentityInit(ConstructorDecl *ctor,
auto selfMetatype = getLoweredType(MetatypeType::get(selfTy)); auto selfMetatype = getLoweredType(MetatypeType::get(selfTy));
SILValue selfMetatypeValue = B.createMetatype(loc, selfMetatype); SILValue selfMetatypeValue = B.createMetatype(loc, selfMetatype);
// --- create a temporary storage for the result of the call
// it will be deallocated automatically as we exit this scope
VarDecl *var = classDecl->getDistributedActorIDProperty(); VarDecl *var = classDecl->getDistributedActorIDProperty();
auto resultTy = getLoweredType(F.mapTypeIntoEnvironment(var->getInterfaceType())); if (useLoweredAddresses()) {
auto temp = emitTemporaryAllocation(loc, resultTy); // --- create a temporary storage for the result of the call
// it will be deallocated automatically as we exit this scope
auto resultTy = getLoweredType(F.mapTypeIntoEnvironment(var->getInterfaceType()));
auto temp = emitTemporaryAllocation(loc, resultTy);
// --- emit the call itself. // --- emit the call itself.
emitDistributedActorSystemWitnessCall( emitDistributedActorSystemWitnessCall(
B, loc, C.Id_assignID, B, loc, C.Id_assignID,
actorSystem, getLoweredType(selfTy), actorSystem, getLoweredType(selfTy),
{ temp, selfMetatypeValue }); { selfMetatypeValue }, temp);
// --- initialize the property. // --- initialize the property.
initializeProperty(*this, loc, borrowedSelfArg, var, temp, IsTake); initializeProperty(*this, loc, borrowedSelfArg, var, temp, IsTake);
} else {
// --- emit the call itself.
auto result = emitDistributedActorSystemWitnessCall(
B, loc, C.Id_assignID,
actorSystem, getLoweredType(selfTy),
{ selfMetatypeValue });
// --- initialize the property.
initializeProperty(*this, loc, borrowedSelfArg, var, result.value(), IsTake);
}
} }
// TODO(distributed): rename to DistributedActorID // TODO(distributed): rename to DistributedActorID
@@ -361,27 +375,6 @@ void SILGenFunction::emitDistributedActorReady(
// ==== ------------------------------------------------------------------------ // ==== ------------------------------------------------------------------------
// MARK: remote instance initialization // MARK: remote instance initialization
/// emit a call to the distributed actor system's resolve function:
///
/// \verbatim
/// system.resolve(id:as:)
/// \endverbatim
static void createDistributedActorFactory_resolve(
SILGenFunction &SGF, ASTContext &C, FuncDecl *fd, SILValue idValue,
SILValue actorSystemValue, Type selfTy, SILValue selfMetatypeValue,
SILType resultTy, SILBasicBlock *normalBB, SILBasicBlock *errorBB) {
auto &B = SGF.B;
auto loc = SILLocation(fd);
loc.markAutoGenerated();
// // ---- actually call system.resolve(id: id, as: Self.self)
emitDistributedActorSystemWitnessCall(
B, loc, C.Id_resolve, actorSystemValue, SGF.getLoweredType(selfTy),
{ idValue, selfMetatypeValue },
std::make_pair(normalBB, errorBB));
}
/// Function body of: /// Function body of:
/// \verbatim /// \verbatim
/// DistributedActor.resolve( /// DistributedActor.resolve(
@@ -435,9 +428,15 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) { // TODO(distrib
// ==== Call `try system.resolve(id: id, as: Self.self)` // ==== Call `try system.resolve(id: id, as: Self.self)`
{ {
createDistributedActorFactory_resolve( auto loc = SILLocation(fd);
*this, C, fd, idArg, actorSystemArg, selfTy, selfMetatypeValue, loc.markAutoGenerated();
optionalReturnTy, switchBB, errorBB);
// // ---- actually call system.resolve(id: id, as: Self.self)
emitDistributedActorSystemWitnessCall(
B, loc, C.Id_resolve, actorSystemArg, getLoweredType(selfTy),
{ idArg, selfMetatypeValue },
/*indirectResult=*/std::nullopt,
std::make_pair(switchBB, errorBB));
} }
// ==== switch resolved { ... } // ==== switch resolved { ... }

View File

@@ -35,7 +35,7 @@
#include "swift/Basic/Assertions.h" #include "swift/Basic/Assertions.h"
#include "swift/SIL/Consumption.h" #include "swift/SIL/Consumption.h"
#include "swift/SIL/InstructionUtils.h" #include "swift/SIL/InstructionUtils.h"
#include "swift/SIL/MemAccessUtils.h" #include "swift/SIL/SILGenUtils.h"
#include "swift/SIL/PrettyStackTrace.h" #include "swift/SIL/PrettyStackTrace.h"
#include "swift/SIL/SILArgument.h" #include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILInstruction.h"
@@ -708,9 +708,7 @@ SILValue UnenforcedAccess::beginAccess(SILGenFunction &SGF, SILLocation loc,
if (!SGF.getOptions().VerifyExclusivity) if (!SGF.getOptions().VerifyExclusivity)
return address; return address;
auto storage = AccessStorage::compute(address); if (isPossibleUnsafeAccessInvalidStorage(address, &SGF.F))
// Unsafe access may have invalid storage (e.g. a RawPointer).
if (storage && !isPossibleFormalAccessStorage(storage, &SGF.F))
return address; return address;
auto BAI = auto BAI =

View File

@@ -20,12 +20,15 @@
namespace swift { namespace swift {
void emitDistributedActorSystemWitnessCall( /// \returns the result of the call, if returned directly.
std::optional<SILValue> emitDistributedActorSystemWitnessCall(
SILBuilder &B, SILLocation loc, DeclName methodName, SILValue base, SILBuilder &B, SILLocation loc, DeclName methodName, SILValue base,
// types to be passed through to SubstitutionMap: // types to be passed through to SubstitutionMap:
SILType actorType, SILType actorType,
// call arguments, except the base which will be passed last // call arguments, except the base which will be passed last
ArrayRef<SILValue> args, ArrayRef<SILValue> args,
// pre-allocated, uninitialized indirect result storage, if needed
std::optional<SILValue> indirectResult,
std::optional<std::pair<SILBasicBlock *, SILBasicBlock *>> tryTargets) { std::optional<std::pair<SILBasicBlock *, SILBasicBlock *>> tryTargets) {
auto &F = B.getFunction(); auto &F = B.getFunction();
auto &M = B.getModule(); auto &M = B.getModule();
@@ -73,7 +76,6 @@ void emitDistributedActorSystemWitnessCall(
KnownProtocolKind::DistributedActor); KnownProtocolKind::DistributedActor);
assert(actorProto); assert(actorProto);
ProtocolConformanceRef conformance;
auto distributedActorConfRef = lookupConformance( auto distributedActorConfRef = lookupConformance(
actorType.getASTType(), actorProto); actorType.getASTType(), actorProto);
assert(!distributedActorConfRef.isInvalid() && assert(!distributedActorConfRef.isInvalid() &&
@@ -85,42 +87,61 @@ void emitDistributedActorSystemWitnessCall(
subs = SubstitutionMap::get(genericSig, subTypes, subConformances); subs = SubstitutionMap::get(genericSig, subTypes, subConformances);
} }
std::optional<SILValue> temporaryArgumentBuffer;
// If the self parameter is indirect but the base is a value, put it
// into a temporary allocation.
auto methodSILFnTy = methodSILTy.castTo<SILFunctionType>(); auto methodSILFnTy = methodSILTy.castTo<SILFunctionType>();
std::optional<SILValue> temporaryActorSystemBuffer; SILFunctionConventions conv(methodSILFnTy, M);
if (methodSILFnTy->getSelfParameter().isFormalIndirect() &&
!base->getType().isAddress()) { // Since this code lives outside of SILGen, manage our clean-ups manually.
auto buf = B.createAllocStack(loc, base->getType(), std::nullopt); SmallVector<SILInstruction *, 2> cleanups;
base = B.emitCopyValueOperation(loc, base);
B.emitStoreValueOperation( auto prepareArgument = [&](SILParameterInfo param, SILValue arg) -> SILValue {
loc, base, buf, StoreOwnershipQualifier::Init); if (conv.isSILIndirect(param)) {
temporaryActorSystemBuffer = SILValue(buf); // Does it need temporary stack storage?
} if (!arg->getType().isAddress() &&
!dyn_cast<AnyMetatypeType>(arg->getType().getASTType())) {
auto buf = B.createAllocStack(loc, arg->getType(), std::nullopt);
cleanups.push_back(buf);
auto copy = B.emitCopyValueOperation(loc, arg);
B.emitStoreValueOperation(
loc, copy, buf, StoreOwnershipQualifier::Init);
return buf;
}
return arg; // no temporary storage needed
}
// Otherwise, it's a direct convention. Borrow if needed.
if (arg->getType().isAddress()) {
arg = B.emitLoadBorrowOperation(loc, arg);
cleanups.push_back(arg.getDefiningInstruction());
}
return arg;
};
SILValue selfArg = prepareArgument(methodSILFnTy->getSelfParameter(), base);
// === Call the method. // === Call the method.
// --- Push the arguments // --- Push the arguments
SmallVector<SILValue, 2> allArgs; SmallVector<SILValue, 2> allArgs;
const bool hasIndirectResult = conv.getNumIndirectSILResults() > 0;
ASSERT(hasIndirectResult == indirectResult.has_value() && "no indirectResult storage given!");
ASSERT(conv.getNumIndirectSILResults() <= 1);
const bool hasDirectResult = conv.getNumDirectSILResults() > 0;
ASSERT(!(hasIndirectResult && hasDirectResult) && "indirect AND direct results aren't supported");
ASSERT(conv.getNumDirectSILResults() <= 1);
if (hasIndirectResult) {
allArgs.push_back(*indirectResult);
}
auto params = methodSILFnTy->getParameters(); auto params = methodSILFnTy->getParameters();
for (size_t i = 0; i < args.size(); ++i) { for (size_t i = 0; i < args.size(); ++i) {
auto arg = args[i]; allArgs.push_back(prepareArgument(params[i], args[i]));
if (params[i].isFormalIndirect() &&
!arg->getType().isAddress() &&
!dyn_cast<AnyMetatypeType>(arg->getType().getASTType())) {
auto buf = B.createAllocStack(loc, arg->getType(), std::nullopt);
auto argCopy = B.emitCopyValueOperation(loc, arg);
B.emitStoreValueOperation(
loc, argCopy, buf, StoreOwnershipQualifier::Init);
temporaryArgumentBuffer = SILValue(buf);
allArgs.push_back(*temporaryArgumentBuffer);
} else {
allArgs.push_back(arg);
}
} }
// Push the self argument // Push the self argument
auto selfArg = temporaryActorSystemBuffer ? *temporaryActorSystemBuffer : base;
allArgs.push_back(selfArg); allArgs.push_back(selfArg);
SILInstruction *apply; SILInstruction *apply;
@@ -132,7 +153,7 @@ void emitDistributedActorSystemWitnessCall(
apply = B.createApply(loc, witnessMethod, subs, allArgs); apply = B.createApply(loc, witnessMethod, subs, allArgs);
} }
// Local function to emit a cleanup after the call. // Local function to emit cleanups after the call in successor blocks.
auto emitCleanup = [&](llvm::function_ref<void(SILBuilder &builder)> fn) { auto emitCleanup = [&](llvm::function_ref<void(SILBuilder &builder)> fn) {
if (tryTargets) { if (tryTargets) {
{ {
@@ -148,25 +169,45 @@ void emitDistributedActorSystemWitnessCall(
} }
}; };
// ==== If we had to create a buffers we need to clean them up // Emit clean-ups in reverse order, to preserve stack nesting, etc.
// --- Cleanup id buffer for (auto inst : reverse(cleanups)) {
if (temporaryArgumentBuffer) { if (auto asi = dyn_cast<AllocStackInst>(inst)) {
emitCleanup([&](SILBuilder & builder) { auto buf = asi->getResult(0);
auto value = builder.emitLoadValueOperation( emitCleanup([&](SILBuilder & builder) {
loc, *temporaryArgumentBuffer, LoadOwnershipQualifier::Take); // FIXME: could do destroy_addr rather than take + destroy_value
builder.emitDestroyValueOperation(loc, value); auto value = builder.emitLoadValueOperation(
builder.createDeallocStack(loc, *temporaryArgumentBuffer); loc, buf, LoadOwnershipQualifier::Take);
}); builder.emitDestroyValueOperation(loc, value);
builder.createDeallocStack(loc, buf);
});
continue;
}
if (auto lb = dyn_cast<LoadBorrowInst>(inst)) {
auto borrow = lb->getResult(0);
emitCleanup([&](SILBuilder & builder) {
builder.emitEndBorrowOperation(loc, borrow);
});
continue;
}
if (isa<LoadInst>(inst)) {
// no clean-ups required
continue;
}
llvm_unreachable("unknown instruction kind to clean-up!");
} }
// --- Cleanup base buffer
if (temporaryActorSystemBuffer) { // If this was a try_apply, then the result is the BB argument of the
emitCleanup([&](SILBuilder & builder) { // successor block. We let our caller figure that out themselves.
auto value = builder.emitLoadValueOperation( //
loc, *temporaryActorSystemBuffer, LoadOwnershipQualifier::Take); // Otherwise, the apply had a single direct result, so we return that.
builder.emitDestroyValueOperation(loc, value); if (hasDirectResult && !tryTargets) {
builder.createDeallocStack(loc, *temporaryActorSystemBuffer); return apply->getResult(0);
});
} }
return std::nullopt;
} }
void emitActorReadyCall(SILBuilder &B, SILLocation loc, SILValue actor, void emitActorReadyCall(SILBuilder &B, SILLocation loc, SILValue actor,

View File

@@ -1,4 +1,5 @@
// RUN: %target-run-simple-swift( -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s // RUN: %target-run-simple-swift( -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s
// RUN: %target-run-simple-swift(-Xfrontend -enable-sil-opaque-values -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s
// REQUIRES: executable_test // REQUIRES: executable_test
// REQUIRES: concurrency // REQUIRES: concurrency

View File

@@ -1,4 +1,5 @@
// RUN: %target-run-simple-swift( -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s // RUN: %target-run-simple-swift( -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s
// RUN: %target-run-simple-swift(-Xfrontend -enable-sil-opaque-values -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s
// REQUIRES: executable_test // REQUIRES: executable_test
// REQUIRES: concurrency // REQUIRES: concurrency
@@ -9,9 +10,6 @@
// UNSUPPORTED: back_deployment_runtime // UNSUPPORTED: back_deployment_runtime
// FIXME(distributed): Seems something remains incorrect here
// REQUIRES: rdar92952551
import Distributed import Distributed
enum MyError: Error { enum MyError: Error {

View File

@@ -1,4 +1,5 @@
// RUN: %target-run-simple-swift(-target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s // RUN: %target-run-simple-swift(-target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s
// RUN: %target-run-simple-swift(-Xfrontend -enable-sil-opaque-values -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s
// REQUIRES: executable_test // REQUIRES: executable_test
// REQUIRES: concurrency // REQUIRES: concurrency