Skip to content

Commit 7d4f45b

Browse files
authored
Merge pull request #85608 from kavon/opaque-values/fixes-5
OpaqueValues: fixes for distributed actors + introduce AccessControls
2 parents 2c9013b + 10d8053 commit 7d4f45b

File tree

15 files changed

+251
-100
lines changed

15 files changed

+251
-100
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//===--- AccessControls.h ---------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines macros that help control access to APIs.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_ACCESSCONTROLS_H
18+
#define SWIFT_ACCESSCONTROLS_H
19+
20+
/// Deprecation warnings
21+
#if defined(__clang__) || defined(__GNUC__)
22+
#if !defined(SWIFT_DEPRECATED)
23+
#define SWIFT_DEPRECATED __attribute__((deprecated))
24+
#endif
25+
#if !defined(SWIFT_DEPRECATED_MSG)
26+
#define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
27+
#endif
28+
#else
29+
#if !defined(SWIFT_DEPRECATED)
30+
#define SWIFT_DEPRECATED
31+
#endif
32+
#if !defined(SWIFT_DEPRECATED_MSG)
33+
#define SWIFT_DEPRECATED_MSG(...)
34+
#endif
35+
#endif
36+
37+
38+
/// Unavailable errors
39+
#if defined(__clang__) || defined(__GNUC__)
40+
#if !defined(SWIFT_UNAVAILABLE)
41+
#define SWIFT_UNAVAILABLE __attribute__((unavailable))
42+
#endif
43+
#if !defined(SWIFT_UNAVAILABLE_MSG)
44+
#define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
45+
#endif
46+
#else
47+
#if !defined(SWIFT_UNAVAILABLE)
48+
#define SWIFT_UNAVAILABLE
49+
#endif
50+
#if !defined(SWIFT_UNAVAILABLE_MSG)
51+
#define SWIFT_UNAVAILABLE_MSG(msg)
52+
#endif
53+
#endif
54+
55+
56+
// Access controls that are only active when included in SILGen sources.
57+
#if defined(SWIFT_INCLUDED_IN_SILGEN_SOURCES)
58+
59+
// Override any prior definitions with these.
60+
#define SWIFT_DEPRECATED_IN_SILGEN SWIFT_DEPRECATED
61+
#define SWIFT_DEPRECATED_IN_SILGEN_MSG(...) SWIFT_DEPRECATED_MSG(__VA_ARGS__)
62+
#define SWIFT_UNAVAILABLE_IN_SILGEN SWIFT_UNAVAILABLE
63+
#define SWIFT_UNAVAILABLE_IN_SILGEN_MSG(MSG) SWIFT_UNAVAILABLE_MSG(MSG)
64+
65+
#else
66+
67+
#if !defined(SWIFT_DEPRECATED_IN_SILGEN)
68+
#define SWIFT_DEPRECATED_IN_SILGEN
69+
#endif
70+
#if !defined(SWIFT_DEPRECATED_IN_SILGEN_MSG)
71+
#define SWIFT_DEPRECATED_IN_SILGEN_MSG(...)
72+
#endif
73+
#if !defined(SWIFT_UNAVAILABLE_IN_SILGEN)
74+
#define SWIFT_UNAVAILABLE_IN_SILGEN
75+
#endif
76+
#if !defined(SWIFT_UNAVAILABLE_IN_SILGEN_MSG)
77+
#define SWIFT_UNAVAILABLE_IN_SILGEN_MSG(MSG)
78+
#endif
79+
#endif // SWIFT_INCLUDED_IN_SILGEN_SOURCES
80+
81+
#endif // SWIFT_ACCESSCONTROLS_H

include/swift/SIL/SILFunctionConventions.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#define SWIFT_SIL_FUNCTIONCONVENTIONS_H
3232

