Skip to content

Commit 46fbf8c

Browse files
committed
IRGen: Consistently mangle 'associated type paths' without a generic signature
Mangling uses a generic signature is used to shorten member types to just a name where the protocol is unambiguous. Unfortunately, in the particular case of 'associated type paths', the IRGen mangler did not consistently set the right signature. Sometimes, it would use no signature, and other times it would use the signature of the concrete conforming type, which is incorrect because the member type is written relative to the root protocol's generic signature, <Self : P>. This was caught by some new assertions I'm adding to the rewrite system. Note that this changes the mangling of a few symbols, but none are public in the ABI.
1 parent db6ea99 commit 46fbf8c

7 files changed

+21
-8
lines changed

lib/IRGen/IRGenMangler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ std::string IRGenMangler::mangleSymbolNameForAssociatedConformanceWitness(
288288
Buffer << "default associated conformance";
289289
}
290290

291+
// appendProtocolConformance() sets CurGenericSignature; clear it out
292+
// before calling appendAssociatedTypePath().
293+
CurGenericSignature = nullptr;
294+
291295
bool isFirstAssociatedTypeIdentifier = true;
292296
appendAssociatedTypePath(associatedType, isFirstAssociatedTypeIdentifier);
293297
appendProtocolName(proto);

lib/IRGen/IRGenMangler.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,11 @@ class IRGenMangler : public Mangle::ASTMangler {
426426
const ProtocolDecl *Proto) {
427427
beginMangling();
428428
appendProtocolConformance(Conformance);
429+
430+
// appendProtocolConformance() sets CurGenericSignature; clear it out
431+
// before calling appendAssociatedTypePath().
432+
CurGenericSignature = nullptr;
433+
429434
bool isFirstAssociatedTypeIdentifier = true;
430435
appendAssociatedTypePath(AssociatedType, isFirstAssociatedTypeIdentifier);
431436
appendAnyGenericType(Proto);
@@ -444,6 +449,10 @@ class IRGenMangler : public Mangle::ASTMangler {
444449
}
445450

446451
void appendAssociatedTypePath(CanType associatedType, bool &isFirst) {
452+
// In the mangling format, the "short associated type" optimization is
453+
// not performed when mangling an associated type path.
454+
assert(!CurGenericSignature && "Caller needs to explicitly clear the signature");
455+
447456
if (auto memberType = dyn_cast<DependentMemberType>(associatedType)) {
448457
appendAssociatedTypePath(memberType.getBase(), isFirst);
449458
appendAssociatedTypeName(memberType);

test/IRGen/associated_type_witness.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ struct WithUniversal : Assocked {
5050
// Witness table for GenericWithUniversal : Assocked.
5151
// GLOBAL-LABEL: @"$s23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAAWP" = hidden global [4 x i8*] [
5252
// GLOBAL-SAME: @"$s23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAAMc"
53-
// GLOBAL-SAME: @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5Assoc_AA1P"
54-
// GLOBAL-SAME: @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5Assoc_AA1Q"
53+
// GLOBAL-SAME: @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5AssocAaEP_AA1P"
54+
// GLOBAL-SAME: @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5AssocAaEP_AA1Q"
5555
// GLOBAL-SAME: @"symbolic{{.*}}23associated_type_witness9UniversalV"
5656
// GLOBAL-SAME: ]
5757
struct GenericWithUniversal<T> : Assocked {
@@ -88,8 +88,8 @@ struct Pair<T, U> : P, Q {}
8888
// Generic witness table pattern for Computed : Assocked.
8989
// GLOBAL-LABEL: @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAAWp" = internal global [4 x i8*] [
9090
// GLOBAL-SAME: @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAAMc"
91-
// GLOBAL-SAME: @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1P"
92-
// GLOBAL-SAME: @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1Q"
91+
// GLOBAL-SAME: @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5AssocAaEP_AA1P"
92+
// GLOBAL-SAME: @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5AssocAaEP_AA1Q"
9393
// GLOBAL-SAME: @"symbolic{{.*}}23associated_type_witness4PairV{{.*}}"
9494
// GLOBAL-SAME: ]
9595

test/IRGen/assoctypepath.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ protocol P {
1717
protocol Q: P where A: Z {}
1818
protocol R: Q where A.ZZ: Y {}
1919

20-
// CHECK: define {{.*}} @"$s13assoctypepath1SVyxGAA1RAA1A_2ZZAA1YPWT"
20+
// CHECK: define {{.*}} @"$s13assoctypepath1SVyxGAA1RAA1AAA1PP_2ZZAA1ZPAA1YPWT"
2121

2222
struct S<T>: R where T: Z, T.ZZ: Y {
2323
typealias A = T

test/IRGen/opaque_result_type_associated_type_conformance_path.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct Foo<T: Tubb>: P {
1414
func foo(_ x: T) -> some Tubb { return x }
1515
}
1616

17-
// CHECK-LABEL: define {{.*}} @"$s030opaque_result_type_associated_C17_conformance_path3FooVyxGAA1PAA1B_AA4ButtPWT"
17+
// CHECK-LABEL: define {{.*}} @"$s030opaque_result_type_associated_C17_conformance_path3FooVyxGAA1PAA1AAaEP_AA4ButtPWT"
1818
// CHECK: [[TUBB_CONFORMANCE:%.*]] = call swiftcc i8** @swift_getOpaqueTypeConformance({{.*}}, i{{.*}} 1)
1919
// CHECK: [[BUTT_CONFORMANCE_ADDR:%.*]] = getelementptr {{.*}} [[TUBB_CONFORMANCE]], i32 1
2020
// CHECK: [[BUTT_CONFORMANCE_LOAD:%.*]] = load {{.*}} [[BUTT_CONFORMANCE_ADDR]]

test/IRGen/same_type_constraints.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ where Self : CodingType,
6767
print(Self.ValueType.self)
6868
}
6969

70-
// OSIZE: define internal swiftcc i8** @"$s21same_type_constraints12GenericKlazzCyxq_GAA1EAA4Data_AA0F4TypePWT"(%swift.type* readnone %"GenericKlazz<T, R>.Data", %swift.type* nocapture readonly %"GenericKlazz<T, R>", i8** nocapture readnone %"GenericKlazz<T, R>.E") [[ATTRS:#[0-9]+]] {
70+
// OSIZE: define internal swiftcc i8** @"$s21same_type_constraints12GenericKlazzCyxq_GAA1EAA4DataAaEP_AA0F4TypePWT"(%swift.type* readnone %"GenericKlazz<T, R>.Data", %swift.type* nocapture readonly %"GenericKlazz<T, R>", i8** nocapture readnone %"GenericKlazz<T, R>.E") [[ATTRS:#[0-9]+]] {
7171
// OSIZE: [[ATTRS]] = {{{.*}}noinline
7272

7373
// Check that same-typing two generic parameters together lowers correctly.

test/Inputs/conditional_conformance_recursive.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ protocol P3: P2 where A: P3 { }
1919
extension Wrapper: P3 where T: P3 { }
2020

2121
// associated type witness table accessor for A : P2 in Wrapper<T>: P2
22-
// CHECK-LABEL: define internal swiftcc i8** @"$s33conditional_conformance_recursive7WrapperVyxGAA2P2A2aERzrl1A_AaEPWT"
22+
// CHECK-LABEL: define internal swiftcc i8** @"$s33conditional_conformance_recursive7WrapperVyxGAA2P2A2aERzrl1AAA2P1P_AaEPWT"
2323
// CHECK: [[CONDITIONAL_REQ_BUFFER:%.*]] = alloca [1 x i8**]
2424
// CHECK: [[FIRST_REQ:%.*]] = getelementptr inbounds [1 x i8**], [1 x i8**]* [[CONDITIONAL_REQ_BUFFER]]
2525
// CHECK: call i8** @swift_getWitnessTable

0 commit comments

Comments
 (0)