Skip to content

Commit 6689a9c

Browse files
committed
[clang] Fix computeTypeLinkageInfo for non-record member pointers
MemberPointerType can point to records, functions, or types from template parameters. computeTypeLinkageInfo used to expect only records, and crash for anything else. It seems that the compiler never executed this code path before patch llvm#136128 where the issue was reported. 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 For non-record types, it should be enough to look at a pointee type to determine linkage and visibility. LIT tests 74 and 75 are reduced from Chromium and LLVM libc test harness as reported in llvm#136128.
1 parent a095ebc commit 6689a9c

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

clang/lib/AST/Type.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4787,8 +4787,10 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
47874787
return computeTypeLinkageInfo(cast<ReferenceType>(T)->getPointeeType());
47884788
case Type::MemberPointer: {
47894789
const auto *MPT = cast<MemberPointerType>(T);
4790-
LinkageInfo LV =
4791-
getDeclLinkageAndVisibility(MPT->getMostRecentCXXRecordDecl());
4790+
LinkageInfo LV;
4791+
if (auto *D = MPT->getMostRecentCXXRecordDecl()) {
4792+
LV.merge(getDeclLinkageAndVisibility(D));
4793+
}
47924794
LV.merge(computeTypeLinkageInfo(MPT->getPointeeType()));
47934795
return LV;
47944796
}

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)