Skip to content

Commit f5ba3d0

Browse files
committed
[clang] Fix computeTypeLinkageInfo for dependent member pointers (#136689)
MemberPointerType may refer to a dependent class (qualifier), for which getMostRecentCXXRecordDecl returns NULL. It seems that the compiler never executed this code path before patch #136128 where the issue was reported. LIT tests 74 and 75 are reduced from Chromium and LLVM libc test harness as reported in #136128. Function member (test74): MemberPointerType 'type-parameter-0-0 (type-parameter-0-1::*)(void)' dependent |-TemplateTypeParmType 'type-parameter-0-1' dependent depth 0 index 1 `-FunctionProtoType 'type-parameter-0-0 (void)' dependent cdecl `-TemplateTypeParmType 'type-parameter-0-0' dependent depth 0 index 0 Template parameter (test75): MemberPointerType 'type-parameter-0-1 type-parameter-0-0::*' dependent |-TemplateTypeParmType 'type-parameter-0-0' dependent depth 0 index 0 `-TemplateTypeParmType 'type-parameter-0-1' dependent depth 0 index 1
1 parent 0cd3fd4 commit f5ba3d0

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

clang/lib/AST/Type.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4793,8 +4793,12 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
47934793
return computeTypeLinkageInfo(cast<ReferenceType>(T)->getPointeeType());
47944794
case Type::MemberPointer: {
47954795
const auto *MPT = cast<MemberPointerType>(T);
4796-
LinkageInfo LV =
4797-
getDeclLinkageAndVisibility(MPT->getMostRecentCXXRecordDecl());
4796+
LinkageInfo LV;
4797+
if (auto *D = MPT->getMostRecentCXXRecordDecl()) {
4798+
LV.merge(getDeclLinkageAndVisibility(D));
4799+
} else if (auto *Ty = MPT->getQualifier()->getAsType()) {
4800+
LV.merge(computeTypeLinkageInfo(Ty));
4801+
}
47984802
LV.merge(computeTypeLinkageInfo(MPT->getPointeeType()));
47994803
return LV;
48004804
}

clang/test/CodeGenCXX/visibility.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,3 +1463,40 @@ namespace test71 {
14631463
// CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i64 @_ZN6test713fooIlE3zedEv(
14641464
// CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIlE3barIiEET_v(
14651465
}
1466+
1467+
namespace test74 {
1468+
template <typename> struct T;
1469+
template <typename R>
1470+
struct T<void (R::*)()> {
1471+
template <typename M>
1472+
static __attribute__((__visibility__("hidden"))) void Invoke(M) {
1473+
}
1474+
};
1475+
1476+
struct C;
1477+
void (C::*MM)();
1478+
1479+
void Fun() {
1480+
T<decltype(MM)>::Invoke(0);
1481+
}
1482+
// CHECK-LABEL: define linkonce_odr void @_ZN6test741TIMNS_1CEFvvEE6InvokeIiEEvT_(
1483+
// CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test741TIMNS_1CEFvvEE6InvokeIiEEvT_(
1484+
}
1485+
1486+
namespace test75 {
1487+
template <class> struct T;
1488+
template <class C, class Ret>
1489+
struct T<Ret C::*> {
1490+
template <class M>
1491+
static __attribute__((__visibility__("hidden")))
1492+
void Invoke(M) {
1493+
}
1494+
};
1495+
1496+
struct A;
1497+
void Fun() {
1498+
T<void (A::*)()>::Invoke(0);
1499+
}
1500+
// CHECK-LABEL: define linkonce_odr void @_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
1501+
// CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
1502+
}

0 commit comments

Comments
 (0)