diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h index 01f414a7257bf9..45bb741f5629f4 100644 --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -2593,34 +2593,38 @@ Node *AbstractManglingParser::parseName(NameState *State) { if (look() == 'Z') return getDerived().parseLocalName(State); - // ::= - if (look() == 'S' && look(1) != 't') { - Node *S = getDerived().parseSubstitution(); - if (S == nullptr) - return nullptr; - if (look() != 'I') - return nullptr; - Node *TA = getDerived().parseTemplateArgs(State != nullptr); - if (TA == nullptr) - return nullptr; - if (State) State->EndsWithTemplateArgs = true; - return make(S, TA); + Node *Result = nullptr; + bool IsSubst = look() == 'S' && look(1) != 't'; + if (IsSubst) { + // A substitution must lead to: + // ::= + Result = getDerived().parseSubstitution(); + } else { + // An unscoped name can be one of: + // ::= + // ::= + Result = getDerived().parseUnscopedName(State); } - - Node *N = getDerived().parseUnscopedName(State); - if (N == nullptr) + if (Result == nullptr) return nullptr; - // ::= + if (look() == 'I') { - Subs.push_back(N); + // ::= + if (!IsSubst) + // An unscoped-template-name is substitutable. + Subs.push_back(Result); Node *TA = getDerived().parseTemplateArgs(State != nullptr); if (TA == nullptr) return nullptr; - if (State) State->EndsWithTemplateArgs = true; - return make(N, TA); + if (State) + State->EndsWithTemplateArgs = true; + Result = make(Result, TA); + } else if (IsSubst) { + // The substitution case must be followed by . + return nullptr; } - // ::= - return N; + + return Result; } // := Z E [] @@ -2665,13 +2669,17 @@ Node *AbstractManglingParser::parseLocalName(NameState *State) { template Node * AbstractManglingParser::parseUnscopedName(NameState *State) { - if (consumeIf("StL") || consumeIf("St")) { - Node *R = getDerived().parseUnqualifiedName(State); - if (R == nullptr) - return nullptr; - return make(R); - } - return getDerived().parseUnqualifiedName(State); + bool IsStd = consumeIf("St"); + if (IsStd) + consumeIf('L'); + + Node *Result = getDerived().parseUnqualifiedName(State); + if (Result == nullptr) + return nullptr; + if (IsStd) + Result = make(Result); + + return Result; } // ::= [abi-tags] @@ -4066,9 +4074,9 @@ Node *AbstractManglingParser::parseType() { } // ::= # See Compression below case 'S': { - if (look(1) && look(1) != 't') { - Node *Sub = getDerived().parseSubstitution(); - if (Sub == nullptr) + if (look(1) != 't') { + Result = getDerived().parseSubstitution(); + if (Result == nullptr) return nullptr; // Sub could be either of: @@ -4085,13 +4093,13 @@ Node *AbstractManglingParser::parseType() { Node *TA = getDerived().parseTemplateArgs(); if (TA == nullptr) return nullptr; - Result = make(Sub, TA); - break; + Result = make(Result, TA); + } else { + // If all we parsed was a substitution, don't re-insert into the + // substitution table. + return Result; } - - // If all we parsed was a substitution, don't re-insert into the - // substitution table. - return Sub; + break; } DEMANGLE_FALLTHROUGH; } diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp index b1bc05661144a0..7bbb17c581cc19 100644 --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -29855,6 +29855,8 @@ const char* cases[][2] = // This should be invalid, but it is currently not recognized as such // See https://llvm.org/PR51407 {"_Zcv1BIRT_EIS1_E", "operator B<><>"}, + + {"_Z3TPLIiET_S0_", "int TPL(int)"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]); diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h index 98ff73e21cca65..a3a0381edf97d9 100644 --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -2595,34 +2595,38 @@ Node *AbstractManglingParser::parseName(NameState *State) { if (look() == 'Z') return getDerived().parseLocalName(State); - // ::= - if (look() == 'S' && look(1) != 't') { - Node *S = getDerived().parseSubstitution(); - if (S == nullptr) - return nullptr; - if (look() != 'I') - return nullptr; - Node *TA = getDerived().parseTemplateArgs(State != nullptr); - if (TA == nullptr) - return nullptr; - if (State) State->EndsWithTemplateArgs = true; - return make(S, TA); + Node *Result = nullptr; + bool IsSubst = look() == 'S' && look(1) != 't'; + if (IsSubst) { + // A substitution must lead to: + // ::= + Result = getDerived().parseSubstitution(); + } else { + // An unscoped name can be one of: + // ::= + // ::= + Result = getDerived().parseUnscopedName(State); } - - Node *N = getDerived().parseUnscopedName(State); - if (N == nullptr) + if (Result == nullptr) return nullptr; - // ::= + if (look() == 'I') { - Subs.push_back(N); + // ::= + if (!IsSubst) + // An unscoped-template-name is substitutable. + Subs.push_back(Result); Node *TA = getDerived().parseTemplateArgs(State != nullptr); if (TA == nullptr) return nullptr; - if (State) State->EndsWithTemplateArgs = true; - return make(N, TA); + if (State) + State->EndsWithTemplateArgs = true; + Result = make(Result, TA); + } else if (IsSubst) { + // The substitution case must be followed by . + return nullptr; } - // ::= - return N; + + return Result; } // := Z E [] @@ -2667,13 +2671,17 @@ Node *AbstractManglingParser::parseLocalName(NameState *State) { template Node * AbstractManglingParser::parseUnscopedName(NameState *State) { - if (consumeIf("StL") || consumeIf("St")) { - Node *R = getDerived().parseUnqualifiedName(State); - if (R == nullptr) - return nullptr; - return make(R); - } - return getDerived().parseUnqualifiedName(State); + bool IsStd = consumeIf("St"); + if (IsStd) + consumeIf('L'); + + Node *Result = getDerived().parseUnqualifiedName(State); + if (Result == nullptr) + return nullptr; + if (IsStd) + Result = make(Result); + + return Result; } // ::= [abi-tags] @@ -4068,9 +4076,9 @@ Node *AbstractManglingParser::parseType() { } // ::= # See Compression below case 'S': { - if (look(1) && look(1) != 't') { - Node *Sub = getDerived().parseSubstitution(); - if (Sub == nullptr) + if (look(1) != 't') { + Result = getDerived().parseSubstitution(); + if (Result == nullptr) return nullptr; // Sub could be either of: @@ -4087,13 +4095,13 @@ Node *AbstractManglingParser::parseType() { Node *TA = getDerived().parseTemplateArgs(); if (TA == nullptr) return nullptr; - Result = make(Sub, TA); - break; + Result = make(Result, TA); + } else { + // If all we parsed was a substitution, don't re-insert into the + // substitution table. + return Result; } - - // If all we parsed was a substitution, don't re-insert into the - // substitution table. - return Sub; + break; } DEMANGLE_FALLTHROUGH; }