diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2009-09-23 16:29:38 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2009-09-23 16:29:38 +0000 |
commit | dda2da581957d0c0614197a7f0021c95c707f005 (patch) | |
tree | e387ca644e57ba37c6ba41648c7681b7f3ae5c2a | |
parent | b646ba3f1c134c4fc22b000caff77725ccec1791 (diff) | |
download | gcc-dda2da581957d0c0614197a7f0021c95c707f005.zip gcc-dda2da581957d0c0614197a7f0021c95c707f005.tar.gz gcc-dda2da581957d0c0614197a7f0021c95c707f005.tar.bz2 |
re PR debug/41248 (VTA: Assertion at 2910 of cfgexpand.c (expand_debug_locations))
gcc/ChangeLog:
PR debug/41248
* cfgexpand.c (convert_debug_memory_address): New.
(expand_debug_expr): Convert base address and offset to the same
mode. Use it to convert addresses to other modes. Accept
ptr_mode addresses.
gcc/testsuite/ChangeLog:
PR debug/41248
* gcc.dg/pr41248.c: New.
From-SVN: r152087
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 59 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr41248.c | 27 |
4 files changed, 97 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 47bef8c..22941d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-09-23 Alexandre Oliva <aoliva@redhat.com> + + PR debug/41248 + * cfgexpand.c (convert_debug_memory_address): New. + (expand_debug_expr): Convert base address and offset to the same + mode. Use it to convert addresses to other modes. Accept + ptr_mode addresses. + 2009-09-23 Richard Guenther <rguenther@suse.de> * alias.c (ao_ref_from_mem): Correct for negative MEM_OFFSET diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 0ed6bd5..f4a9f5e 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2234,6 +2234,38 @@ unwrap_constant (rtx x) return ret; } +/* Convert X to MODE, that must be Pmode or ptr_mode, without emitting + any rtl. */ + +static rtx +convert_debug_memory_address (enum machine_mode mode, rtx x) +{ + enum machine_mode xmode = GET_MODE (x); + +#ifndef POINTERS_EXTEND_UNSIGNED + gcc_assert (mode == Pmode); + gcc_assert (xmode == mode || xmode == VOIDmode); +#else + gcc_assert (mode == Pmode || mode == ptr_mode); + + if (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode) + return x; + + if (GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (xmode)) + x = simplify_gen_subreg (mode, x, xmode, + subreg_lowpart_offset + (mode, xmode)); + else if (POINTERS_EXTEND_UNSIGNED > 0) + x = gen_rtx_ZERO_EXTEND (mode, x); + else if (!POINTERS_EXTEND_UNSIGNED) + x = gen_rtx_SIGN_EXTEND (mode, x); + else + gcc_unreachable (); +#endif /* POINTERS_EXTEND_UNSIGNED */ + + return x; +} + /* Return an RTX equivalent to the value of the tree expression EXP. */ @@ -2410,6 +2442,7 @@ expand_debug_expr (tree exp) return NULL; gcc_assert (GET_MODE (op0) == Pmode + || GET_MODE (op0) == ptr_mode || GET_CODE (op0) == CONST_INT || GET_CODE (op0) == CONST_DOUBLE); @@ -2436,6 +2469,7 @@ expand_debug_expr (tree exp) return NULL; gcc_assert (GET_MODE (op0) == Pmode + || GET_MODE (op0) == ptr_mode || GET_CODE (op0) == CONST_INT || GET_CODE (op0) == CONST_DOUBLE); @@ -2468,13 +2502,32 @@ expand_debug_expr (tree exp) if (offset) { + enum machine_mode addrmode, offmode; + gcc_assert (MEM_P (op0)); + op0 = XEXP (op0, 0); + addrmode = GET_MODE (op0); + if (addrmode == VOIDmode) + addrmode = Pmode; + op1 = expand_debug_expr (offset); if (!op1) return NULL; - op0 = gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, XEXP (op0, 0), op1)); + offmode = GET_MODE (op1); + if (offmode == VOIDmode) + offmode = TYPE_MODE (TREE_TYPE (offset)); + + if (addrmode != offmode) + op1 = simplify_gen_subreg (addrmode, op1, offmode, + subreg_lowpart_offset (addrmode, + offmode)); + + /* Don't use offset_address here, we don't need a + recognizable address, and we don't want to generate + code. */ + op0 = gen_rtx_MEM (mode, gen_rtx_PLUS (addrmode, op0, op1)); } if (MEM_P (op0)) @@ -2785,7 +2838,9 @@ expand_debug_expr (tree exp) if (!op0 || !MEM_P (op0)) return NULL; - return XEXP (op0, 0); + op0 = convert_debug_memory_address (mode, XEXP (op0, 0)); + + return op0; case VECTOR_CST: exp = build_constructor_from_list (TREE_TYPE (exp), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5fa33fd..4c8e14e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-09-23 Alexandre Oliva <aoliva@redhat.com> + + PR debug/41248 + * gcc.dg/pr41248.c: New. + 2009-09-23 Dodji Seketeli <dodji@redhat.com> PR debug/41065 diff --git a/gcc/testsuite/gcc.dg/pr41248.c b/gcc/testsuite/gcc.dg/pr41248.c new file mode 100644 index 0000000..0d5a749 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr41248.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +struct __gcov_var { + unsigned int offset; + unsigned int buffer[(1 << 10) + 1]; +} __gcov_var; +unsigned int * gcov_write_words (unsigned int words) { + unsigned int *result; + result = &__gcov_var.buffer[__gcov_var.offset]; + return result; +} + +struct gcov_ctr_summary { }; +struct gcov_summary { + unsigned int checksum; + struct gcov_ctr_summary ctrs[1]; +}; +void __gcov_write_unsigned (unsigned int); +void __gcov_write_summary (unsigned int tag, + const struct gcov_summary *summary) +{ + unsigned ix; + const struct gcov_ctr_summary *csum; + __gcov_write_unsigned (summary->checksum); + for (csum = summary->ctrs, ix = 1; ix--; csum++) { } +} |