Index: libcxxabi/src/demangle/ItaniumDemangle.h =================================================================== --- libcxxabi/src/demangle/ItaniumDemangle.h +++ libcxxabi/src/demangle/ItaniumDemangle.h @@ -3108,15 +3108,6 @@ Node *SoFar = nullptr; while (!consumeIf('E')) { - consumeIf('L'); // extension - - if (consumeIf('M')) { - // := [] M - if (SoFar == nullptr) - return nullptr; - continue; - } - if (State) // Only set end-with-template on the case that does that. State->EndsWithTemplateArgs = false; @@ -3161,12 +3152,17 @@ return nullptr; continue; // Do not push a new substitution. } else { + consumeIf('L'); // extension // ::= [] SoFar = getDerived().parseUnqualifiedName(State, SoFar); } if (SoFar == nullptr) return nullptr; Subs.push_back(SoFar); + + // No longer used. + // := [] M + consumeIf('M'); } if (SoFar == nullptr || Subs.empty()) Index: libcxxabi/test/test_demangle.pass.cpp =================================================================== --- libcxxabi/test/test_demangle.pass.cpp +++ libcxxabi/test/test_demangle.pass.cpp @@ -29946,6 +29946,9 @@ "_ZN3CLSIiEIiEE", "_ZN3CLSDtLi0EEE", "_ZN3CLSIiEEvNS_T_Ev", + + "_ZN1fIiEEvNTUt_E", + "_ZNDTUt_Ev", }; const unsigned NI = sizeof(invalid_cases) / sizeof(invalid_cases[0]); Index: llvm/include/llvm/Demangle/ItaniumDemangle.h =================================================================== --- llvm/include/llvm/Demangle/ItaniumDemangle.h +++ llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -3108,15 +3108,6 @@ Node *SoFar = nullptr; while (!consumeIf('E')) { - consumeIf('L'); // extension - - if (consumeIf('M')) { - // := [] M - if (SoFar == nullptr) - return nullptr; - continue; - } - if (State) // Only set end-with-template on the case that does that. State->EndsWithTemplateArgs = false; @@ -3161,12 +3152,17 @@ return nullptr; continue; // Do not push a new substitution. } else { + consumeIf('L'); // extension // ::= [] SoFar = getDerived().parseUnqualifiedName(State, SoFar); } if (SoFar == nullptr) return nullptr; Subs.push_back(SoFar); + + // No longer used. + // := [] M + consumeIf('M'); } if (SoFar == nullptr || Subs.empty())