3333
#include "swift/AST/Types.h"
34+
#include "swift/Basic/AccessControls.h"
3435
#include "swift/SIL/SILArgumentConvention.h"
3536
#include "swift/SIL/SILType.h"
3637
#include "llvm/Support/ErrorHandling.h"
@@ -526,11 +527,9 @@ class SILFunctionConventions {
526527
- getNumIndirectSILErrorResults()];
527528
}
528529

529-
/// WARNING: Do not use this from SILGen!
530-
/// Use methods such as `isSILIndirect` or query the ParameterInfo instead.
531-
///
532530
/// Return the SIL argument convention of apply/entry argument at
533531
/// the given argument index.
532+
SWIFT_UNAVAILABLE_IN_SILGEN_MSG("Use methods such as `isSILIndirect` or query the ParameterInfo instead.")
534533
SILArgumentConvention getSILArgumentConvention(unsigned index) const;
535534

536535
/// Return the SIL type of the apply/entry argument at the given index.

include/swift/SIL/SILGenUtils.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// Created by Kavon Farvardin on 11/19/25.
3+
//
4+
5+
#ifndef SWIFT_SILGENUTILS_H
6+
#define SWIFT_SILGENUTILS_H
7+
8+
#include "swift/SIL/SILValue.h"
9+
10+
namespace swift {
11+
12+
// Unsafe access may have invalid storage (e.g. a RawPointer).
13+
bool isPossibleUnsafeAccessInvalidStorage(SILValue access, SILFunction *F);
14+
15+
} // namespace swift
16+
17+
#endif // SWIFT_SILGENUTILS_H

include/swift/SILOptimizer/Utils/DistributedActor.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "swift/AST/Decl.h"
1717
#include "llvm/ADT/ArrayRef.h"
18+
#include "swift/SIL/SILValue.h"
1819
#include <optional>
1920
#include <utility>
2021

@@ -30,7 +31,6 @@ class SILArgument;
3031
class SILFunction;
3132
class SILLocation;
3233
class SILType;
33-
class SILValue;
3434

