Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions include/swift/Basic/AccessControls.h
Original file line number Diff line number Diff line change
@@ -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
5 changes: 2 additions & 3 deletions include/swift/SIL/SILFunctionConventions.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#define SWIFT_SIL_FUNCTIONCONVENTIONS_H

#include "swift/AST/Types.h"
#include "swift/Basic/AccessControls.h"
#include "swift/SIL/SILArgumentConvention.h"
#include "swift/SIL/SILType.h"
#include "llvm/Support/ErrorHandling.h"
Expand Down Expand Up @@ -526,11 +527,9 @@ class SILFunctionConventions {
- 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
/// the given argument index.
SWIFT_UNAVAILABLE_IN_SILGEN_MSG("Use methods such as `isSILIndirect` or query the ParameterInfo instead.")
SILArgumentConvention getSILArgumentConvention(unsigned index) const;

/// Return the SIL type of the apply/entry argument at the given index.
Expand Down
17 changes: 17 additions & 0 deletions include/swift/SIL/SILGenUtils.h
Original file line number Diff line number Diff line change
@@ -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
9 changes: 7 additions & 2 deletions include/swift/SILOptimizer/Utils/DistributedActor.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "swift/AST/Decl.h"
#include "llvm/ADT/ArrayRef.h"
#include "swift/SIL/SILValue.h"
#include <optional>
#include <utility>

Expand All @@ -30,7 +31,6 @@ class SILArgument;
class SILFunction;
class SILLocation;
class SILType;
class SILValue;

/// Creates a reference to the distributed actor's \p actorSystem
/// stored property.
Expand All @@ -46,11 +46,16 @@ SILValue refDistributedActorSystem(SILBuilder &B,
/// \param actorType If non-empty, the type of the distributed actor that is
/// provided as one of the arguments.
/// \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
/// 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,
SILType actorType, llvm::ArrayRef<SILValue> args,
std::optional<SILValue> indirectResult = std::nullopt,
std::optional<std::pair<SILBasicBlock *, SILBasicBlock *>> tryTargets =
std::nullopt);

Expand Down
2 changes: 0 additions & 2 deletions lib/SIL/IR/SILArgument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ SILParameterInfo SILFunctionArgument::getKnownParameterInfo() const {
return getFunction()->getConventions().getParamInfoForSILArg(getIndex());
}

/// WARNING: Do not use this from SILGen!
/// Use methods such as `isSILIndirect` or query the ParameterInfo instead.
SILArgumentConvention
SILFunctionConventions::getSILArgumentConvention(unsigned index) const {
assert(index < getNumSILArguments());
Expand Down
7 changes: 7 additions & 0 deletions lib/SIL/Utils/MemAccessUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "swift/SIL/SILBridging.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILGenUtils.h"
#include "swift/SIL/SILUndef.h"
#include "swift/SIL/Test.h"
#include "llvm/Support/Debug.h"
Expand Down Expand Up @@ -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,
SILFunction *F) {
switch (storage.getKind()) {
Expand Down
2 changes: 2 additions & 0 deletions lib/SILGen/Cleanup.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#ifndef SWIFT_SILGEN_CLEANUP_H
#define SWIFT_SILGEN_CLEANUP_H

#define SWIFT_INCLUDED_IN_SILGEN_SOURCES

#include "swift/Basic/Assertions.h"
#include "swift/Basic/Debug.h"
#include "swift/Basic/DiverseStack.h"
Expand Down
2 changes: 2 additions & 0 deletions lib/SILGen/ManagedValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#ifndef SWIFT_LOWERING_MANAGEDVALUE_H
#define SWIFT_LOWERING_MANAGEDVALUE_H

#define SWIFT_INCLUDED_IN_SILGEN_SOURCES

#include "Cleanup.h"
#include "llvm/ADT/PointerIntPair.h"
#include "swift/Basic/Assertions.h"
Expand Down
2 changes: 2 additions & 0 deletions lib/SILGen/SILGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#ifndef SILGEN_H
#define SILGEN_H

#define SWIFT_INCLUDED_IN_SILGEN_SOURCES

#include "ASTVisitor.h"
#include "Cleanup.h"
#include "swift/AST/ASTContext.h"
Expand Down
77 changes: 38 additions & 39 deletions lib/SILGen/SILGenDistributed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,17 @@ static void initializeProperty(SILGenFunction &SGF, SILLocation loc,

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);
} else {
if (value->getType().isAddress()) {
SGF.emitSemanticLoadInto(loc, value, SGF.F.getTypeLowering(value->getType()),
fieldAddr, SGF.getTypeLowering(loweredType), isTake, IsInitialization);
} 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(
loc, value, fieldAddr, StoreOwnershipQualifier::Init);
}
Expand Down Expand Up @@ -204,20 +207,31 @@ void SILGenFunction::emitDistActorIdentityInit(ConstructorDecl *ctor,
auto selfMetatype = getLoweredType(MetatypeType::get(selfTy));
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();
auto resultTy = getLoweredType(F.mapTypeIntoEnvironment(var->getInterfaceType()));
auto temp = emitTemporaryAllocation(loc, resultTy);

// --- emit the call itself.
emitDistributedActorSystemWitnessCall(
B, loc, C.Id_assignID,
actorSystem, getLoweredType(selfTy),
{ temp, selfMetatypeValue });

// --- initialize the property.
initializeProperty(*this, loc, borrowedSelfArg, var, temp, IsTake);
if (useLoweredAddresses()) {
// --- 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.
emitDistributedActorSystemWitnessCall(
B, loc, C.Id_assignID,
actorSystem, getLoweredType(selfTy),
{ selfMetatypeValue }, temp);

// --- initialize the property.
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
Expand Down Expand Up @@ -361,27 +375,6 @@ void SILGenFunction::emitDistributedActorReady(
// ==== ------------------------------------------------------------------------
// 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:
/// \verbatim
/// DistributedActor.resolve(
Expand Down Expand Up @@ -435,9 +428,15 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) { // TODO(distrib

// ==== Call `try system.resolve(id: id, as: Self.self)`
{
createDistributedActorFactory_resolve(
*this, C, fd, idArg, actorSystemArg, selfTy, selfMetatypeValue,
optionalReturnTy, switchBB, errorBB);
auto loc = SILLocation(fd);
loc.markAutoGenerated();

// // ---- 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 { ... }
Expand Down
6 changes: 2 additions & 4 deletions lib/SILGen/SILGenLValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include "swift/Basic/Assertions.h"
#include "swift/SIL/Consumption.h"
#include "swift/SIL/InstructionUtils.h"
#include "swift/SIL/MemAccessUtils.h"
#include "swift/SIL/SILGenUtils.h"
#include "swift/SIL/PrettyStackTrace.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILInstruction.h"
Expand Down Expand Up @@ -708,9 +708,7 @@ SILValue UnenforcedAccess::beginAccess(SILGenFunction &SGF, SILLocation loc,
if (!SGF.getOptions().VerifyExclusivity)
return address;

auto storage = AccessStorage::compute(address);
// Unsafe access may have invalid storage (e.g. a RawPointer).
if (storage && !isPossibleFormalAccessStorage(storage, &SGF.F))
if (isPossibleUnsafeAccessInvalidStorage(address, &SGF.F))
return address;

auto BAI =
Expand Down
Loading