[clang] [Clang] Add support for GCC bound member functions extension (PR #135649)
Sirui Mu via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 21 21:58:56 PDT 2025
================
@@ -0,0 +1,105 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -Wno-pmf-conversions %s -O3 -emit-llvm -o - | FileCheck %s
+
+struct A {
+ int data;
+//.
+// CHECK: @method = local_unnamed_addr global ptr @_ZN1A6methodEv, align 8
+//.
+// CHECK-LABEL: define linkonce_odr noundef i32 @_ZN1A6methodEv(
+// CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(12) [[THIS:%.*]]) #[[ATTR0:[0-9]+]] comdat align 2 {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret i32 0
+//
+ int method() { return 0; }
+ virtual int virtual_method() { return 1; }
+ virtual ~A() = default;
+};
+
+struct C {
+ int data;
+};
+
+struct B : C, A {
+ virtual int virtual_method() override { return 2; }
+};
+
+using pmf_type = int (A::*)();
+using pf_type = int (*)(A*);
+
+pf_type method = reinterpret_cast<pf_type>(&A::method);
+
+// CHECK-LABEL: define dso_local noundef ptr @_Z11convert_pmfP1AMS_FivE(
+// CHECK-SAME: ptr noundef readonly captures(none) [[P:%.*]], i64 [[METHOD_COERCE0:%.*]], i64 [[METHOD_COERCE1:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[TMP0:%.*]] = and i64 [[METHOD_COERCE0]], 1
+// CHECK-NEXT: [[MEMPTR_ISVIRTUAL_NOT:%.*]] = icmp eq i64 [[TMP0]], 0
+// CHECK-NEXT: br i1 [[MEMPTR_ISVIRTUAL_NOT]], label %[[MEMPTR_NONVIRTUAL:.*]], label %[[MEMPTR_VIRTUAL:.*]]
+// CHECK: [[MEMPTR_VIRTUAL]]:
+// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[METHOD_COERCE1]]
+// CHECK-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP1]], align 8, !tbaa [[TBAA2:![0-9]+]]
+// CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[VTABLE]], i64 [[METHOD_COERCE0]]
+// CHECK-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP2]], i64 -1
+// CHECK-NEXT: [[MEMPTR_VIRTUALFN:%.*]] = load ptr, ptr [[TMP3]], align 8, !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT: br label %[[MEMPTR_END:.*]]
+// CHECK: [[MEMPTR_NONVIRTUAL]]:
+// CHECK-NEXT: [[MEMPTR_NONVIRTUALFN:%.*]] = inttoptr i64 [[METHOD_COERCE0]] to ptr
+// CHECK-NEXT: br label %[[MEMPTR_END]]
----------------
Lancern wrote:
Seems like the non-virtual path does not take into account the offset in the pmf, and unfortunately this is also what gcc is doing. Although this PR is primarily for the virtual path, the erroneous non-virtual path could really cause problems very easily.
https://github.com/llvm/llvm-project/pull/135649
More information about the cfe-commits
mailing list