3535
/// Creates a reference to the distributed actor's \p actorSystem
3636
/// stored property.
@@ -46,11 +46,16 @@ SILValue refDistributedActorSystem(SILBuilder &B,
4646
/// \param actorType If non-empty, the type of the distributed actor that is
4747
/// provided as one of the arguments.
4848
/// \param args The arguments provided to the call, not including the base.
49+
/// \param indirectResult If the result is known to be returned indirect,
50+
/// this is the temporary storage for it.
4951
/// \param tryTargets For a call that can throw, the normal and error basic
5052
/// blocks that the call will branch to.
51-
void emitDistributedActorSystemWitnessCall(
53+
/// \returns If the apply result is known to be returned directly,
54+
/// and there are no tryTargets, then the result is returned.
55+
std::optional<SILValue> emitDistributedActorSystemWitnessCall(
5256
SILBuilder &B, SILLocation loc, DeclName methodName, SILValue base,
5357
SILType actorType, llvm::ArrayRef<SILValue> args,
58+
std::optional<SILValue> indirectResult = std::nullopt,
5459
std::optional<std::pair<SILBasicBlock *, SILBasicBlock *>> tryTargets =
5560
std::nullopt);
5661

lib/SIL/IR/SILArgument.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ SILParameterInfo SILFunctionArgument::getKnownParameterInfo() const {
8787
return getFunction()->getConventions().getParamInfoForSILArg(getIndex());
8888
}
8989

90-
/// WARNING: Do not use this from SILGen!
91-
/// Use methods such as `isSILIndirect` or query the ParameterInfo instead.
9290
SILArgumentConvention
9391
SILFunctionConventions::getSILArgumentConvention(unsigned index) const {
9492
assert(index < getNumSILArguments());

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/SIL/SILBridging.h"
2323
#include "swift/SIL/SILInstruction.h"
2424
#include "swift/SIL/SILModule.h"
25+
#include "swift/SIL/SILGenUtils.h"
2526
#include "swift/SIL/SILUndef.h"
2627
#include "swift/SIL/Test.h"
2728
#include "llvm/Support/Debug.h"
@@ -2485,6 +2486,12 @@ void swift::checkSwitchEnumBlockArg(SILPhiArgument *arg) {
24852486
}
24862487
}
24872488

2489+
bool swift::isPossibleUnsafeAccessInvalidStorage(SILValue address,
2490+
SILFunction *F) {
2491+
auto storage = AccessStorage::compute(address);
2492+
return storage && !isPossibleFormalAccessStorage(storage, F);
2493+
}
2494+
24882495
bool swift::isPossibleFormalAccessStorage(const AccessStorage &storage,
24892496
SILFunction *F) {
24902497
switch (storage.getKind()) {

lib/SILGen/Cleanup.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#ifndef SWIFT_SILGEN_CLEANUP_H
1818
#define SWIFT_SILGEN_CLEANUP_H
1919

20+
#define SWIFT_INCLUDED_IN_SILGEN_SOURCES
21+
2022
#include "swift/Basic/Assertions.h"
2123
#include "swift/Basic/Debug.h"
2224
#include "swift/Basic/DiverseStack.h"

lib/SILGen/ManagedValue.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#ifndef SWIFT_LOWERING_MANAGEDVALUE_H
2121
#define SWIFT_LOWERING_MANAGEDVALUE_H
2222

23+
#define SWIFT_INCLUDED_IN_SILGEN_SOURCES
24+
2325
#include "Cleanup.h"
2426
#include "llvm/ADT/PointerIntPair.h"
2527
#include "swift/Basic/Assertions.h"

lib/SILGen/SILGen.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#ifndef SILGEN_H
1414
#define SILGEN_H
1515

16+
#define SWIFT_INCLUDED_IN_SILGEN_SOURCES
17+
1618
#include "ASTVisitor.h"
1719
#include "Cleanup.h"
1820
#include "swift/AST/ASTContext.h"

lib/SILGen/SILGenDistributed.cpp

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,17 @@ static void initializeProperty(SILGenFunction &SGF, SILLocation loc,
6363

6464
auto fieldAddr = emitActorPropertyReference(SGF, loc, actorSelf, prop);
6565

66-
if (loweredType.isAddressOnly(SGF.F)) {
66+
if (loweredType.isAddressOnly(SGF.F) && SGF.useLoweredAddresses()) {
6767
SGF.B.createCopyAddr(loc, value, fieldAddr, isTake, IsInitialization);
6868
} else {
6969
if (value->getType().isAddress()) {
7070
SGF.emitSemanticLoadInto(loc, value, SGF.F.getTypeLowering(value->getType()),
7171
fieldAddr, SGF.getTypeLowering(loweredType), isTake, IsInitialization);
7272
} else {
73-
value = SGF.B.emitCopyValueOperation(loc, value);
73+
// If it's not semantically a take, copy it.
74+
if (isTake == IsNotTake)
75+
value = SGF.B.emitCopyValueOperation(loc, value);
76+
7477
SGF.B.emitStoreValueOperation(
7578
loc, value, fieldAddr, StoreOwnershipQualifier::Init);
7679
}
@@ -204,20 +207,31 @@ void SILGenFunction::emitDistActorIdentityInit(ConstructorDecl *ctor,
204207
auto selfMetatype = getLoweredType(MetatypeType::get(selfTy));
205208
SILValue selfMetatypeValue = B.createMetatype(loc, selfMetatype);
206209

207-
// --- create a temporary storage for the result of the call
208-
// it will be deallocated automatically as we exit this scope
209210
VarDecl *var = classDecl->getDistributedActorIDProperty();
210-
auto resultTy = getLoweredType(F.mapTypeIntoEnvironment(var->getInterfaceType()));
211-
auto temp = emitTemporaryAllocation(loc, resultTy);
212-
213-
// --- emit the call itself.
214-
emitDistributedActorSystemWitnessCall(
215-
B, loc, C.Id_assignID,
216-
actorSystem, getLoweredType(selfTy),
217-
{ temp, selfMetatypeValue });
218-
219-
// --- initialize the property.
220-
initializeProperty(*this, loc, borrowedSelfArg, var, temp, IsTake);
211+
if (useLoweredAddresses()) {
212+
// --- create a temporary storage for the result of the call
213+
// it will be deallocated automatically as we exit this scope
214+
auto resultTy = getLoweredType(F.mapTypeIntoEnvironment(var->getInterfaceType()));
215+
auto temp = emitTemporaryAllocation(loc, resultTy);
216+
217+
// --- emit the call itself.
218+
emitDistributedActorSystemWitnessCall(
219+
B, loc, C.Id_assignID,
220+
actorSystem, getLoweredType(selfTy),
221+
{ selfMetatypeValue }, temp);
222+
223+
// --- initialize the property.
224+
initializeProperty(*this, loc, borrowedSelfArg, var, temp, IsTake);
225+
} else {
226+
// --- emit the call itself.
227+
auto result = emitDistributedActorSystemWitnessCall(
228+
B, loc, C.Id_assignID,
229+
actorSystem, getLoweredType(selfTy),
230+
{ selfMetatypeValue });
231+
232+
// --- initialize the property.
233+
initializeProperty(*this, loc, borrowedSelfArg, var, result.value(), IsTake);
234+
}
221235
}
222236

223237
// TODO(distributed): rename to DistributedActorID
@@ -361,27 +375,6 @@ void SILGenFunction::emitDistributedActorReady(
361375
// ==== ------------------------------------------------------------------------
362376
// MARK: remote instance initialization
363377

364-
/// emit a call to the distributed actor system's resolve function:
365-
///
366-
/// \verbatim
367-
/// system.resolve(id:as:)
368-
/// \endverbatim
369-
static void createDistributedActorFactory_resolve(
370-
SILGenFunction &SGF, ASTContext &C, FuncDecl *fd, SILValue idValue,
371-
SILValue actorSystemValue, Type selfTy, SILValue selfMetatypeValue,
372-
SILType resultTy, SILBasicBlock *normalBB, SILBasicBlock *errorBB) {
373-
auto &B = SGF.B;
374-
375-
auto loc = SILLocation(fd);
376-
loc.markAutoGenerated();
377-
378-
// // ---- actually call system.resolve(id: id, as: Self.self)
379-
emitDistributedActorSystemWitnessCall(
380-
B, loc, C.Id_resolve, actorSystemValue, SGF.getLoweredType(selfTy),
381-
{ idValue, selfMetatypeValue },
382-
std::make_pair(normalBB, errorBB));
383-
}
384-
385378
/// Function body of:
386379
/// \verbatim
387380
/// DistributedActor.resolve(
@@ -435,9 +428,15 @@ void SILGenFunction::emitDistributedActorFactory(FuncDecl *fd) { // TODO(distrib
435428

436429
// ==== Call `try system.resolve(id: id, as: Self.self)`
437430
{
438-
createDistributedActorFactory_resolve(
439-
*this, C, fd, idArg, actorSystemArg, selfTy, selfMetatypeValue,
440-
optionalReturnTy, switchBB, errorBB);
431+
auto loc = SILLocation(fd);
432+
loc.markAutoGenerated();
433+
434+
// // ---- actually call system.resolve(id: id, as: Self.self)
435+
emitDistributedActorSystemWitnessCall(
436+
B, loc, C.Id_resolve, actorSystemArg, getLoweredType(selfTy),
437+
{ idArg, selfMetatypeValue },
438+
/*indirectResult=*/std::nullopt,
439+
std::make_pair(switchBB, errorBB));
441440
}
442441

443442
// ==== switch resolved { ... }

0 commit comments

Comments
 (0)