Skip to content

Commit 71b2529

Browse files
plafosseclaude
andcommitted
Fix L_Z embedded mangled name in primary expressions
When a template non-type parameter uses a pointer to a function as its value, the Itanium ABI encodes it as L <mangled-name> E inside the template argument. DemanglePrimaryExpression() handled this case via a _Z prefix check, but called DemangleSymbol with m_topLevel=false and without clearing the outer template substitution table. This caused T_ / T0_ / ... references inside the embedded symbol's parameter list to resolve against the outer symbol's template params, not the inner symbol's, leading to a DemangleException and a complete demangling failure for these symbols. Fix: save/clear m_templateSubstitute and set m_topLevel=true before recursing into DemangleSymbol for the embedded name, then restore both afterwards. This mirrors the same pattern used by DemangleLocalName. Also use GetTypeAndName() instead of manually concatenating GetStringBeforeName() + name + GetStringAfterName() to ensure proper spacing between return type and function name. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e010074 commit 71b2529

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

demangler/gnu3/demangle_gnu3.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -960,13 +960,18 @@ string DemangleGNU3::DemanglePrimaryExpression()
960960
if (m_reader.PeekString(2) == "_Z")
961961
{
962962
m_reader.Consume(2);
963+
// The embedded _Z... is an independent mangled name with its own
964+
// template scope. Save and clear the template substitution table
965+
// so inner T_ / T0_ etc. resolve within this symbol, not the outer
966+
// one. Set m_topLevel = true so template args get pushed properly.
967+
auto savedTemplateSubstitute = m_templateSubstitute;
968+
m_templateSubstitute.clear();
963969
oldTopLevel = m_topLevel;
964-
m_topLevel = false;
970+
m_topLevel = true;
965971
DemangledTypeNode t = DemangleSymbol(tmpList);
966972
m_topLevel = oldTopLevel;
967-
out += t.GetStringBeforeName();
968-
out += tmpList.GetString();
969-
out += t.GetStringAfterName();
973+
m_templateSubstitute = std::move(savedTemplateSubstitute);
974+
out += t.GetTypeAndName(tmpList);
970975
dedent()
971976
return out;
972977
}

0 commit comments

Comments
 (0)