Author: Andrew Savonichev
Date: 2025-04-28T15:49:54+09:00
New Revision: f5ba3d0c6d413e46fa962be80cfb37857e35b9ab

URL: 
https://github.com/llvm/llvm-project/commit/f5ba3d0c6d413e46fa962be80cfb37857e35b9ab
DIFF: 
https://github.com/llvm/llvm-project/commit/f5ba3d0c6d413e46fa962be80cfb37857e35b9ab.diff

LOG: [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

Added: 
    

Modified: 
    clang/lib/AST/Type.cpp
    clang/test/CodeGenCXX/visibility.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 111a642173418..d298f1cff73cf 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -4793,8 +4793,12 @@ LinkageInfo 
LinkageComputer::computeTypeLinkageInfo(const Type *T) {
     return computeTypeLinkageInfo(cast<ReferenceType>(T)->getPointeeType());
   case Type::MemberPointer: {
     const auto *MPT = cast<MemberPointerType>(T);
-    LinkageInfo LV =
-        getDeclLinkageAndVisibility(MPT->getMostRecentCXXRecordDecl());
+    LinkageInfo LV;
+    if (auto *D = MPT->getMostRecentCXXRecordDecl()) {
+      LV.merge(getDeclLinkageAndVisibility(D));
+    } else if (auto *Ty = MPT->getQualifier()->getAsType()) {
+      LV.merge(computeTypeLinkageInfo(Ty));
+    }
     LV.merge(computeTypeLinkageInfo(MPT->getPointeeType()));
     return LV;
   }

diff  --git a/clang/test/CodeGenCXX/visibility.cpp 
b/clang/test/CodeGenCXX/visibility.cpp
index e1061f3dbd18f..b4c6fdcbcdf33 100644
--- a/clang/test/CodeGenCXX/visibility.cpp
+++ b/clang/test/CodeGenCXX/visibility.cpp
@@ -1463,3 +1463,40 @@ namespace test71 {
   // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i64 
@_ZN6test713fooIlE3zedEv(
   // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i32 
@_ZN6test713fooIlE3barIiEET_v(
 }
+
+namespace test74 {
+  template <typename> struct T;
+  template <typename R>
+  struct T<void (R::*)()> {
+    template <typename M>
+    static __attribute__((__visibility__("hidden"))) void Invoke(M) {
+    }
+  };
+
+  struct C;
+  void (C::*MM)();
+
+  void Fun() {
+    T<decltype(MM)>::Invoke(0);
+  }
+  // CHECK-LABEL: define linkonce_odr void 
@_ZN6test741TIMNS_1CEFvvEE6InvokeIiEEvT_(
+  // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void 
@_ZN6test741TIMNS_1CEFvvEE6InvokeIiEEvT_(
+}
+
+namespace test75 {
+  template <class> struct T;
+  template <class C, class Ret>
+  struct T<Ret C::*> {
+    template <class M>
+    static __attribute__((__visibility__("hidden")))
+    void Invoke(M) {
+    }
+  };
+
+  struct A;
+  void Fun() {
+    T<void (A::*)()>::Invoke(0);
+  }
+  // CHECK-LABEL: define linkonce_odr void 
@_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
+  // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void 
@_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to