Skip to content

Commit 8175a71

Browse files
plafosseclaude
andcommitted
GNU3 demangler: fix substitution table for unscoped template names and sr intermediate qualifiers
Two missing substitution table entries caused out-of-range access (SG_=17) when decoding symbols like std::swap<T> with enable_if/enable_if constraints: 1. DemangleName case 'S': after processing template args for an unscoped name (e.g. St 4swap I...E), the encoder pushes BOTH the prefix (std::swap) AND the full instantiation (std::swap<T>) to the substitution table. We were only pushing the prefix. Fixed by adding PushType(type) after template args are appended. 2. DemangleExpression sr else branch: when processing a multi-level sr scope without the N prefix (e.g. sr St 6__and_ I...E ...), intermediate template qualifiers must be pushed to the substitution table. Previously the while loop appended to 'out' but never called PushType, unlike the N-prefix branch. Fixed by adding PushType(CreateUnknownType(...)) for intermediate qualifiers. Reduces failures from 211 to 90 on the 178,883-symbol test corpus (99.95%). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b381baf commit 8175a71

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

demangler/gnu3/demangle_gnu3.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,9 @@ string DemangleGNU3::DemangleExpression()
18591859
if (isdigit(m_reader.Peek()))
18601860
{
18611861
// Another source name follows — intermediate qualifier.
1862+
// Push to the substitution table, mirroring what the
1863+
// N-prefix sr branch does for each nested qualifier.
1864+
PushType(CreateUnknownType(out + segName + GetTemplateString(args)));
18621865
out += segName + GetTemplateString(args) + "::";
18631866
}
18641867
else
@@ -2243,6 +2246,11 @@ DemangledTypeNode DemangleGNU3::DemangleName()
22432246
DemangleTemplateArgs(args);
22442247
ExtendTypeName(type, GetTemplateString(args));
22452248
type.SetHasTemplateArguments(true);
2249+
// Push the template instantiation (e.g. std::swap<T>) so that the
2250+
// substitution table matches what the encoder built. The encoder adds
2251+
// both the unscoped-template-name (prefix, already pushed above) and
2252+
// the full template-id (instantiation).
2253+
PushType(type);
22462254
}
22472255
break;
22482256
case 'N': //<nested-name>

0 commit comments

Comments
 (0)