Skip to content

Commit f858eed

Browse files
committed
[Runtime] Fix subscript key path printing when arguments can't be resolved.
If there's a mismatch between the arguments we match and the arguments we actually have, we can end up indexing off the end of the argumentTypeNames vector. This can happen when an argument has a dependent generic type. Add a bounds check and print <unknown> when we're out of bounds to avoid crashing. For correctness, we should match generic dependent types and add them to the arguments array, but we'll fix the crashes first. rdar://104438524
1 parent 8738c81 commit f858eed

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

lib/Demangling/NodePrinter.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3315,6 +3315,11 @@ std::string Demangle::keyPathSourceString(const char *MangledName,
33153315
case Node::Kind::Subscript: {
33163316
std::string subscriptText = "subscript(";
33173317
std::vector<std::string> argumentTypeNames;
3318+
auto getArgumentTypeName = [&argumentTypeNames](size_t i) {
3319+
if (i < argumentTypeNames.size())
3320+
return argumentTypeNames[i];
3321+
return std::string("<unknown>");
3322+
};
33183323
// Multiple arguments case
33193324
NodePointer argList = matchSequenceOfKinds(
33203325
child, {
@@ -3362,27 +3367,27 @@ std::string Demangle::keyPathSourceString(const char *MangledName,
33623367
if (child->getKind() == Node::Kind::LabelList) {
33633368
size_t numChildren = child->getNumChildren();
33643369
if (numChildren == 0) {
3365-
subscriptText += unlabelledArg + argumentTypeNames[0];
3370+
subscriptText += unlabelledArg + getArgumentTypeName(0);
33663371
} else {
33673372
while (idx < numChildren) {
33683373
Node *argChild = child->getChild(idx);
33693374
idx += 1;
33703375
if (argChild->getKind() == Node::Kind::Identifier) {
33713376
subscriptText += std::string(argChild->getText()) + ": " +
3372-
argumentTypeNames[idx - 1];
3377+
getArgumentTypeName(idx - 1);
33733378
if (idx != numChildren) {
33743379
subscriptText += ", ";
33753380
}
33763381
} else if (argChild->getKind() ==
33773382
Node::Kind::FirstElementMarker ||
33783383
argChild->getKind() == Node::Kind::VariadicMarker) {
3379-
subscriptText += unlabelledArg + argumentTypeNames[idx - 1];
3384+
subscriptText += unlabelledArg + getArgumentTypeName(idx - 1);
33803385
}
33813386
}
33823387
}
33833388
}
33843389
} else {
3385-
subscriptText += unlabelledArg + argumentTypeNames[0];
3390+
subscriptText += unlabelledArg + getArgumentTypeName(0);
33863391
}
33873392
return subscriptText + ")";
33883393
}

test/Interpreter/keypath.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,21 @@ class Controller {
3636
0
3737
}
3838

39+
subscript<T>(array: [T]) -> T? {
40+
array.first
41+
}
42+
43+
subscript<T, U>(array: [T], array2: [U]) -> T? {
44+
array.first
45+
}
46+
47+
subscript<T>(array array: [T]) -> T? {
48+
array.first
49+
}
50+
51+
subscript<T, U>(array array: [T], array2 array2: [U]) -> T? {
52+
array.first
53+
}
3954
}
4055

4156
struct S {
@@ -95,3 +110,11 @@ print(\Controller.thirdLabel)
95110
print(\Controller.[])
96111
// CHECK: \Controller.self
97112
print(\Controller.self)
113+
// CHECK: \Controller.subscript(_: <unknown>)
114+
print(\Controller[[42]])
115+
// CHECK: Controller.subscript(_: <unknown>)
116+
print(\Controller[[42], [42]])
117+
// CHECK: \Controller.subscript(array: <unknown>)
118+
print(\Controller[array: [42]])
119+
// CHECK: \Controller.subscript(array: <unknown>, array2: <unknown>)
120+
print(\Controller[array: [42], array2: [42]])

0 commit comments

Comments
 (0)