This is the trunk variant of the 54515 fix - we shouldn't really
return NULL_TREE from get_base_address apart from for invalid
inputs (and then it's just GIGO).  This makes us go half-way to
fix the PR, I'll followup with a patch to look through
WITH_SIZE_EXPR (after thinking about effects on alias analysis).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-09-11  Richard Guenther  <rguent...@suse.de>

        PR middle-end/54515
        * gimple.c (get_base_address): Do not return NULL_TREE apart
        from for WITH_SIZE_EXPR.
        * gimple-fold.c (canonicalize_constructor_val): Do not call
        get_base_address when not necessary.

        * g++.dg/tree-ssa/pr54515.C: New testcase.

Index: gcc/gimple.c
===================================================================
--- gcc/gimple.c        (revision 191143)
+++ gcc/gimple.c        (working copy)
@@ -2878,16 +2878,12 @@ get_base_address (tree t)
       && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
     t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
 
-  if (TREE_CODE (t) == SSA_NAME
-      || DECL_P (t)
-      || TREE_CODE (t) == STRING_CST
-      || TREE_CODE (t) == CONSTRUCTOR
-      || INDIRECT_REF_P (t)
-      || TREE_CODE (t) == MEM_REF
-      || TREE_CODE (t) == TARGET_MEM_REF)
-    return t;
-  else
+  /* ???  Either the alias oracle or all callers need to properly deal
+     with WITH_SIZE_EXPRs before we can look through those.  */
+  if (TREE_CODE (t) == WITH_SIZE_EXPR)
     return NULL_TREE;
+
+  return t;
 }
 
 void
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c   (revision 191143)
+++ gcc/gimple-fold.c   (working copy)
@@ -154,13 +154,15 @@ canonicalize_constructor_val (tree cval,
     }
   if (TREE_CODE (cval) == ADDR_EXPR)
     {
-      tree base = get_base_address (TREE_OPERAND (cval, 0));
-      if (!base && TREE_CODE (TREE_OPERAND (cval, 0)) == COMPOUND_LITERAL_EXPR)
+      tree base = NULL_TREE;
+      if (TREE_CODE (TREE_OPERAND (cval, 0)) == COMPOUND_LITERAL_EXPR)
        {
          base = COMPOUND_LITERAL_EXPR_DECL (TREE_OPERAND (cval, 0));
          if (base)
            TREE_OPERAND (cval, 0) = base;
        }
+      else
+       base = get_base_address (TREE_OPERAND (cval, 0));
       if (!base)
        return NULL_TREE;
 
Index: gcc/testsuite/g++.dg/tree-ssa/pr54515.C
===================================================================
--- gcc/testsuite/g++.dg/tree-ssa/pr54515.C     (revision 0)
+++ gcc/testsuite/g++.dg/tree-ssa/pr54515.C     (working copy)
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-O2" }
+
+template < typename T > T h2le (T)
+{
+    T a;
+    unsigned short &b = a;
+    short c = 0;
+    unsigned char (&d)[2] = reinterpret_cast < unsigned char (&)[2] > (c);
+    unsigned char (&e)[2] = reinterpret_cast < unsigned char (&)[2] > (b);
+    e[0] = d[0];
+    return a;
+}
+
+void
+bar ()
+{
+    h2le ((unsigned short) 0);
+}

Reply via email to