]> granicus.if.org Git - clang/commitdiff
[ms-cxxabi] bitcast to i8* to deref a data member pointer
authorReid Kleckner <reid@kleckner.net>
Thu, 5 Dec 2013 22:44:07 +0000 (22:44 +0000)
committerReid Kleckner <reid@kleckner.net>
Thu, 5 Dec 2013 22:44:07 +0000 (22:44 +0000)
This was causing us to miscompile
llvm::SymbolTableListTraits::getListOwner(), which uses data member
pointers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196545 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenCXX/microsoft-abi-member-pointers.cpp

index 6a45dba9975ad9e2a74425a00777af2394baf569..044e572ed4a811e704c35e2ea2bef03eb033bd94 100644 (file)
@@ -1691,6 +1691,11 @@ MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
     Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset,
                              VBPtrOffset);
   }
+
+  // Cast to char*.
+  Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
+
+  // Apply the offset, which we assume is non-null.
   llvm::Value *Addr =
     Builder.CreateInBoundsGEP(Base, FieldOffset, "memptr.offset");
 
index c0dcd3cf831692ce33234a37b46996553ba66003..dca9f170a909e0df876d78e818415dcd16f7abe0 100644 (file)
@@ -537,3 +537,23 @@ int A::*reinterpret(int C::*mp) {
 }
 
 }
+
+namespace Test3 {
+// Make sure we cast 'this' to i8* before using GEP.
+
+struct A {
+  int a;
+  int b;
+};
+
+int *load_data(A *a, int A::*mp) {
+  return &(a->*mp);
+// CHECK-LABEL: define i32* @"\01?load_data@Test3@@YAPAHPAUA@1@PQ21@H@Z"{{.*}}  {
+// CHECK:    %[[a:.*]] = load %"struct.Test3::A"** %{{.*}}, align 4
+// CHECK:    %[[mp:.*]] = load i32* %{{.*}}, align 4
+// CHECK:    %[[a_i8:.*]] = bitcast %"struct.Test3::A"* %[[a]] to i8*
+// CHECK:    getelementptr inbounds i8* %[[a_i8]], i32 %[[mp]]
+// CHECK: }
+}
+
+}