[PATCH] D41036: IRGen: When performing CFI checks, load vtable pointer from vbase when necessary.

2017-12-13 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc added a comment.

Ping.


https://reviews.llvm.org/D41036



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


[PATCH] D41036: IRGen: When performing CFI checks, load vtable pointer from vbase when necessary.

2017-12-13 Thread Peter Collingbourne via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL320638: IRGen: When performing CFI checks, load vtable 
pointer from vbase when… (authored by pcc, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D41036?vs=126220&id=126831#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41036

Files:
  cfe/trunk/lib/CodeGen/CGCXXABI.h
  cfe/trunk/lib/CodeGen/CGClass.cpp
  cfe/trunk/lib/CodeGen/CGExprCXX.cpp
  cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
  cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
  cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
  cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp

Index: cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
===
--- cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
+++ cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-nvcall -fsanitize-trap=cfi-nvcall | FileCheck %s
+
+struct foo {
+  virtual ~foo() {}
+  virtual void f() = 0;
+};
+
+template 
+struct bar : virtual public foo {
+  void f() {}
+};
+
+struct baz : public bar {
+  virtual ~baz() {}
+  void g() {}
+};
+
+void f(baz *z) {
+  // CHECK: define{{.*}}@"\01?f@@YAXPEAUbaz@@@Z"
+  // Load z, vbtable, vbase offset and vtable.
+  // CHECK: load
+  // CHECK: load
+  // CHECK: load
+  // CHECK: load
+  // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+  z->g();
+}
Index: cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
===
--- cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
+++ cfe/trunk/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast | FileCheck %s
+
+struct foo {
+  virtual ~foo() {}
+  virtual void f() = 0;
+};
+
+template 
+struct bar : virtual public foo {
+  void f() {
+// CHECK: define{{.*}}@"\01?f@?$bar@UbazUEAAXXZ"
+// Load "this", vbtable, vbase offset and vtable.
+// CHECK: load
+// CHECK: load
+// CHECK: load
+// CHECK: load
+// CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+static_cast(*this);
+  }
+};
+
+struct baz : public bar {
+  virtual ~baz() {}
+};
+
+int main() {
+  baz *z = new baz;
+  z->f();
+}
Index: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
===
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
@@ -389,6 +389,10 @@
 
   void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
 
+  std::pair
+  LoadVTablePtr(CodeGenFunction &CGF, Address This,
+const CXXRecordDecl *RD) override;
+
  private:
bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const {
  const auto &VtableLayout =
@@ -4041,3 +4045,9 @@
   }
   return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());
 }
+
+std::pair
+ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) {
+  return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
+}
Index: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
===
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -578,7 +578,7 @@
 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
   }
 
-  std::pair
+  std::tuple
   performBaseAdjustment(CodeGenFunction &CGF, Address Value,
 QualType SrcRecordTy);
 
@@ -745,6 +745,10 @@
 
   llvm::GlobalVariable *getThrowInfo(QualType T) override;
 
+  std::pair
+  LoadVTablePtr(CodeGenFunction &CGF, Address This,
+const CXXRecordDecl *RD) override;
+
 private:
   typedef std::pair VFTableIdTy;
   typedef llvm::DenseMap VTablesMapTy;
@@ -926,7 +930,7 @@
 /// We need to perform a generic polymorphic operation (like a typeid
 /// or a cast), which requires an object with a vfptr.  Adjust the
 /// address to point to an object with a vfptr.
-std::pair
+std::tuple
 MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy) {
   Value = CGF.Builder.CreateBitCast(Value, CGF.Int8PtrTy);
@@ -937,7 +941,8 @@
   // covers non-virtual base subobjects: a class with its own virtual
   // functions would be a candidate to be a primary base.
   if (Context.getASTRecordLayout(SrcDecl).hasExtendableVFPtr())
-return std::make_pair(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0));
+return std::make_tuple(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0),
+   SrcDecl);
 
   // Okay, one of the vbases must have a vfptr, or else this isn't
   // actually a polymorphic class.
@@ -956,7 +961,7 @@
   llvm::Value *Pt

[PATCH] D41036: IRGen: When performing CFI checks, load vtable pointer from vbase when necessary.

2017-12-13 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

Looks good!


Repository:
  rL LLVM

https://reviews.llvm.org/D41036



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


[PATCH] D41036: IRGen: When performing CFI checks, load vtable pointer from vbase when necessary.

