[demangler] Reorder parseNestedName loop

parseNestedName's main loop allowed parsing a grammar that was more
flexible than the actual grammar.  This refactors that to rule out
some more incorrect manglings.

1) The 'L' extension only applies to unqualified-name components, so
check it just there.

2) The 'M' suffix is, AFAICT, removed from the grammar.  Rather than
eliminate it, let's parse it after we've parsed a component.

Added some additional bad mangling tests, which are now rejected.

I don't break the 'T' and 'D[tT]' cases out of the loop, even though
they can only appear at first position, as it seems simpler to just
check there is nothing SoFar.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D119542
This commit is contained in:
Nathan Sidwell 2022-01-25 12:31:01 -08:00
parent 082f328899
commit 6244730e29
3 changed files with 13 additions and 18 deletions

View File

@ -3188,15 +3188,6 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
Node *SoFar = nullptr;
while (!consumeIf('E')) {
consumeIf('L'); // extension
if (consumeIf('M')) {
// <data-member-prefix> := <member source-name> [<template-args>] M
if (SoFar == nullptr)
return nullptr;
continue;
}
if (State)
// Only set end-with-template on the case that does that.
State->EndsWithTemplateArgs = false;
@ -3241,12 +3232,17 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
return nullptr;
continue; // Do not push a new substitution.
} else {
consumeIf('L'); // extension
// ::= [<prefix>] <unqualified-name>
SoFar = getDerived().parseUnqualifiedName(State, SoFar);
}
if (SoFar == nullptr)
return nullptr;
Subs.push_back(SoFar);
// No longer used.
// <data-member-prefix> := <member source-name> [<template-args>] M
consumeIf('M');
}
if (SoFar == nullptr || Subs.empty())

View File

@ -29947,6 +29947,9 @@ const char* invalid_cases[] =
"_ZN3CLSIiEIiEE",
"_ZN3CLSDtLi0EEE",
"_ZN3CLSIiEEvNS_T_Ev",
"_ZN1fIiEEvNTUt_E",
"_ZNDTUt_Ev",
};
const unsigned NI = sizeof(invalid_cases) / sizeof(invalid_cases[0]);

View File

@ -3188,15 +3188,6 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
Node *SoFar = nullptr;
while (!consumeIf('E')) {
consumeIf('L'); // extension
if (consumeIf('M')) {
// <data-member-prefix> := <member source-name> [<template-args>] M
if (SoFar == nullptr)
return nullptr;
continue;
}
if (State)
// Only set end-with-template on the case that does that.
State->EndsWithTemplateArgs = false;
@ -3241,12 +3232,17 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
return nullptr;
continue; // Do not push a new substitution.
} else {
consumeIf('L'); // extension
// ::= [<prefix>] <unqualified-name>
SoFar = getDerived().parseUnqualifiedName(State, SoFar);
}
if (SoFar == nullptr)
return nullptr;
Subs.push_back(SoFar);
// No longer used.
// <data-member-prefix> := <member source-name> [<template-args>] M
consumeIf('M');
}
if (SoFar == nullptr || Subs.empty())