mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[rbi] Fix demangling of sending results.
The issue here is that the demangler (since we have a postfix mangling) parses parameters/results/etc and then uses earlier postfix type arguments to attach the relevant types to the parameters/results/etc. Since the flag for a sending result was placed in between the parameters and results, we get an off by one error. Rather than fix that specific issue by introducing an offset for the off by one error, I used the fact that the impl-function part of the mangling is not ABI and can be modified to move the bit used to signify a sending result to before the parameters so the whole problem is avoided. I also while I was doing this looked through the sending result mangling for any further issues and fixed them as I found them. rdar://141962865
This commit is contained in:
@@ -837,7 +837,7 @@ mangled in to disambiguate.
|
||||
impl-function-type ::= type* 'I' FUNC-ATTRIBUTES '_'
|
||||
impl-function-type ::= type* generic-signature 'I' FUNC-ATTRIBUTES '_'
|
||||
|
||||
FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? ISOLATION? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? SENDABLE? ASYNC? (PARAM-CONVENTION PARAM-DIFFERENTIABILITY?)* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION RESULT-DIFFERENTIABILITY?)?
|
||||
FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? ISOLATION? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? SENDABLE? ASYNC? SENDING-RESULT? (PARAM-CONVENTION PARAM-DIFFERENTIABILITY?)* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION RESULT-DIFFERENTIABILITY?)?
|
||||
|
||||
PATTERN-SUBS ::= 's' // has pattern substitutions
|
||||
INVOCATION-SUB ::= 'I' // has invocation substitutions
|
||||
@@ -871,8 +871,9 @@ mangled in to disambiguate.
|
||||
COROUTINE-KIND ::= 'G' // yield-many coroutine
|
||||
|
||||
#if SWIFT_RUNTIME_VERSION >= 5.5
|
||||
SENDABLE ::= 'h' // @Sendable
|
||||
ASYNC ::= 'H' // @async
|
||||
SENDABLE ::= 'h' // @Sendable
|
||||
ASYNC ::= 'H' // @async
|
||||
SENDING-RESULT ::= 'T' // sending result
|
||||
#endif
|
||||
|
||||
PARAM-CONVENTION ::= 'i' // indirect in
|
||||
|
||||
@@ -1093,7 +1093,14 @@ protected:
|
||||
flags = flags.withSendable();
|
||||
} else if (child->getText() == "@async") {
|
||||
flags = flags.withAsync();
|
||||
} else if (child->getText() == "sending-result") {
|
||||
flags = flags.withSendingResult();
|
||||
}
|
||||
} else if (child->getKind() == NodeKind::ImplSendingResult) {
|
||||
// NOTE: This flag needs to be set both at the function level and on
|
||||
// each of the parameters. The flag on the function just means that
|
||||
// all parameters are sending (which is always true today).
|
||||
flags = flags.withSendingResult();
|
||||
} else if (child->getKind() == NodeKind::ImplCoroutineKind) {
|
||||
if (!child->hasText())
|
||||
return MAKE_NODE_TYPE_ERROR0(child, "expected text");
|
||||
|
||||
@@ -677,6 +677,10 @@ Type ASTBuilder::createImplFunctionType(
|
||||
auto type = result.getType()->getCanonicalType();
|
||||
auto conv = getResultConvention(result.getConvention());
|
||||
auto options = *getResultOptions(result.getOptions());
|
||||
// We currently set sending result at the function level, but we set sending
|
||||
// result on each result.
|
||||
if (flags.hasSendingResult())
|
||||
options |= SILResultInfo::IsSending;
|
||||
funcResults.emplace_back(type, conv, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -2301,6 +2301,19 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
|
||||
OpArgs.push_back('H');
|
||||
}
|
||||
|
||||
// Mangle if we have a sending result and we are in a recursive position.
|
||||
//
|
||||
// DISCUSSION: We only want sending results to change ABI if it is using in a
|
||||
// function value passed to a parameter or generic position... but not if it
|
||||
// is just added to a return type.
|
||||
//
|
||||
// E.x.:
|
||||
//
|
||||
// func foo() -> sending X // No mangling
|
||||
// func bar(_ x: () -> sending X) {} // Add to mangling for x
|
||||
if (isInRecursion && fn->hasSendingResult())
|
||||
OpArgs.push_back('T');
|
||||
|
||||
GenericSignature sig = fn->getSubstGenericSignature();
|
||||
|
||||
// Mangle the parameters.
|
||||
@@ -2313,10 +2326,6 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
|
||||
appendType(param.getInterfaceType(), sig, forDecl);
|
||||
}
|
||||
|
||||
// Mangle if we have a sending result.
|
||||
if (isInRecursion && fn->hasSendingResult())
|
||||
OpArgs.push_back('T');
|
||||
|
||||
// Mangle the results.
|
||||
for (auto result : fn->getResults()) {
|
||||
OpArgs.push_back(getResultConvention(result.getConvention()));
|
||||
|
||||
@@ -2418,6 +2418,10 @@ NodePointer Demangler::demangleImplFunctionType() {
|
||||
*this);
|
||||
}
|
||||
|
||||
if (nextIf('T')) {
|
||||
type->addChild(createNode(Node::Kind::ImplSendingResult), *this);
|
||||
}
|
||||
|
||||
addChild(type, GenSig);
|
||||
|
||||
int NumTypesToAdd = 0;
|
||||
@@ -2431,10 +2435,6 @@ NodePointer Demangler::demangleImplFunctionType() {
|
||||
++NumTypesToAdd;
|
||||
}
|
||||
|
||||
if (nextIf('T')) {
|
||||
type->addChild(createNode(Node::Kind::ImplSendingResult), *this);
|
||||
}
|
||||
|
||||
while (NodePointer Result = demangleImplResultConvention(
|
||||
Node::Kind::ImplResult)) {
|
||||
type = addChild(type, Result);
|
||||
@@ -2467,7 +2467,7 @@ NodePointer Demangler::demangleImplFunctionType() {
|
||||
return nullptr;
|
||||
type->getChild(type->getNumChildren() - Idx - 1)->addChild(ConvTy, *this);
|
||||
}
|
||||
|
||||
|
||||
return createType(type);
|
||||
}
|
||||
|
||||
|
||||
@@ -2252,6 +2252,9 @@ private:
|
||||
if (Mangled.nextIf('H'))
|
||||
addImplFunctionAttribute(type, "@async");
|
||||
|
||||
if (Mangled.nextIf('T'))
|
||||
addImplFunctionAttribute(type, "sending-result");
|
||||
|
||||
// Enter a new generic context if this type is generic.
|
||||
// FIXME: replace with std::optional, when we have it.
|
||||
bool isPseudogeneric = false;
|
||||
|
||||
@@ -2120,9 +2120,10 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) {
|
||||
}
|
||||
case Node::Kind::ImplFunctionAttribute: {
|
||||
char FuncAttr = llvm::StringSwitch<char>(Child->getText())
|
||||
.Case("@Sendable", 'h')
|
||||
.Case("@async", 'H')
|
||||
.Default(0);
|
||||
.Case("@Sendable", 'h')
|
||||
.Case("@async", 'H')
|
||||
.Case("sending-result", 'T')
|
||||
.Default(0);
|
||||
if (!FuncAttr) {
|
||||
return MANGLING_ERROR(ManglingError::InvalidImplFunctionAttribute,
|
||||
Child);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// RUN: %target-swift-frontend %s -emit-silgen -swift-version 6 | swift-demangle | %FileCheck -check-prefix=CHECK %s
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend %s -emit-silgen -swift-version 6 | swift-demangle | %FileCheck %s
|
||||
// RUN: %target-swift-frontend %s -emit-silgen -swift-version 6 | %FileCheck -check-prefix=SIL %s
|
||||
|
||||
// REQUIRES: concurrency
|
||||
// REQUIRES: asserts
|
||||
@@ -110,3 +112,21 @@ struct ConstructorSharedTest {
|
||||
// CHECK: sil hidden [ossa] @sending_mangling.ConstructorSharedTest.functionSuppressed(sending_mangling.NonSendableKlass) -> () : $@convention(method) (@sil_sending @guaranteed NonSendableKlass, ConstructorSharedTest) -> () {
|
||||
func functionSuppressed(_ x: __shared sending NonSendableKlass) {}
|
||||
}
|
||||
|
||||
// Make sure that we produce the appropriate reabstraction thunk.
|
||||
func reabstractionThunkTest_takeSendingReturnSending<T>(
|
||||
_ x: sending T) -> sending T { fatalError() }
|
||||
func reabstractionThunkTest_reabstractionThunkGenerator<T>(
|
||||
_ x: sending T,
|
||||
_ f: (sending T) -> T) {}
|
||||
|
||||
// CHECK: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @reabstraction thunk helper from @escaping @callee_guaranteed (@in sending sending_mangling.NonSendableKlass) -> sending (@out sending_mangling.NonSendableKlass) to @escaping @callee_guaranteed (@owned sending sending_mangling.NonSendableKlass) -> sending (@owned sending_mangling.NonSendableKlass) : $@convention(thin) (@sil_sending @owned NonSendableKlass, @guaranteed @callee_guaranteed (@sil_sending @in NonSendableKlass) -> @sil_sending @out NonSendableKlass) -> @sil_sending @owned NonSendableKlass {
|
||||
// SIL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s16sending_mangling16NonSendableKlassCACIegTiTr_A2CIegTxTo_TR : $@convention(thin) (@sil_sending @owned NonSendableKlass, @guaranteed @callee_guaranteed (@sil_sending @in NonSendableKlass) -> @sil_sending @out NonSendableKlass) -> @sil_sending @owned NonSendableKlass {
|
||||
|
||||
// CHECK: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @reabstraction thunk helper from @callee_guaranteed (@owned sending sending_mangling.NonSendableKlass) -> (@owned sending_mangling.NonSendableKlass) to @escaping @callee_guaranteed (@in sending sending_mangling.NonSendableKlass) -> (@out sending_mangling.NonSendableKlass) : $@convention(thin) (@sil_sending @in NonSendableKlass, @guaranteed @noescape @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> @owned NonSendableKlass) -> @out NonSendableKlass {
|
||||
// SIL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s16sending_mangling16NonSendableKlassCACIgxTo_A2CIegiTr_TR : $@convention(thin) (@sil_sending @in NonSendableKlass, @guaranteed @noescape @callee_guaranteed (@sil_sending @owned NonSendableKlass) -> @owned NonSendableKlass) -> @out NonSendableKlass {
|
||||
func reabstractionThunkTest() {
|
||||
reabstractionThunkTest_reabstractionThunkGenerator(
|
||||
NonSendableKlass(),
|
||||
reabstractionThunkTest_takeSendingReturnSending)
|
||||
}
|
||||
|
||||
@@ -485,3 +485,5 @@ $s4main4SlabVy$1_SiG ---> main.Slab<2, Swift.Int>
|
||||
$s$n3_SSBV ---> Builtin.FixedArray<-4, Swift.String>
|
||||
$s3red7MyActorC3runyxxyYaKACYcYTXEYaKlFZ ---> static red.MyActor.run<A>(@red.MyActor () async throws -> sending A) async throws -> A
|
||||
$s3red7MyActorC3runyxxyYaKYAYTXEYaKlFZ ---> static red.MyActor.run<A>(@isolated(any) () async throws -> sending A) async throws -> A
|
||||
$s7ToolKit10TypedValueOACs5Error_pIgHTnTrzo_A2CsAD_pIegHiTrzr_TR ---> {T:} reabstraction thunk helper from @callee_guaranteed @async (@in_guaranteed sending ToolKit.TypedValue) -> sending (@out ToolKit.TypedValue, @error @owned Swift.Error) to @escaping @callee_guaranteed @async (@in sending ToolKit.TypedValue) -> (@out ToolKit.TypedValue, @error @out Swift.Error)
|
||||
$s16sending_mangling16NonSendableKlassCACIegTiTr_A2CIegTxTo_TR ---> {T:} reabstraction thunk helper from @escaping @callee_guaranteed (@in sending sending_mangling.NonSendableKlass) -> sending (@out sending_mangling.NonSendableKlass) to @escaping @callee_guaranteed (@owned sending sending_mangling.NonSendableKlass) -> sending (@owned sending_mangling.NonSendableKlass)
|
||||
|
||||
Reference in New Issue
Block a user