From 91dcf8d2987d2ab81accd3b090500e5f42c1a7da Mon Sep 17 00:00:00 2001 From: Mike Ash Date: Mon, 30 Jan 2023 14:00:42 -0500 Subject: [PATCH] [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 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 --- lib/Demangling/NodePrinter.cpp | 13 +++++++---- test/Interpreter/keypath.swift | 26 +++++++++++++++++++++ test/stdlib/symbol-visibility-linux.test-sh | 2 ++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index 5949749c4ab5b..65d140dab80e5 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -3407,6 +3407,11 @@ std::string Demangle::keyPathSourceString(const char *MangledName, case Node::Kind::Subscript: { std::string subscriptText = "subscript("; std::vector argumentTypeNames; + auto getArgumentTypeName = [&argumentTypeNames](size_t i) { + if (i < argumentTypeNames.size()) + return argumentTypeNames[i]; + return std::string(""); + }; // Multiple arguments case NodePointer argList = matchSequenceOfKinds( child, { @@ -3454,27 +3459,27 @@ std::string Demangle::keyPathSourceString(const char *MangledName, if (child->getKind() == Node::Kind::LabelList) { size_t numChildren = child->getNumChildren(); if (numChildren == 0) { - subscriptText += unlabelledArg + argumentTypeNames[0]; + subscriptText += unlabelledArg + getArgumentTypeName(0); } else { while (idx < numChildren) { Node *argChild = child->getChild(idx); idx += 1; if (argChild->getKind() == Node::Kind::Identifier) { subscriptText += std::string(argChild->getText()) + ": " + - argumentTypeNames[idx - 1]; + getArgumentTypeName(idx - 1); if (idx != numChildren) { subscriptText += ", "; } } else if (argChild->getKind() == Node::Kind::FirstElementMarker || argChild->getKind() == Node::Kind::VariadicMarker) { - subscriptText += unlabelledArg + argumentTypeNames[idx - 1]; + subscriptText += unlabelledArg + getArgumentTypeName(idx - 1); } } } } } else { - subscriptText += unlabelledArg + argumentTypeNames[0]; + subscriptText += unlabelledArg + getArgumentTypeName(0); } return subscriptText + ")"; } diff --git a/test/Interpreter/keypath.swift b/test/Interpreter/keypath.swift index 6250d2792ea69..e4205980e21bc 100644 --- a/test/Interpreter/keypath.swift +++ b/test/Interpreter/keypath.swift @@ -36,6 +36,21 @@ class Controller { 0 } + subscript(array: [T]) -> T? { + array.first + } + + subscript(array: [T], array2: [U]) -> T? { + array.first + } + + subscript(array array: [T]) -> T? { + array.first + } + + subscript(array array: [T], array2 array2: [U]) -> T? { + array.first + } } struct S { @@ -95,3 +110,14 @@ print(\Controller.thirdLabel) print(\Controller.[]) // CHECK: \Controller.self print(\Controller.self) + +// Subscripts with dependent generic types don't produce good output currently, +// so we're just checking to make sure they don't crash. +// CHECK: \Controller. +print(\Controller[[42]]) +// CHECK: Controller. +print(\Controller[[42], [42]]) +// CHECK: \Controller. +print(\Controller[array: [42]]) +// CHECK: \Controller. +print(\Controller[array: [42], array2: [42]]) diff --git a/test/stdlib/symbol-visibility-linux.test-sh b/test/stdlib/symbol-visibility-linux.test-sh index d923230f4db1a..98edf6ee404f9 100644 --- a/test/stdlib/symbol-visibility-linux.test-sh +++ b/test/stdlib/symbol-visibility-linux.test-sh @@ -37,6 +37,7 @@ // RUN: -e _ZSt9call_onceIRFvPvEJDnEEvRSt9once_flagOT_DpOT0_ \ // RUN: -e _ZNKSt8functionIFSsmmEEclEmm \ // RUN: -e _ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_realloc_insertIJS5_EEEvN9__gnu_cxx17__normal_iteratorIPS5_S7_EEDpOT_ \ +// RUN: -e _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_OS8_ \ // RUN: -e _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_ \ // RUN: > %t/swiftCore-all.txt // 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 @@ // RUN: -e _ZSt9call_onceIRFvPvEJDnEEvRSt9once_flagOT_DpOT0_ \ // RUN: -e _ZNKSt8functionIFSsmmEEclEmm \ // RUN: -e _ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_realloc_insertIJS5_EEEvN9__gnu_cxx17__normal_iteratorIPS5_S7_EEDpOT_ \ +// RUN: -e _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_OS8_ \ // RUN: -e _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_ \ // RUN: > %t/swiftRemoteMirror-all.txt // RUN: %llvm-nm --defined-only --extern-only --no-weak %platform-dylib-dir/%target-library-name(swiftRemoteMirror) > %t/swiftRemoteMirror-no-weak.txt