diff --git a/gcc/expr.cc b/gcc/expr.cc index fb062dc..a013650 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -11183,6 +11183,13 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, infinitely recurse. */ gcc_assert (tem != exp); + /* If tem is a VAR_DECL, we need a memory reference. */ + enum expand_modifier tem_modifier = modifier; + if (tem_modifier == EXPAND_SUM) + tem_modifier = EXPAND_NORMAL; + if (TREE_CODE (tem) == VAR_DECL) + tem_modifier = EXPAND_MEMORY; + /* If TEM's type is a union of variable size, pass TARGET to the inner computation, since it will need a temporary and TARGET is known to have to do. This occurs in unchecked conversion in Ada. */ @@ -11194,9 +11201,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, != INTEGER_CST) && modifier != EXPAND_STACK_PARM ? target : NULL_RTX), - VOIDmode, - modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier, - NULL, true); + VOIDmode, tem_modifier, NULL, true); /* If the field has a mode, we want to access it in the field's mode, not the computed mode. diff --git a/gcc/testsuite/g++.dg/opt/pr105874.C b/gcc/testsuite/g++.dg/opt/pr105874.C new file mode 100644 index 0000000..58699a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr105874.C @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=c++11" } */ +#include + +static constexpr int NBR_SHIFT = 4; + +static constexpr int MAXBOARDSIZE = 25; + +static constexpr int MAXSQ = ((MAXBOARDSIZE + 2) * (MAXBOARDSIZE + 2)); + +enum square_t : char { + BLACK = 0, WHITE = 1, EMPTY = 2, INVAL = 3 + }; + +const std::array s_eyemask = { + 4 * (1 << (NBR_SHIFT * BLACK)), + 4 * (1 << (NBR_SHIFT * WHITE)) +}; + +/* counts of neighboring stones */ +std::array m_neighbours; + +int is_eye(const int color, const int i) { + /* check for 4 neighbors of the same color */ + int ownsurrounded = (m_neighbours[i] & s_eyemask[color]); + + return ownsurrounded; +} + +/* { dg-final { scan-assembler "s_eyemask" } } */