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); +}