From 9430b7bad813a444e6a7e35d6b5f92d2b99f40cf Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 26 Oct 2012 21:19:25 +0200 Subject: [PATCH] re PR debug/54970 (Missing DW_OP_GNU_implicit_pointer in debuginfo) PR debug/54970 * cfgexpand.c (expand_debug_expr): Expand &MEM_REF[&var, n] as DEBUG_IMPLICIT_PTR + n if &var expands to DEBUG_IMPLICIT_PTR. * tree-sra.c (create_access_replacement): Allow also MEM_REFs with ADDR_EXPR first operand in DECL_DEBUG_EXPR expressions. * var-tracking.c (track_expr_p): Handle MEM_REFs in DECL_DEBUG_EXPR expressions. * dwarf2out.c (add_var_loc_to_decl): Likewise. PR debug/54971 * gcc.dg/guality/pr54970.c: New test. From-SVN: r192860 --- gcc/ChangeLog | 11 ++++++++ gcc/cfgexpand.c | 21 +++++++++++++++ gcc/dwarf2out.c | 5 +++- gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gcc.dg/guality/pr54970.c | 47 ++++++++++++++++++++++++++++++++++ gcc/tree-sra.c | 11 ++++++-- gcc/var-tracking.c | 4 ++- 7 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/guality/pr54970.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f63b2e..7a04872 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2012-10-26 Jakub Jelinek + + PR debug/54970 + * cfgexpand.c (expand_debug_expr): Expand &MEM_REF[&var, n] + as DEBUG_IMPLICIT_PTR + n if &var expands to DEBUG_IMPLICIT_PTR. + * tree-sra.c (create_access_replacement): Allow also MEM_REFs + with ADDR_EXPR first operand in DECL_DEBUG_EXPR expressions. + * var-tracking.c (track_expr_p): Handle MEM_REFs in DECL_DEBUG_EXPR + expressions. + * dwarf2out.c (add_var_loc_to_decl): Likewise. + 2012-10-26 Jeff Law * tree-ssa-threadedge.c (cond_arg_set_in_bb): Use last stmt. diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 4ae1600..ba86eb5 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -3284,6 +3284,27 @@ expand_debug_expr (tree exp) } } + if (TREE_CODE (TREE_OPERAND (exp, 0)) == MEM_REF + && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) + == ADDR_EXPR) + { + op0 = expand_debug_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), + 0)); + if (op0 != NULL + && (GET_CODE (op0) == DEBUG_IMPLICIT_PTR + || (GET_CODE (op0) == PLUS + && GET_CODE (XEXP (op0, 0)) == DEBUG_IMPLICIT_PTR + && CONST_INT_P (XEXP (op0, 1))))) + { + op1 = expand_debug_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), + 1)); + if (!op1 || !CONST_INT_P (op1)) + return NULL; + + return plus_constant (mode, op0, INTVAL (op1)); + } + } + return NULL; } diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 6442edd..24c7506 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -4622,7 +4622,10 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) if (DECL_DEBUG_EXPR_IS_FROM (decl)) { tree realdecl = DECL_DEBUG_EXPR (decl); - if (realdecl && handled_component_p (realdecl)) + if (realdecl + && (handled_component_p (realdecl) + || (TREE_CODE (realdecl) == MEM_REF + && TREE_CODE (TREE_OPERAND (realdecl, 0)) == ADDR_EXPR))) { HOST_WIDE_INT maxsize; tree innerdecl; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4675011..b3b6fac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-10-26 Jakub Jelinek + + PR debug/54970 + PR debug/54971 + * gcc.dg/guality/pr54970.c: New test. + 2012-10-26 Paolo Carlini PR c++/54984 diff --git a/gcc/testsuite/gcc.dg/guality/pr54970.c b/gcc/testsuite/gcc.dg/guality/pr54970.c new file mode 100644 index 0000000..bd940e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr54970.c @@ -0,0 +1,47 @@ +/* PR debug/54970 */ +/* PR debug/54971 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +#include "../nop.h" + +int +main () +{ + int a[] = { 1, 2, 3 }; /* { dg-final { gdb-test 15 "a\[0\]" "1" } } */ + int *p = a + 2; /* { dg-final { gdb-test 15 "a\[1\]" "2" } } */ + int *q = a + 1; /* { dg-final { gdb-test 15 "a\[2\]" "3" } } */ + /* { dg-final { gdb-test 15 "*p" "3" } } */ + asm volatile ("NOP"); /* { dg-final { gdb-test 15 "*q" "2" } } */ + *p += 10; /* { dg-final { gdb-test 20 "a\[0\]" "1" } } */ + /* { dg-final { gdb-test 20 "a\[1\]" "2" } } */ + /* { dg-final { gdb-test 20 "a\[2\]" "13" } } */ + /* { dg-final { gdb-test 20 "*p" "13" } } */ + asm volatile ("NOP"); /* { dg-final { gdb-test 20 "*q" "2" } } */ + *q += 10; /* { dg-final { gdb-test 25 "a\[0\]" "1" } } */ + /* { dg-final { gdb-test 25 "a\[1\]" "12" } } */ + /* { dg-final { gdb-test 25 "a\[2\]" "13" } } */ + /* { dg-final { gdb-test 25 "*p" "13" } } */ + asm volatile ("NOP"); /* { dg-final { gdb-test 25 "*q" "12" } } */ + __builtin_memcpy (&a, (int [3]) { 4, 5, 6 }, sizeof (a)); + /* { dg-final { gdb-test 31 "a\[0\]" "4" } } */ + /* { dg-final { gdb-test 31 "a\[1\]" "5" } } */ + /* { dg-final { gdb-test 31 "a\[2\]" "6" } } */ + /* { dg-final { gdb-test 31 "*p" "6" } } */ + asm volatile ("NOP"); /* { dg-final { gdb-test 31 "*q" "5" } } */ + *p += 20; /* { dg-final { gdb-test 36 "a\[0\]" "4" } } */ + /* { dg-final { gdb-test 36 "a\[1\]" "5" } } */ + /* { dg-final { gdb-test 36 "a\[2\]" "26" } } */ + /* { dg-final { gdb-test 36 "*p" "26" } } */ + asm volatile ("NOP"); /* { dg-final { gdb-test 36 "*q" "5" } } */ + *q += 20; /* { dg-final { gdb-test 45 "a\[0\]" "4" } } */ + /* { dg-final { gdb-test 45 "a\[1\]" "25" } } */ + /* { dg-final { gdb-test 45 "a\[2\]" "26" } } */ + /* { dg-final { gdb-test 45 "*p" "26" } } */ + /* { dg-final { gdb-test 45 "p\[-1\]" "25" } } */ + /* { dg-final { gdb-test 45 "p\[-2\]" "4" } } */ + /* { dg-final { gdb-test 45 "q\[-1\]" "4" } } */ + /* { dg-final { gdb-test 45 "q\[1\]" "26" } } */ + asm volatile ("NOP"); /* { dg-final { gdb-test 45 "*q" "25" } } */ + return 0; +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 65b5ef5..bf1a0f2 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1,7 +1,7 @@ /* Scalar Replacement of Aggregates (SRA) converts some structure references into scalar references, exposing them to the scalar optimizers. - Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Contributed by Martin Jambor This file is part of GCC. @@ -1941,7 +1941,8 @@ create_access_replacement (struct access *access) and that get_ref_base_and_extent works properly on the expression. It cannot handle accesses at a non-constant offset though, so just give up in those cases. */ - for (d = debug_expr; !fail && handled_component_p (d); + for (d = debug_expr; + !fail && (handled_component_p (d) || TREE_CODE (d) == MEM_REF); d = TREE_OPERAND (d, 0)) switch (TREE_CODE (d)) { @@ -1959,6 +1960,12 @@ create_access_replacement (struct access *access) && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST) fail = true; break; + case MEM_REF: + if (TREE_CODE (TREE_OPERAND (d, 0)) != ADDR_EXPR) + fail = true; + else + d = TREE_OPERAND (d, 0); + break; default: break; } diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 25973a9..9b28c7d 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -4921,7 +4921,9 @@ track_expr_p (tree expr, bool need_rtl) realdecl = expr; else if (!DECL_P (realdecl)) { - if (handled_component_p (realdecl)) + if (handled_component_p (realdecl) + || (TREE_CODE (realdecl) == MEM_REF + && TREE_CODE (TREE_OPERAND (realdecl, 0)) == ADDR_EXPR)) { HOST_WIDE_INT bitsize, bitpos, maxsize; tree innerdecl -- 2.7.4