| Issue |
110088
|
| Summary |
[abi] Declaring class of a member-like friend method is not mangled.
|
| Labels |
new issue
|
| Assignees |
VitaNuo
|
| Reporter |
VitaNuo
|
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 https://github.com/itanium-cxx-abi/cxx-abi/issues/24#issuecomment-934493006, 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.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs