aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2009-09-23 16:29:38 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2009-09-23 16:29:38 +0000
commitdda2da581957d0c0614197a7f0021c95c707f005 (patch)
treee387ca644e57ba37c6ba41648c7681b7f3ae5c2a
parentb646ba3f1c134c4fc22b000caff77725ccec1791 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cfgexpand.c59
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr41248.c27
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++) { }
+}