r223726 - DebugInfo: Correctly identify the location of C++ member initializer list elements

David Blaikie dblaikie at gmail.com
Mon Dec 8 16:32:23 PST 2014


Author: dblaikie
Date: Mon Dec  8 18:32:22 2014
New Revision: 223726

URL: http://llvm.org/viewvc/llvm-project?rev=223726&view=rev
Log:
DebugInfo: Correctly identify the location of C++ member initializer list elements

This particularly helps the fidelity of ASan reports (which can occur
even in these examples - if, for example, one uses placement new over a
buffer of insufficient size - now ASan will correctly identify which
member's initialization went over the end of the buffer).

This doesn't cover all types of members - more coming.

Modified:
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGenCXX/debug-info-line.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=223726&r1=223725&r2=223726&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Mon Dec  8 18:32:22 2014
@@ -597,17 +597,19 @@ static void EmitMemberInitializer(CodeGe
   ArrayRef<VarDecl *> ArrayIndexes;
   if (MemberInit->getNumArrayIndices())
     ArrayIndexes = MemberInit->getArrayIndexes();
-  CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes);
+  CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes,
+                              MemberInit->getMemberLocation());
 }
 
-void CodeGenFunction::EmitInitializerForField(FieldDecl *Field,
-                                              LValue LHS, Expr *Init,
-                                             ArrayRef<VarDecl *> ArrayIndexes) {
+void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS,
+                                              Expr *Init,
+                                              ArrayRef<VarDecl *> ArrayIndexes,
+                                              SourceLocation DbgLoc) {
   QualType FieldType = Field->getType();
   switch (getEvaluationKind(FieldType)) {
   case TEK_Scalar:
     if (LHS.isSimple()) {
-      EmitExprAsInit(Init, Field, LHS, false);
+      EmitExprAsInit(Init, Field, LHS, false, DbgLoc);
     } else {
       RValue RHS = RValue::get(EmitScalarExpr(Init));
       EmitStoreThroughLValue(RHS, LHS);

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=223726&r1=223725&r2=223726&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Dec  8 18:32:22 2014
@@ -596,16 +596,15 @@ static void drillIntoBlockVariable(CodeG
   lvalue.setAddress(CGF.BuildBlockByrefAddress(lvalue.getAddress(), var));
 }
 
-void CodeGenFunction::EmitScalarInit(const Expr *init,
-                                     const ValueDecl *D,
-                                     LValue lvalue,
-                                     bool capturedByInit) {
+void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
+                                     LValue lvalue, bool capturedByInit,
+                                     SourceLocation DbgLoc) {
   Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
   if (!lifetime) {
     llvm::Value *value = EmitScalarExpr(init);
     if (capturedByInit)
       drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
-    EmitStoreThroughLValue(RValue::get(value), lvalue, true);
+    EmitStoreThroughLValue(RValue::get(value), lvalue, true, DbgLoc);
     return;
   }
   
@@ -1192,22 +1191,21 @@ void CodeGenFunction::EmitAutoVarInit(co
 /// \param alignment the alignment of the address
 /// \param capturedByInit true if the variable is a __block variable
 ///   whose address is potentially changed by the initializer
-void CodeGenFunction::EmitExprAsInit(const Expr *init,
-                                     const ValueDecl *D,
-                                     LValue lvalue,
-                                     bool capturedByInit) {
+void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl *D,
+                                     LValue lvalue, bool capturedByInit,
+                                     SourceLocation DbgLoc) {
   QualType type = D->getType();
 
   if (type->isReferenceType()) {
     RValue rvalue = EmitReferenceBindingToExpr(init);
     if (capturedByInit)
       drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
-    EmitStoreThroughLValue(rvalue, lvalue, true);
+    EmitStoreThroughLValue(rvalue, lvalue, true, DbgLoc);
     return;
   }
   switch (getEvaluationKind(type)) {
   case TEK_Scalar:
-    EmitScalarInit(init, D, lvalue, capturedByInit);
+    EmitScalarInit(init, D, lvalue, capturedByInit, DbgLoc);
     return;
   case TEK_Complex: {
     ComplexPairTy complex = EmitComplexExpr(init);

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=223726&r1=223725&r2=223726&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Dec  8 18:32:22 2014
@@ -1437,7 +1437,11 @@ RValue CodeGenFunction::EmitLoadOfGlobal
 /// lvalue, where both are guaranteed to the have the same type, and that type
 /// is 'Ty'.
 void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
-                                             bool isInit) {
+                                             bool isInit,
+                                             SourceLocation DbgLoc) {
+  if (auto *DI = getDebugInfo())
+    DI->EmitLocation(Builder, DbgLoc);
+
   if (!Dst.isSimple()) {
     if (Dst.isVectorElt()) {
       // Read/modify/write the vector, inserting the new element.

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=223726&r1=223725&r2=223726&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Dec  8 18:32:22 2014
@@ -1299,7 +1299,8 @@ public:
                         FunctionArgList &Args);
 
   void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init,
-                               ArrayRef<VarDecl *> ArrayIndexes);
+                               ArrayRef<VarDecl *> ArrayIndexes,
+                               SourceLocation DbgLoc = SourceLocation());
 
   /// InitializeVTablePointer - Initialize the vtable pointer of the given
   /// subobject.
@@ -1543,8 +1544,9 @@ public:
 
   /// EmitExprAsInit - Emits the code necessary to initialize a
   /// location in memory with the given initializer.
-  void EmitExprAsInit(const Expr *init, const ValueDecl *D,
-                      LValue lvalue, bool capturedByInit);
+  void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue,
+                      bool capturedByInit,
+                      SourceLocation DbgLoc = SourceLocation());
 
   /// hasVolatileMember - returns true if aggregate type has a volatile
   /// member.
@@ -1830,8 +1832,9 @@ public:
   /// This function can be called with a null (unreachable) insert point.
   void EmitVarDecl(const VarDecl &D);
 
-  void EmitScalarInit(const Expr *init, const ValueDecl *D,
-                      LValue lvalue, bool capturedByInit);
+  void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue,
+                      bool capturedByInit,
+                      SourceLocation DbgLoc = SourceLocation());
   void EmitScalarInit(llvm::Value *init, LValue lvalue);
 
   typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D,
@@ -2150,7 +2153,8 @@ public:
   /// EmitStoreThroughLValue - Store the specified rvalue into the specified
   /// lvalue, where both are guaranteed to the have the same type, and that type
   /// is 'Ty'.
-  void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false);
+  void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false,
+                              SourceLocation DbgLoc = SourceLocation());
   void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst);
   void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst);
 

Modified: cfe/trunk/test/CodeGenCXX/debug-info-line.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-line.cpp?rev=223726&r1=223725&r2=223726&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-info-line.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/debug-info-line.cpp Mon Dec  8 18:32:22 2014
@@ -1,26 +1,33 @@
 // RUN: %clang_cc1 -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
 
-int src(); int* sink();
+int &src(); int* sink();
 
 void f1() {
 #line 100
   * // The store for the assignment should be attributed to the start of the
     // assignment expression here, regardless of the location of subexpressions.
-  (
-  sink
-  (
-  )
-  +
-  3
-  )
-  =
-  src
-  (
-  )
-  +
-  42
-  ;
-  // CHECK: store {{.*}}, !dbg [[DBG1:!.*]]
+  sink() = src();
+  // CHECK: store {{.*}}, !dbg [[DBG_F1:!.*]]
 }
 
-// CHECK: [[DBG1]] = metadata !{i32 100, {{.*}}
+struct foo {
+  int i;
+  int &j;
+  foo();
+};
+
+foo::foo()
+  :
+#line 200
+    i
+    (src()),
+    j
+    (src())
+    // CHECK: store i32 {{.*}} !dbg [[DBG_FOO_VALUE:!.*]]
+    // CHECK: store i32* {{.*}} !dbg [[DBG_FOO_REF:!.*]]
+{
+}
+
+// CHECK: [[DBG_F1]] = metadata !{i32 100,
+// CHECK: [[DBG_FOO_VALUE]] = metadata !{i32 200,
+// CHECK: [[DBG_FOO_REF]] = metadata !{i32 202,





More information about the cfe-commits mailing list