Skip to content

Conversation

VitaNuo
Copy link
Contributor

@VitaNuo VitaNuo commented Sep 13, 2024

When demangling a template template parameter (method<bool, Bar>(Bar<bool> b)), the current demangler version first enters the template argument (bool) into the substitutions list, then the whole template specialization (Bar<bool>). The template name (Bar) never becomes a substitution candidate on its own.

This is different when mangling. Mangling method<bool, Bar>(Bar<bool> b, Bar<int> i) substitutes the Bar in the second parameter with the substitution for TemplateTemplateParmDecl.

This leads to a discrepancy between mangler and demangler, see #108009.

…emangling.

When demangling a template template parameter (`method<bool, Bar>(Bar<bool> b)`), the current demangler version first enters the template argument (`bool`) into the substitutions list, then the whole template specialization (`Bar<bool>`). The template name (`Bar`) never becomes a substitution candidate on its own.

This is different when mangling. Mangling `method<bool, Bar>(Bar<bool> b, Bar<int> i)` substitutes the `Bar` in the second parameter with the substitution for `TemplateTemplateParmDecl`.

This leads to a discrepancy between mangler and demangler,
see llvm#108009.
@VitaNuo VitaNuo requested a review from a team as a code owner September 13, 2024 11:26
@llvmbot llvmbot added the libc++abi libc++abi C++ Runtime Library. Not libc++. label Sep 13, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 13, 2024

@llvm/pr-subscribers-libcxxabi

Author: Viktoriia Bakalova (VitaNuo)

Changes

…emangling.

When demangling a template template parameter (method&lt;bool, Bar&gt;(Bar&lt;bool&gt; b)), the current demangler version first enters the template argument (bool) into the substitutions list, then the whole template specialization (Bar&lt;bool&gt;). The template name (Bar) never becomes a substitution candidate on its own.

This is different when mangling. Mangling method&lt;bool, Bar&gt;(Bar&lt;bool&gt; b, Bar&lt;int&gt; i) substitutes the Bar in the second parameter with the substitution for TemplateTemplateParmDecl.

This leads to a discrepancy between mangler and demangler, see #108009.


Full diff: https://github.com/llvm/llvm-project/pull/108538.diff

3 Files Affected:

  • (modified) libcxxabi/src/demangle/ItaniumDemangle.h (+1)
  • (modified) libcxxabi/test/test_demangle.pass.cpp (+3)
  • (modified) llvm/include/llvm/Demangle/ItaniumDemangle.h (+1)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 3b041efe3aac00..d1f8da9d6b57b1 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -4336,6 +4336,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
     // parse them, take the second production.
 
     if (TryToParseTemplateArgs && look() == 'I') {
+      Subs.push_back(Result);
       Node *TA = getDerived().parseTemplateArgs();
       if (TA == nullptr)
         return nullptr;
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index 77f79e0d40e84f..44af7e041cbcf4 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -30024,6 +30024,9 @@ const char* cases[][2] =
     // See https://github.com/itanium-cxx-abi/cxx-abi/issues/165.
     {"_ZN1C1fIiEEvDTtlNS_UlT_TL0__E_EEE", "void C::f<int>(decltype(C::'lambda'(int, auto){}))"},
 
+    // See https://github.com/llvm/llvm-project/issues/108009.
+    {"_ZN3FooIiE6methodIb3BarEEvT0_IT_ES3_IiE", "void Foo<int>::method<bool, Bar>(Bar<bool>, Bar<int>)"},
+
     // C++20 class type non-type template parameters:
     {"_Z1fIXtl1BLPi0ELi1EEEEvv", "void f<B{(int*)0, 1}>()"},
     {"_Z1fIXtl1BLPi32EEEEvv", "void f<B{(int*)32}>()"},
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 0af0224bc83fa8..21144bd8c07060 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -4336,6 +4336,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
     // parse them, take the second production.
 
     if (TryToParseTemplateArgs && look() == 'I') {
+      Subs.push_back(Result);
       Node *TA = getDerived().parseTemplateArgs();
       if (TA == nullptr)
         return nullptr;

Copy link
Member

@Michael137 Michael137 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me, thanks!

@ldionne ldionne changed the title [ItaniumDemangle] Add template name to the substituions list during d… [ItaniumDemangle] Add template name to the substituions list during demangling Sep 13, 2024
@ldionne ldionne changed the title [ItaniumDemangle] Add template name to the substituions list during demangling [ItaniumDemangle] Add template name to the substitutions list during demangling Sep 16, 2024
@VitaNuo VitaNuo merged commit 2612316 into llvm:main Sep 23, 2024
62 of 64 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++abi libc++abi C++ Runtime Library. Not libc++.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[abi] method parameter mangled as a substitution does not demangle correctly
3 participants