================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits