Skip to content

Commit 147558e

Browse files
authored
[clang][ItaniumMangle] Mangle friend function templates with a constr… (#110247)
…aint that depends on a template parameter from an enclosing template as members of the enclosing class. Such function templates should be considered member-like constrained friends per [temp.friend]p9 and itanium-cxx-abi/cxx-abi#24 (comment)).
1 parent 0d384fe commit 147558e

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ Bug Fixes to C++ Support
447447
- Fixed an assertion failure in debug mode, and potential crashes in release mode, when
448448
diagnosing a failed cast caused indirectly by a failed implicit conversion to the type of the constructor parameter.
449449
- Fixed an assertion failure by adjusting integral to boolean vector conversions (#GH108326)
450+
- Mangle friend function templates with a constraint that depends on a template parameter from an enclosing template as members of the enclosing class. (#GH110247)
450451

451452
Bug Fixes to AST Handling
452453
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ ItaniumMangleContextImpl::getEffectiveDeclContext(const Decl *D) {
693693
if (VD->isExternC())
694694
return getASTContext().getTranslationUnitDecl();
695695

696-
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
696+
if (const auto *FD = D->getAsFunction()) {
697697
if (FD->isExternC())
698698
return getASTContext().getTranslationUnitDecl();
699699
// Member-like constrained friends are mangled as if they were members of

clang/test/CodeGenCXX/mangle-concept.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,30 +52,53 @@ namespace test2 {
5252
};
5353

5454
A<int> ai;
55+
A<bool> aj;
5556

5657
// CHECK-LABEL: define {{.*}}@{{.*}}test2{{.*}}use
5758
void use() {
5859
// CHECK: call {{.*}}@_ZN5test21AIiEF1fEzQ4TrueIT_E(
5960
// CLANG17: call {{.*}}@_ZN5test21fEz(
6061
f(ai);
61-
// CHECK: call {{.*}}@_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E(
62+
// CHECK: call {{.*}}@_ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E(
6263
// CLANG17: call {{.*}}@_ZN5test21gIvEEvz(
6364
g(ai);
6465
// CHECK: call {{.*}}@_ZN5test21hIvEEvzQ4TrueITL0__E(
6566
// CLANG17: call {{.*}}@_ZN5test21hIvEEvz(
6667
h(ai);
67-
// CHECK: call {{.*}}@_ZN5test2F1iIvQaa4TrueIT_E4TrueITL0__EEEvz(
68+
// CHECK: call {{.*}}@_ZN5test21AIiEF1iIvQaa4TrueIT_E4TrueITL0__EEEvz(
6869
// CLANG17: call {{.*}}@_ZN5test21iIvEEvz(
6970
i(ai);
7071
// CHECK: call {{.*}}@_ZN5test21jIvQ4TrueITL0__EEEvz(
7172
// CLANG17: call {{.*}}@_ZN5test21jIvEEvz(
7273
j(ai);
73-
// CHECK: call {{.*}}@_ZN5test2F1kITk4TruevQ4TrueIT_EEEvz(
74+
// CHECK: call {{.*}}@_ZN5test21AIiEF1kITk4TruevQ4TrueIT_EEEvz(
7475
// CLANG17: call {{.*}}@_ZN5test21kIvEEvz(
7576
k(ai);
7677
// CHECK: call {{.*}}@_ZN5test21lITk4TruevEEvz(
7778
// CLANG17: call {{.*}}@_ZN5test21lIvEEvz(
7879
l(ai);
80+
81+
// CHECK: call {{.*}}@_ZN5test21AIbEF1fEzQ4TrueIT_E(
82+
// CLANG17: call {{.*}}@_ZN5test21fEz(
83+
f(aj);
84+
// CHECK: call {{.*}}@_ZN5test21AIbEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E(
85+
// CLANG17: call {{.*}}@_ZN5test21gIvEEvz(
86+
g(aj);
87+
// CHECK: call {{.*}}@_ZN5test21hIvEEvzQ4TrueITL0__E(
88+
// CLANG17: call {{.*}}@_ZN5test21hIvEEvz(
89+
h(aj);
90+
// CHECK: call {{.*}}@_ZN5test21AIbEF1iIvQaa4TrueIT_E4TrueITL0__EEEvz(
91+
// CLANG17: call {{.*}}@_ZN5test21iIvEEvz(
92+
i(aj);
93+
// CHECK: call {{.*}}@_ZN5test21jIvQ4TrueITL0__EEEvz(
94+
// CLANG17: call {{.*}}@_ZN5test21jIvEEvz(
95+
j(aj);
96+
// CHECK: call {{.*}}@_ZN5test21AIbEF1kITk4TruevQ4TrueIT_EEEvz(
97+
// CLANG17: call {{.*}}@_ZN5test21kIvEEvz(
98+
k(aj);
99+
// CHECK: call {{.*}}@_ZN5test21lITk4TruevEEvz(
100+
// CLANG17: call {{.*}}@_ZN5test21lIvEEvz(
101+
l(aj);
79102
}
80103
}
81104

libcxxabi/test/test_demangle.pass.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30128,11 +30128,15 @@ const char* cases[][2] =
3012830128
// C++20 concepts, see https://github.com/itanium-cxx-abi/cxx-abi/issues/24.
3012930129
{"_Z2f0IiE1SIX1CIT_EEEv", "S<C<int>> f0<int>()"},
3013030130
{"_ZN5test21AIiEF1fEzQ4TrueIT_E", "test2::A<int>::friend f(...) requires True<T>"},
30131-
{"_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E", "void test2::friend g<void>(...) requires True<T> && True<TL0_>"},
30131+
{"_ZN5test21AIbEF1fEzQ4TrueIT_E", "test2::A<bool>::friend f(...) requires True<T>"},
30132+
{"_ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E", "void test2::A<int>::friend g<void>(...) requires True<T> && True<TL0_>"},
30133+
{"_ZN5test21AIbEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E", "void test2::A<bool>::friend g<void>(...) requires True<T> && True<TL0_>"},
3013230134
{"_ZN5test21hIvEEvzQ4TrueITL0__E", "void test2::h<void>(...) requires True<TL0_>"},
30133-
{"_ZN5test2F1iIvQaa4TrueIT_E4TrueITL0__EEEvz", "void test2::friend i<void>(...)"},
30135+
{"_ZN5test21AIiEF1iIvQaa4TrueIT_E4TrueITL0__EEEvz", "void test2::A<int>::friend i<void>(...)"},
30136+
{"_ZN5test21AIbEF1iIvQaa4TrueIT_E4TrueITL0__EEEvz", "void test2::A<bool>::friend i<void>(...)"},
3013430137
{"_ZN5test21jIvQ4TrueITL0__EEEvz", "void test2::j<void>(...)"},
30135-
{"_ZN5test2F1kITk4TruevQ4TrueIT_EEEvz", "void test2::friend k<void>(...)"},
30138+
{"_ZN5test21AIiEF1kITk4TruevQ4TrueIT_EEEvz", "void test2::A<int>::friend k<void>(...)"},
30139+
{"_ZN5test21AIbEF1kITk4TruevQ4TrueIT_EEEvz", "void test2::A<bool>::friend k<void>(...)"},
3013630140
{"_ZN5test21lITk4TruevEEvz", "void test2::l<void>(...)"},
3013730141
{"_ZN5test31dITnDaLi0EEEvv", "void test3::d<0>()"},
3013830142
{"_ZN5test31eITnDcLi0EEEvv", "void test3::e<0>()"},

0 commit comments

Comments
 (0)