[PATCH] VLA debug info fix (PR debug/42801)

Jakub Jelinek jakub@redhat.com
Mon May 24 20:29:00 GMT 2010


Hi!

On the attached testcase GCC doesn't generate useful debug info
for the VLAs from inlined functions.  There are two issues:
1) the DW_AT_type in the abstract origin obviously can't have
   DW_AT_upper_bound, at least not one with a location.
   Normally we don't emit DW_AT_type when emitting DW_AT_abstract_origin
   attribute - we assume the DW_AT_type from the abstract origin
   is fully useful.  That's not the case for VLAs (or pointers to VLAs
   etc.), where DW_AT_type on the concrete inlined instance can provide
   extra information.  I think the DW_AT_type on the abstract origin
   is useful though (while it doesn't have bounds, it at least says
   what is the element size and that it is an array), so this patch
   just emits the DW_AT_type also alongside of the DW_AT_abstract_origin
   attribute for VLAs when emitting DW_AT_location
2) DW_AT_location wasn't emitted.  The problem is that we have
   "a" variable with DECL_VALUE_EXPR *a.1, but during inlining we
   don't remap the content of DECL_VALUE_EXPR; var-tracking provides
   us with location for a.1 in fn5 or fn6, but DECL_VALUE_EXPR
   still references a.1 from fn2 or fn3 and thus doesn't have any location.
   Richard fixed a similar issue for C++ ctor cloning only (i.e. when
   copying BIND_EXPR) but it is needed also during inlining when there
   is no BIND_EXPR apparently.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2010-05-24  Jakub Jelinek  <jakub@redhat.com>

	PR debug/42801
	* tree-inline.c (remap_decls): Remap DECL_VALUE_EXPR here...
	(copy_bind_expr): ... instead of here.
	(copy_tree_body_r): If id->remapping_type_depth clear TREE_BLOCK
	if the block hasn't been remapped.
	* dwarf2out.c (gen_formal_parameter_die, gen_variable_die): When
	emitting concrete instance of abstract VLA, add DW_AT_type attribute.

	* gcc.dg/guality/sra-2.c: New test.

--- gcc/tree-inline.c.jj	2010-05-24 17:52:25.000000000 +0200
+++ gcc/tree-inline.c	2010-05-24 18:50:16.000000000 +0200
@@ -574,6 +574,19 @@ remap_decls (tree decls, VEC(tree,gc) **
 	  gcc_assert (DECL_P (new_var));
 	  TREE_CHAIN (new_var) = new_decls;
 	  new_decls = new_var;
+ 
+	  /* Also copy value-expressions.  */
+	  if (TREE_CODE (new_var) == VAR_DECL
+	      && DECL_HAS_VALUE_EXPR_P (new_var))
+	    {
+	      tree tem = DECL_VALUE_EXPR (new_var);
+	      bool old_regimplify = id->regimplify;
+	      id->remapping_type_depth++;
+	      walk_tree (&tem, copy_tree_body_r, id, NULL);
+	      id->remapping_type_depth--;
+	      id->regimplify = old_regimplify;
+	      SET_DECL_VALUE_EXPR (new_var, tem);
+	    }
 	}
     }
 
@@ -665,23 +678,9 @@ copy_bind_expr (tree *tp, int *walk_subt
     }
 
   if (BIND_EXPR_VARS (*tp))
-    {
-      tree t;
-
-      /* This will remap a lot of the same decls again, but this should be
-	 harmless.  */
-      BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id);
- 
-      /* Also copy value-expressions.  */
-      for (t = BIND_EXPR_VARS (*tp); t; t = TREE_CHAIN (t))
-	if (TREE_CODE (t) == VAR_DECL
-	    && DECL_HAS_VALUE_EXPR_P (t))
-	  {
-	    tree tem = DECL_VALUE_EXPR (t);
-	    walk_tree (&tem, copy_tree_body_r, id, NULL);
-	    SET_DECL_VALUE_EXPR (t, tem);
-	  }
-    }
+    /* This will remap a lot of the same decls again, but this should be
+       harmless.  */
+    BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id);
 }
 
 
@@ -1116,8 +1115,9 @@ copy_tree_body_r (tree *tp, int *walk_su
 	      tree *n;
 	      n = (tree *) pointer_map_contains (id->decl_map,
 						 TREE_BLOCK (*tp));
-	      gcc_assert (n);
-	      new_block = *n;
+	      gcc_assert (n || id->remapping_type_depth != 0);
+	      if (n)
+		new_block = *n;
 	    }
 	  TREE_BLOCK (*tp) = new_block;
 	}
