aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-09-14 19:09:05 -0700
committerRichard Henderson <rth@gcc.gnu.org>2004-09-14 19:09:05 -0700
commit67f236204409bd498339b92c65fdb031344e8e36 (patch)
tree0def536aabaa0d13bd39500073f84cb635da145e
parent5ffcd77909762ca7091b915aef658f28c635ed36 (diff)
downloadgcc-67f236204409bd498339b92c65fdb031344e8e36.zip
gcc-67f236204409bd498339b92c65fdb031344e8e36.tar.gz
gcc-67f236204409bd498339b92c65fdb031344e8e36.tar.bz2
re PR middle-end/17397 (gimplify ICE)
PR middle-end/17397 * gimplify.c (gimplify_addr_expr): Don't inadvertently change types while folding <ADDR_EXPR <INDIRECT_REF X>>. From-SVN: r87528
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimplify.c43
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr17397.c12
3 files changed, 51 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9100659..ff7e392 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-09-14 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/17397
+ * gimplify.c (gimplify_addr_expr): Don't inadvertently change types
+ while folding <ADDR_EXPR <INDIRECT_REF X>>.
+
2004-09-14 Andrew Pinski <apinski@apple.com>
* tree-ssa-copy.c (may_propagate_copy): Don't check the aliasing
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 640e3b0..027fd05 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -74,6 +74,9 @@ typedef struct gimple_temp_hash_elt
/* Forward declarations. */
static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
+#ifdef ENABLE_CHECKING
+static bool cpt_same_type (tree a, tree b);
+#endif
/* Return a hash value for a formal temporary table entry. */
@@ -3051,12 +3054,34 @@ gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
switch (TREE_CODE (op0))
{
case INDIRECT_REF:
+ do_indirect_ref:
/* Check if we are dealing with an expression of the form '&*ptr'.
While the front end folds away '&*ptr' into 'ptr', these
expressions may be generated internally by the compiler (e.g.,
builtins like __builtin_va_end). */
- *expr_p = TREE_OPERAND (op0, 0);
- ret = GS_OK;
+ /* Caution: the silent array decomposition semantics we allow for
+ ADDR_EXPR means we can't always discard the pair. */
+ {
+ tree op00 = TREE_OPERAND (op0, 0);
+ tree t_expr = TREE_TYPE (expr);
+ tree t_op00 = TREE_TYPE (op00);
+
+ if (!lang_hooks.types_compatible_p (t_expr, t_op00))
+ {
+#ifdef ENABLE_CHECKING
+ tree t_op0 = TREE_TYPE (op0);
+ gcc_assert (TREE_CODE (t_op0) == ARRAY_TYPE
+ && POINTER_TYPE_P (t_expr)
+ && cpt_same_type (TREE_TYPE (t_op0),
+ TREE_TYPE (t_expr))
+ && POINTER_TYPE_P (t_op00)
+ && cpt_same_type (t_op0, TREE_TYPE (t_op00)));
+#endif
+ op00 = fold_convert (TREE_TYPE (expr), op00);
+ }
+ *expr_p = op00;
+ ret = GS_OK;
+ }
break;
case VIEW_CONVERT_EXPR:
@@ -3079,14 +3104,12 @@ gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
is_gimple_addressable, fb_either);
if (ret != GS_ERROR)
{
- /* The above may have made an INDIRECT_REF (e.g, Ada's NULL_EXPR),
- so check for it here. It's not worth checking for the other
- cases above. */
- if (TREE_CODE (TREE_OPERAND (expr, 0)) == INDIRECT_REF)
- {
- *expr_p = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
- break;
- }
+ op0 = TREE_OPERAND (expr, 0);
+
+ /* For various reasons, the gimplification of the expression
+ may have made a new INDIRECT_REF. */
+ if (TREE_CODE (op0) == INDIRECT_REF)
+ goto do_indirect_ref;
/* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS
is set properly. */
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr17397.c b/gcc/testsuite/gcc.c-torture/compile/pr17397.c
new file mode 100644
index 0000000..b857472
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr17397.c
@@ -0,0 +1,12 @@
+/* ICE due to invalid GIMPLE created during strlen simplification. */
+
+extern unsigned long strlen (__const char *__s);
+extern void bar ();
+extern int cols;
+
+void foo (void)
+{
+ char s[cols + 2];
+ if (strlen (s) > 0)
+ bar ();
+}