Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[abi] Declaring class of a member-like friend method is not mangled. #110088

Closed
VitaNuo opened this issue Sep 26, 2024 · 2 comments · Fixed by #110247 or #110503
Closed

[abi] Declaring class of a member-like friend method is not mangled. #110088

VitaNuo opened this issue Sep 26, 2024 · 2 comments · Fixed by #110247 or #110503
Assignees
Labels
ABI Application Binary Interface clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts libc++abi libc++abi C++ Runtime Library. Not libc++. tools:llvm-cxxfilt

Comments

@VitaNuo
Copy link
Contributor

VitaNuo commented Sep 26, 2024

The code sample

template <class>
concept True = true;

namespace test2 {
 template<typename T> struct A {
    template<typename U = void>
    friend void g(...) requires True<T> && True<U> {}
 };

 void call() {
    A<int> ai;
    A<bool> ab;
    g(ai);
    g(ab);
 }
}

does not compile with the following error

Output of x86-64 clang (trunk) (Compiler #1)
<source>:10:17: error: definition with same mangled name '_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E' as another definition
   10 |     friend void g(...) requires True<T> && True<U> {}
      |                 ^
<source>:10:17: note: previous definition is here
1 error generated.
Compiler returned: 1

The reason appears to be that the enclosing class template specialization A<int> (or A<bool>, respectively) is not part of the mangled name _ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E, resulting in g(ai) and g(ab) mangled as the same string.

As per the discussion in itanium-cxx-abi/cxx-abi#24 (comment), the code above is valid and the solution is to include the declaring class in the mangling. From @rjmccall on the aforementioned issue:

The only viable implementation path I can see, given that nothing in the standard prevents these friend declarations from otherwise matching perfectly in signatures and requires-clauses, is to mangle the declaring class for these friends.

Note 1: gcc can compile the above snippet by including the declaring class in the mangling, which results in the mangled string _ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E for g(ai) (Note AIiE mangles the declaring class), and _ZN5test21AIbEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E for g(ab) (Note AIbE mangles the declaring class).

Note 2: this issue stands in the way of implementing the demangling of template parameters in constraints (https://github.com/llvm/llvm-project/blob/main/libcxxabi/src/demangle/ItaniumDemangle.h#L5795).
T_ in _ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E is impossible to demangle, since it is a substitution for the template argument of class A that is not part of the mangling.

@VitaNuo VitaNuo self-assigned this Sep 26, 2024
@VitaNuo VitaNuo added clang Clang issues not falling into any other category libc++abi libc++abi C++ Runtime Library. Not libc++. ABI Application Binary Interface tools:llvm-cxxfilt and removed new issue labels Sep 26, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 26, 2024

@llvm/issue-subscribers-tools-llvm-cxxfilt

Author: Viktoriia Bakalova (VitaNuo)

The code sample
template &lt;class&gt;
concept True = true;

namespace test2 {
 template&lt;typename T&gt; struct A {
    template&lt;typename U = void&gt;
    friend void g(...) requires True&lt;T&gt; &amp;&amp; True&lt;U&gt; {}
 };

 void call() {
    A&lt;int&gt; ai;
    A&lt;bool&gt; ab;
    g(ai);
    g(ab);
 }
}

does not compile with the following error

Output of x86-64 clang (trunk) (Compiler #<!-- -->1)
&lt;source&gt;:10:17: error: definition with same mangled name '_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E' as another definition
   10 |     friend void g(...) requires True&lt;T&gt; &amp;&amp; True&lt;U&gt; {}
      |                 ^
&lt;source&gt;:10:17: note: previous definition is here
1 error generated.
Compiler returned: 1

The reason appears to be that the enclosing class template specialization A&lt;int&gt; (or A&lt;bool&gt;, respectively) is not part of the mangled name _ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E, resulting in g(ai) and g(ab) mangled as the same string.

As per the discussion in itanium-cxx-abi/cxx-abi#24 (comment), the code above is valid and the solution is to include the declaring class in the mangling. From @rjmccall on the aforementioned issue:

The only viable implementation path I can see, given that nothing in the standard prevents these friend declarations from otherwise matching perfectly in signatures and requires-clauses, is to mangle the declaring class for these friends.

Note 1: gcc can compile the above snippet by including the declaring class in the mangling, which results in the mangled string _ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E for g(ai) (Note AIiE mangles the declaring class), and _ZN5test21AIbEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E for g(ab) (Note AIbE mangles the declaring class).

Note 2: this issue stands in the way of implementing the demangling of template parameters in constraints (https://github.com/llvm/llvm-project/blob/main/libcxxabi/src/demangle/ItaniumDemangle.h#L5795).
T_ in _ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E is impossible to demangle, since it is a substitution for the template argument of class A that is not part of the mangling.

@usx95 usx95 added the concepts C++20 concepts label Sep 27, 2024
@VitaNuo VitaNuo reopened this Sep 30, 2024
@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed clang Clang issues not falling into any other category labels Sep 30, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 30, 2024

@llvm/issue-subscribers-clang-frontend

Author: Viktoriia Bakalova (VitaNuo)

The code sample
template &lt;class&gt;
concept True = true;

namespace test2 {
 template&lt;typename T&gt; struct A {
    template&lt;typename U = void&gt;
    friend void g(...) requires True&lt;T&gt; &amp;&amp; True&lt;U&gt; {}
 };

 void call() {
    A&lt;int&gt; ai;
    A&lt;bool&gt; ab;
    g(ai);
    g(ab);
 }
}

does not compile with the following error

Output of x86-64 clang (trunk) (Compiler #<!-- -->1)
&lt;source&gt;:10:17: error: definition with same mangled name '_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E' as another definition
   10 |     friend void g(...) requires True&lt;T&gt; &amp;&amp; True&lt;U&gt; {}
      |                 ^
&lt;source&gt;:10:17: note: previous definition is here
1 error generated.
Compiler returned: 1

The reason appears to be that the enclosing class template specialization A&lt;int&gt; (or A&lt;bool&gt;, respectively) is not part of the mangled name _ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E, resulting in g(ai) and g(ab) mangled as the same string.

As per the discussion in itanium-cxx-abi/cxx-abi#24 (comment), the code above is valid and the solution is to include the declaring class in the mangling. From @rjmccall on the aforementioned issue:

The only viable implementation path I can see, given that nothing in the standard prevents these friend declarations from otherwise matching perfectly in signatures and requires-clauses, is to mangle the declaring class for these friends.

Note 1: gcc can compile the above snippet by including the declaring class in the mangling, which results in the mangled string _ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E for g(ai) (Note AIiE mangles the declaring class), and _ZN5test21AIbEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E for g(ab) (Note AIbE mangles the declaring class).

Note 2: this issue stands in the way of implementing the demangling of template parameters in constraints (https://github.com/llvm/llvm-project/blob/main/libcxxabi/src/demangle/ItaniumDemangle.h#L5795).
T_ in _ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E is impossible to demangle, since it is a substitution for the template argument of class A that is not part of the mangling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ABI Application Binary Interface clang:frontend Language frontend issues, e.g. anything involving "Sema" concepts C++20 concepts libc++abi libc++abi C++ Runtime Library. Not libc++. tools:llvm-cxxfilt
Projects
None yet
4 participants