[PATCH] D26559: Insert a type check before reading vtable.

Ivan Krasin via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 14 12:45:03 PST 2016


krasin updated this revision to Diff 77868.
krasin added a comment.

Add a regression test.


https://reviews.llvm.org/D26559

Files:
  lib/CodeGen/CGExprCXX.cpp
  test/CodeGenCXX/ubsan-null.cpp


Index: test/CodeGenCXX/ubsan-null.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/ubsan-null.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=null %s -o - | FileCheck %s
+struct T {
+  virtual int v() { return 1; }
+};
+
+struct U : T {
+  virtual int v() { return 2; }
+};
+
+// CHECK: define i32 @_Z5get_vP1T
+int get_v(T* t) {
+  // CHECK: [[UBSAN_CMP_RES:%[0-9]+]] = icmp ne %struct.T* %{{[_a-z0-9]+}}, null
+  // CHECK-NEXT: br i1 [[UBSAN_CMP_RES]], label %cont, label %handler.type_mismatch
+  // CHECK: call void @__ubsan_handle_type_mismatch_abort
+  // CHECK: load i32 (%struct.T*)**, i32 (%struct.T*)***
+  return t->v();
+}
Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp
+++ lib/CodeGen/CGExprCXX.cpp
@@ -35,17 +35,6 @@
          "Trying to emit a member or operator call expr on a static method!");
   ASTContext &C = CGF.getContext();
 
-  // C++11 [class.mfct.non-static]p2:
-  //   If a non-static member function of a class X is called for an object that
-  //   is not of type X, or of a type derived from X, the behavior is undefined.
-  SourceLocation CallLoc;
-  if (CE)
-    CallLoc = CE->getExprLoc();
-  CGF.EmitTypeCheck(isa<CXXConstructorDecl>(MD)
-                        ? CodeGenFunction::TCK_ConstructorCall
-                        : CodeGenFunction::TCK_MemberCall,
-                    CallLoc, This, C.getRecordType(MD->getParent()));
-
   // Push the this ptr.
   const CXXRecordDecl *RD =
       CGF.CGM.getCXXABI().getThisArgumentTypeForMethod(MD);
@@ -96,6 +85,14 @@
     const CXXDestructorDecl *DD, const CGCallee &Callee, llvm::Value *This,
     llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE,
     StructorType Type) {
+    SourceLocation CallLoc;
+  ASTContext &C = getContext();
+  if (CE)
+    CallLoc = CE->getExprLoc();
+
+  EmitTypeCheck(CodeGenFunction::TCK_MemberCall,
+                CallLoc, This, C.getRecordType(DD->getParent()));
+
   CallArgList Args;
   commonEmitCXXMemberOrOperatorCall(*this, DD, This, ImplicitParam,
                                     ImplicitParamTy, CE, Args, nullptr);
@@ -293,6 +290,19 @@
 
   llvm::FunctionType *Ty = CGM.getTypes().GetFunctionType(*FInfo);
 
+  // C++11 [class.mfct.non-static]p2:
+  //   If a non-static member function of a class X is called for an object that
+  //   is not of type X, or of a type derived from X, the behavior is undefined.
+  SourceLocation CallLoc;
+  ASTContext &C = getContext();
+  if (CE)
+    CallLoc = CE->getExprLoc();
+
+  EmitTypeCheck(isa<CXXConstructorDecl>(CalleeDecl)
+                ? CodeGenFunction::TCK_ConstructorCall
+                : CodeGenFunction::TCK_MemberCall,
+                CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()));
+
   // FIXME: Uses of 'MD' past this point need to be audited. We may need to use
   // 'CalleeDecl' instead.
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D26559.77868.patch
Type: text/x-patch
Size: 3036 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161114/bb9fddde/attachment.bin>


More information about the cfe-commits mailing list