Skip to content

Commit 91dcf8d

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 3bf7805 commit 91dcf8d

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

lib/Demangling/NodePrinter.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3407,6 +3407,11 @@ std::string Demangle::keyPathSourceString(const char *MangledName,
34073407
case Node::Kind::Subscript: {
34083408
std::string subscriptText = "subscript(";
34093409
std::vector<std::string> argumentTypeNames;
3410+
auto getArgumentTypeName = [&argumentTypeNames](size_t i) {
3411+
if (i < argumentTypeNames.size())
3412+
return argumentTypeNames[i];
3413+
return std::string("<unknown>");
3414+
};
34103415
// Multiple arguments case
34113416
NodePointer argList = matchSequenceOfKinds(
34123417
child, {
@@ -3454,27 +3459,27 @@ std::string Demangle::keyPathSourceString(const char *MangledName,
34543459
if (child->getKind() == Node::Kind::LabelList) {
34553460
size_t numChildren = child->getNumChildren();
34563461
if (numChildren == 0) {
3457-
subscriptText += unlabelledArg + argumentTypeNames[0];
3462+
subscriptText += unlabelledArg + getArgumentTypeName(0);
34583463
} else {
34593464
while (idx < numChildren) {
34603465
Node *argChild = child->getChild(idx);
34613466
idx += 1;
34623467
if (argChild->getKind() == Node::Kind::Identifier) {
34633468
subscriptText += std::string(argChild->getText()) + ": " +
3464-
argumentTypeNames[idx - 1];
3469+
getArgumentTypeName(idx - 1);
34653470
if (idx != numChildren) {
34663471
subscriptText += ", ";
34673472
}
34683473
} else if (argChild->getKind() ==
34693474
Node::Kind::FirstElementMarker ||
34703475
argChild->getKind() == Node::Kind::VariadicMarker) {
3471-
subscriptText += unlabelledArg + argumentTypeNames[idx - 1];
3476+
subscriptText += unlabelledArg + getArgumentTypeName(idx - 1);
34723477
}
34733478
}
34743479
}
34753480
}
34763481
} else {
3477-
subscriptText += unlabelledArg + argumentTypeNames[0];
3482+
subscriptText += unlabelledArg + getArgumentTypeName(0);
34783483
}
34793484
return subscriptText + ")";
34803485
}

test/Interpreter/keypath.swift

Lines changed: 26 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,14 @@ print(\Controller.thirdLabel)
95110
print(\Controller.[])
96111
// CHECK: \Controller.self
97112
print(\Controller.self)
113+
114+
// Subscripts with dependent generic types don't produce good output currently,
115+
// so we're just checking to make sure they don't crash.
116+
// CHECK: \Controller.
117+
print(\Controller[[42]])
118+
// CHECK: Controller.
119+
print(\Controller[[42], [42]])
120+
// CHECK: \Controller.
121+
print(\Controller[array: [42]])
122+
// CHECK: \Controller.
123+
print(\Controller[array: [42], array2: [42]])

test/stdlib/symbol-visibility-linux.test-sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
// RUN: -e _ZSt9call_onceIRFvPvEJDnEEvRSt9once_flagOT_DpOT0_ \
3838
// RUN: -e _ZNKSt8functionIFSsmmEEclEmm \
3939
// RUN: -e _ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_realloc_insertIJS5_EEEvN9__gnu_cxx17__normal_iteratorIPS5_S7_EEDpOT_ \
40+
// RUN: -e _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_OS8_ \
4041
// RUN: -e _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_ \
4142
// RUN: > %t/swiftCore-all.txt
4243
// RUN: %llvm-nm --defined-only --extern-only --no-weak %platform-dylib-dir/%target-library-name(swiftCore) > %t/swiftCore-no-weak.txt
@@ -67,6 +68,7 @@
6768
// RUN: -e _ZSt9call_onceIRFvPvEJDnEEvRSt9once_flagOT_DpOT0_ \
6869
// RUN: -e _ZNKSt8functionIFSsmmEEclEmm \
6970
// RUN: -e _ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_realloc_insertIJS5_EEEvN9__gnu_cxx17__normal_iteratorIPS5_S7_EEDpOT_ \
71+
// RUN: -e _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_OS8_ \
7072
// RUN: -e _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_ \
7173
// RUN: > %t/swiftRemoteMirror-all.txt
7274
// RUN: %llvm-nm --defined-only --extern-only --no-weak %platform-dylib-dir/%target-library-name(swiftRemoteMirror) > %t/swiftRemoteMirror-no-weak.txt

0 commit comments

Comments
 (0)