2017-12-08 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc created this revision.

Under the Microsoft ABI, it is possible for an object not to have
a virtual table pointer of its own if all of its virtual functions
were introduced by virtual bases. In that case, we need to load the
vtable pointer from one of the virtual bases and perform the type
check using its type.


https://reviews.llvm.org/D41036

Files:
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGClass.cpp
  clang/lib/CodeGen/CGExprCXX.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
  clang/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp

Index: clang/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cfi-ms-vbase-nvcall.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-nvcall -fsanitize-trap=cfi-nvcall | FileCheck %s
+
+struct foo {
+  virtual ~foo() {}
+  virtual void f() = 0;
+};
+
+template 
+struct bar : virtual public foo {
+  void f() {}
+};
+
+struct baz : public bar {
+  virtual ~baz() {}
+  void g() {}
+};
+
+void f(baz *z) {
+  // CHECK: define{{.*}}@"\01?f@@YAXPEAUbaz@@@Z"
+  // Load z, vbtable, vbase offset and vtable.
+  // CHECK: load
+  // CHECK: load
+  // CHECK: load
+  // CHECK: load
+  // CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+  z->g();
+}
Index: clang/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cfi-ms-vbase-derived-cast.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -flto -flto-unit -emit-llvm -o - -triple=x86_64-pc-win32 %s -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast | FileCheck %s
+
+struct foo {
+  virtual ~foo() {}
+  virtual void f() = 0;
+};
+
+template 
+struct bar : virtual public foo {
+  void f() {
+// CHECK: define{{.*}}@"\01?f@?$bar@UbazUEAAXXZ"
+// Load "this", vbtable, vbase offset and vtable.
+// CHECK: load
+// CHECK: load
+// CHECK: load
+// CHECK: load
+// CHECK: @llvm.type.test{{.*}}!"?AUfoo@@"
+static_cast(*this);
+  }
+};
+
+struct baz : public bar {
+  virtual ~baz() {}
+};
+
+int main() {
+  baz *z = new baz;
+  z->f();
+}
Index: clang/lib/CodeGen/MicrosoftCXXABI.cpp
===
--- clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -578,7 +578,7 @@
 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
   }
 
-  std::pair
+  std::tuple
   performBaseAdjustment(CodeGenFunction &CGF, Address Value,
 QualType SrcRecordTy);
 
@@ -745,6 +745,10 @@
 
   llvm::GlobalVariable *getThrowInfo(QualType T) override;
 
+  std::pair
+  LoadVTablePtr(CodeGenFunction &CGF, Address This,
+const CXXRecordDecl *RD) override;
+
 private:
   typedef std::pair VFTableIdTy;
   typedef llvm::DenseMap VTablesMapTy;
@@ -926,7 +930,7 @@
 /// We need to perform a generic polymorphic operation (like a typeid
 /// or a cast), which requires an object with a vfptr.  Adjust the
 /// address to point to an object with a vfptr.
-std::pair
+std::tuple
 MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy) {
   Value = CGF.Builder.CreateBitCast(Value, CGF.Int8PtrTy);
@@ -937,7 +941,8 @@
   // covers non-virtual base subobjects: a class with its own virtual
   // functions would be a candidate to be a primary base.
   if (Context.getASTRecordLayout(SrcDecl).hasExtendableVFPtr())
-return std::make_pair(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0));
+return std::make_tuple(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0),
+   SrcDecl);
 
   // Okay, one of the vbases must have a vfptr, or else this isn't
   // actually a polymorphic class.
@@ -956,7 +961,7 @@
   llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP(Value.getPointer(), Offset);
   CharUnits VBaseAlign =
 CGF.CGM.getVBaseAlignment(Value.getAlignment(), SrcDecl, PolymorphicBase);
-  return std::make_pair(Address(Ptr, VBaseAlign), Offset);
+  return std::make_tuple(Address(Ptr, VBaseAlign), Offset, PolymorphicBase);
 }
 
 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
@@ -987,7 +992,7 @@
  QualType SrcRecordTy,
  Address ThisPtr,
  llvm::Type *StdTypeInfoPtrTy) {
-  std::tie(ThisPtr, std::ignore) =
+  std::tie(ThisPtr, std::ignore, std::ignore) =
   performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
   auto Typeid = emitRTtypeidCall(CGF, ThisPtr.getPointer()).getInstruction();
   return CGF.Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
@@ -1011,7 +1016,8 @@
   CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());