]> granicus.if.org Git - clang/commitdiff
[CodeGen] Provide source locations for UBSan type checks when emitting constructor...
authorIgor Kudrin <ikudrin@accesssoftek.com>
Mon, 25 Jun 2018 05:48:04 +0000 (05:48 +0000)
committerIgor Kudrin <ikudrin@accesssoftek.com>
Mon, 25 Jun 2018 05:48:04 +0000 (05:48 +0000)
Differential Revision: https://reviews.llvm.org/D48531

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

lib/CodeGen/CGClass.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/ubsan-ctor-srcloc.cpp [new file with mode: 0644]

index db947d6514a4287133d1194b6541a998a0092095..11a327d2d2f66aab10ee2cb2607e8d8826993256 100644 (file)
@@ -2031,7 +2031,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
                /*ParamsToSkip*/ 0, Order);
 
   EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args,
-                         Overlap);
+                         Overlap, E->getExprLoc());
 }
 
 static bool canEmitDelegateCallArgs(CodeGenFunction &CGF,
@@ -2064,14 +2064,14 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
                                              bool Delegating,
                                              Address This,
                                              CallArgList &Args,
-                                             AggValueSlot::Overlap_t Overlap) {
+                                             AggValueSlot::Overlap_t Overlap,
+                                             SourceLocation Loc) {
   const CXXRecordDecl *ClassDecl = D->getParent();
 
   // 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.
-  // FIXME: Provide a source location here.
-  EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, SourceLocation(),
+  EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc,
                 This.getPointer(), getContext().getRecordType(ClassDecl));
 
   if (D->isTrivial() && D->isDefaultConstructor()) {
@@ -2180,7 +2180,8 @@ void CodeGenFunction::EmitInheritedCXXConstructorCall(
   }
 
   EmitCXXConstructorCall(D, Ctor_Base, ForVirtualBase, /*Delegating*/false,
-                         This, Args, AggValueSlot::MayOverlap);
+                         This, Args, AggValueSlot::MayOverlap,
+                         E->getLocation());
 }
 
 void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall(
@@ -2277,7 +2278,7 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
                /*ParamsToSkip*/ 1);
 
   EmitCXXConstructorCall(D, Ctor_Complete, false, false, This, Args,
-                         AggValueSlot::MayOverlap);
+                         AggValueSlot::MayOverlap, E->getExprLoc());
 }
 
 void
@@ -2313,7 +2314,7 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
 
   EmitCXXConstructorCall(Ctor, CtorType, /*ForVirtualBase=*/false,
                          /*Delegating=*/true, This, DelegateArgs,
-                         AggValueSlot::MayOverlap);
+                         AggValueSlot::MayOverlap, Loc);
 }
 
 namespace {
index d713cb4c6fbeba6256c14e4a6db741230a5beb41..afe199c4eb5fab23f9e5298e8c469d3ca6ef0fd5 100644 (file)
@@ -2362,7 +2362,8 @@ public:
   void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
                               bool ForVirtualBase, bool Delegating,
                               Address This, CallArgList &Args,
-                              AggValueSlot::Overlap_t Overlap);
+                              AggValueSlot::Overlap_t Overlap,
+                              SourceLocation Loc);
 
   /// Emit assumption load for all bases. Requires to be be called only on
   /// most-derived class and not under construction of the object.
diff --git a/test/CodeGenCXX/ubsan-ctor-srcloc.cpp b/test/CodeGenCXX/ubsan-ctor-srcloc.cpp
new file mode 100644 (file)
index 0000000..da27a66
--- /dev/null
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=alignment -fblocks %s -o %t.ll
+// RUN: FileCheck -check-prefix=ZEROINIT < %t.ll %s
+// RUN: FileCheck -check-prefix=SRCLOC < %t.ll %s
+// ZEROINIT-NOT: @{{.+}} = private unnamed_addr global {{.+}} zeroinitializer
+
+struct A {
+  A(int);
+  int k;
+};
+
+struct B : A {
+  B();
+  B(const B &);
+// SRCLOC-DAG: @{{.+}} = private unnamed_addr global {{.+}} @.src, i32 [[@LINE+1]], i32 12 }
+  using A::A;
+  void f() const;
+};
+
+// SRCLOC-DAG: @{{.+}} = private unnamed_addr global {{.+}} @.src, i32 [[@LINE+1]], i32 10 }
+B::B() : A(1) {}
+
+void foo() {
+  B b(2);
+// SRCLOC-DAG: @{{.+}} = private unnamed_addr global {{.+}} @.src, i32 [[@LINE+1]], i32 5 }
+  ^{b.f();}();
+}