Skip to content

Commit ea9f0ea

Browse files
committed
[Mangling] Mangle protocol names in assoc-type-paths.
The mangling of associated type paths was only adding the names of associated types, and not their enclosing protocols. This led to mangling collisions that could lead to corrupted metadata. In the standard library, for example, the generic requirements for the Unicode _ParsingIterator in the standard library ended up encoding an access to Sequence.Element rather than IteratorProtocol.Element due to the mangling conflict. Part of SR-7553 / rdar://problem/39769906.
1 parent 6982284 commit ea9f0ea

File tree

6 files changed

+18
-20
lines changed

6 files changed

+18
-20
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Globals
6464
global ::= context 'MXE' // extension descriptor
6565
global ::= context 'MXX' // anonymous context descriptor
6666
global ::= context identifier 'MXY' // anonymous context descriptor
67-
global ::= type assoc_type_path 'MXA' // generic parameter ref
67+
global ::= type assoc-type-list 'MXA' // generic parameter ref
6868
global ::= protocol 'Mp' // protocol descriptor
6969

7070
global ::= nominal-type 'Mo' // class metadata immediate member base offset
@@ -91,15 +91,13 @@ Globals
9191
global ::= type protocol-conformance 'WL' // lazy protocol witness table cache variable
9292

9393
global ::= protocol-conformance identifier 'Wt' // associated type metadata accessor
94-
global ::= protocol-conformance assoc_type_path nominal-type 'WT' // associated type witness table accessor
94+
global ::= protocol-conformance assoc-type-list nominal-type 'WT' // associated type witness table accessor
9595
global ::= type protocol-conformance 'Wl' // lazy protocol witness table accessor
9696

9797
global ::= type 'WV' // value witness table
9898
global ::= entity 'Wvd' // field offset
9999
global ::= entity 'WC' // resilient enum tag index
100100

101-
assoc_type_path ::= identifier '_' identifier*
102-
103101
A direct symbol resolves directly to the address of an object. An
104102
indirect symbol resolves to the address of a pointer to the object.
105103
They are distinct manglings to make a certain class of bugs