--- gcc/dwarf2out.c.jj	2010-05-24 17:52:25.000000000 +0200
+++ gcc/dwarf2out.c	2010-05-24 17:58:30.000000000 +0200
@@ -17927,8 +17927,28 @@ gen_formal_parameter_die (tree node, tre
       if (node && node != origin)
         equate_decl_number_to_die (node, parm_die);
       if (! DECL_ABSTRACT (node_or_origin))
-	add_location_or_const_value_attribute (parm_die, node_or_origin,
-					       DW_AT_location);
+	{
+	  if (origin != NULL
+	      && variably_modified_type_p (TREE_TYPE (node_or_origin),
+					   decl_function_context
+							     (node_or_origin)))
+	    {
+	      /* For VLAs add DW_AT_type because it might contain accurate
+		 bounds.  */
+	      tree type = TREE_TYPE (node_or_origin);
+	      if (decl_by_reference_p (node_or_origin))
+		add_type_attribute (parm_die, TREE_TYPE (type),
+				    0, 0, context_die);
+	      else
+		add_type_attribute (parm_die, type,
+				    TREE_READONLY (node_or_origin),
+				    TREE_THIS_VOLATILE (node_or_origin),
+				    context_die);
+	    }
+
+	  add_location_or_const_value_attribute (parm_die, node_or_origin,
+						 DW_AT_location);
+	}
 
       break;
 
@@ -18827,9 +18847,28 @@ gen_variable_die (tree decl, tree origin
           && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin)))
 	defer_location (decl_or_origin, var_die);
       else
-        add_location_or_const_value_attribute (var_die,
-					       decl_or_origin,
-					       DW_AT_location);
+	{
+	  if (origin_die != NULL
+	      && variably_modified_type_p (TREE_TYPE (decl_or_origin),
+					   decl_function_context
+							     (decl_or_origin)))
+	    {
+	      /* For VLAs add DW_AT_type because it might contain accurate
+		 bounds.  */
+	      tree type = TREE_TYPE (decl_or_origin);
+	      if (decl_by_reference_p (decl_or_origin))
+		add_type_attribute (var_die, TREE_TYPE (type),
+				    0, 0, context_die);
+	      else
+		add_type_attribute (var_die, type,
+				    TREE_READONLY (decl_or_origin),
+				    TREE_THIS_VOLATILE (decl_or_origin),
+				    context_die);
+	    }
+	  add_location_or_const_value_attribute (var_die,
+						 decl_or_origin,
+						 DW_AT_location);
+	}
       add_pubname (decl_or_origin, var_die);
     }
   else
--- gcc/testsuite/gcc.dg/guality/sra-2.c.jj	2010-05-24 17:58:30.000000000 +0200
+++ gcc/testsuite/gcc.dg/guality/sra-2.c	2010-05-24 17:58:30.000000000 +0200
@@ -0,0 +1,55 @@
+/* PR debug/42801 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+void __attribute__((noinline))
+fn1 (int *x, int y)
+{
+  asm volatile ("" : : "rm" (x), "rm" (y) : "memory");
+}
+
+static inline __attribute__((always_inline)) int
+fn2 (int i)
+{
+  int a[i];
+  fn1 (a, i);
+  fn1 (a, i);		/* { dg-final { gdb-test 16 "sizeof (a)" "5 * sizeof (int)" } } */
+  return i;
+}
+
+static inline __attribute__((always_inline)) int
+fn3 (int i)
+{
+  int a[i];
+  fn1 (a, i);
+  fn1 (a, i);		/* { dg-final { gdb-test 25 "sizeof (a)" "6 * sizeof (int)" } } */
+  return i;
+}
+
+static inline __attribute__((always_inline)) int
+fn4 (int i)
+{
+  return fn3 (i);
+}
+
+int __attribute__((noinline))
+fn5 (void)
+{
+  return fn2 (5) + 1;
+}
+
+int __attribute__((noinline))
+fn6 (int i)
+{
+  return fn2 (i + 1) + fn4 (i + 2) + fn4 (i + 2) + 1;
+}
+
+int
+main (void)
+{
+  int x = 4;
+  asm volatile ("" : "+r" (x));
+  fn5 ();
+  fn6 (x);
+  return 0;
+}

	Jakub



More information about the Gcc-patches mailing list