lib/Demangling/Demangler.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,10 +1666,10 @@ NodePointer Demangler::popAssocTypePath() {
16661666
bool firstElem = false;
16671667
do {
16681668
firstElem = (popNode(Node::Kind::FirstElementMarker) != nullptr);
1669-
NodePointer AssocTyName = popNode(isDeclName);
1670-
if (!AssocTyName)
1669+
NodePointer AssocTy = popAssocTypeName();
1670+
if (!AssocTy)
16711671
return nullptr;
1672-
AssocTypePath->addChild(AssocTyName, *this);
1672+
AssocTypePath->addChild(AssocTy, *this);
16731673
} while (!firstElem);
16741674
AssocTypePath->reverseChildren();
16751675
return AssocTypePath;

lib/IRGen/IRGenMangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ class IRGenMangler : public Mangle::ASTMangler {
329329
void appendAssociatedTypePath(CanType associatedType, bool &isFirst) {
330330
if (auto memberType = dyn_cast<DependentMemberType>(associatedType)) {
331331
appendAssociatedTypePath(memberType.getBase(), isFirst);
332-
appendIdentifier(memberType->getName().str());
332+
appendAssociatedTypeName(memberType);
333333
appendListSeparator(isFirst);
334334
} else {
335335
assert(isa<GenericTypeParamType>(associatedType));

test/IRGen/associated_type_witness.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,23 @@ struct GenericWithUniversal<T> : Assocked {
5353
// Witness table for Fulfilled : Assocked.
5454
// GLOBAL-LABEL: @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAAWp" = internal constant [4 x i8*] [
5555
// GLOBAL-SAME: @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAAMc"
56-
// GLOBAL-SAME: i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5Assoc_AA1PPWT" to i8*)
57-
// GLOBAL-SAME: i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5Assoc_AA1QPWT" to i8*)
56+
// GLOBAL-SAME: i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1PPWT" to i8*)
57+
// GLOBAL-SAME: i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1QPWT" to i8*)
5858
// GLOBAL-SAME: i8* bitcast (%swift.metadata_response (i64, %swift.type*, i8**)* @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocWt" to i8*)
5959
// GLOBAL-SAME: ]
6060
struct Fulfilled<T : P & Q> : Assocked {
6161
typealias Assoc = T
6262
}
6363

6464
// Associated type witness table access function for Fulfilled.Assoc : P.
65-
// CHECK-LABEL: define internal swiftcc i8** @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5Assoc_AA1PPWT"(%swift.type* %"Fulfilled<T>.Assoc", %swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
65+
// CHECK-LABEL: define internal swiftcc i8** @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1PPWT"(%swift.type* %"Fulfilled<T>.Assoc", %swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
6666
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Fulfilled<T>" to i8***
6767
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 3
6868
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load
6969
// CHECK-NEXT: ret i8** [[T2]]
7070

7171
// Associated type witness table access function for Fulfilled.Assoc : Q.
72-
// CHECK-LABEL: define internal swiftcc i8** @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5Assoc_AA1QPWT"(%swift.type* %"Fulfilled<T>.Assoc", %swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
72+
// CHECK-LABEL: define internal swiftcc i8** @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1QPWT"(%swift.type* %"Fulfilled<T>.Assoc", %swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
7373
// CHECK: [[T0:%.*]] = bitcast %swift.type* %"Fulfilled<T>" to i8***
7474
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 4
7575
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load

test/IRGen/protocol_resilience.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import resilient_protocol
5151

5252
// Requirement signature
5353
// CHECK-SAME: i32 128,
54-
// CHECK-SAME: @"$sx1T_MXA"
54+
// CHECK-SAME: @"$sx1T19protocol_resilience17ResilientProtocolP_MXA"
5555
// CHECK-SAME: @"$s19protocol_resilience17ResilientProtocolMp"
5656

5757
// Protocol requirements

test/IRGen/protocol_resilience_descriptors.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
// Protocol descriptor
1616
// CHECK-DEFINITION-LABEL: @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsMp" ={{( protected)?}} constant
17-
// CHECK-DEFINITION-SAME: @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0TN"
17+
// CHECK-DEFINITION-SAME: @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2AC_AA014OtherResilientC0TN"
1818
// CHECK-DEFINITION-SAME: $s2T118resilient_protocol29ProtocolWithAssocTypeDefaultsPTM
1919
// CHECK-DEFINITION-SAME: $s2T218resilient_protocol29ProtocolWithAssocTypeDefaultsPTM
2020

@@ -24,10 +24,10 @@
2424
// Associated type and conformance
2525

2626
// CHECK-DEFINITION: @"$s1T18resilient_protocol24ProtocolWithRequirementsPTl" ={{( dllexport)?}}{{( protected)?}} alias
27-
// CHECK-DEFINITION: @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0Tn" ={{( dllexport)?}}{{( protected)?}} alias
27+
// CHECK-DEFINITION: @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2AC_AA014OtherResilientC0Tn" ={{( dllexport)?}}{{( protected)?}} alias
2828

2929
// Default associated conformance witnesses
30-
// CHECK-DEFINITION-LABEL: define internal swiftcc i8** @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0TN"
30+
// CHECK-DEFINITION-LABEL: define internal swiftcc i8** @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2AC_AA014OtherResilientC0TN"
3131

3232
// Default associated type witnesses
3333
// CHECK-DEFINITION-LABEL: define internal swiftcc %swift.metadata_response @"$s2T118resilient_protocol29ProtocolWithAssocTypeDefaultsPTM"
@@ -58,15 +58,15 @@ public struct ConditionallyConforms<Element> { }
5858
public struct Y { }
5959

6060
// CHECK-USAGE: @"$s31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAAWr" = internal
61-
// CHECK-USAGE-SAME: $s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0Tn
62-
// CHECK-USAGE-SAME: $s31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAA2T2_AD014OtherResilientI0PWT
61+
// CHECK-USAGE-SAME: $s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2AC_AA014OtherResilientC0Tn
62+
// CHECK-USAGE-SAME: $s31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAA2T2AdEP_AD014OtherResilientI0PWT
6363
public struct ConformsWithAssocRequirements : ProtocolWithAssocTypeDefaults {
6464
}
6565

66-
// CHECK-USAGE: @"$sx1T_MXA" =
66+
// CHECK-USAGE: @"$sx1T18resilient_protocol24ProtocolWithRequirementsP_MXA" =
6767
// CHECK-USAGE-SAME: i32 0
6868
// CHECK-USAGE-SAME: @"{{got.|__imp_}}$s18resilient_protocol24ProtocolWithRequirementsMp"
69-
// CHECK-USAGE-SAME: @"$sx1T_MXA"
69+
// CHECK-USAGE-SAME: @"$sx1T18resilient_protocol24ProtocolWithRequirementsP_MXA"
7070
// CHECK-USAGE-SAME: %swift.protocol_requirement** @"{{got.|__imp_}}$s1T18resilient_protocol24ProtocolWithRequirementsPTl"
7171

7272
// CHECK-USAGE: @"$s31protocol_resilience_descriptors21ConditionallyConformsVyxG010resilient_A024ProtocolWithRequirementsAaeFRzAA1YV1TRtzlMc"

0 commit comments

Comments
 (0)