https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101437
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |pinskia at gcc dot gnu.org
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The ICE is because since the above change when we see the empty type volatile
*p = s; store, we gimplify it as s and *p (which seems wrong for volatiles,
because that is load from *p instead of store to *p) and that *p is gimplified
as read from *p into a temporary vol.0 and hits the same case, where we when we
try to gimplify for vol.0 = *p the from_p part *p, we gimplify it as vol.1 = *p
and like that until we eat all of the stack.
The difference between the struct S {}; case that was handled like that forever
and worked fine is in:
else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
&& TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
{
/* Historically, the compiler has treated a bare reference
to a non-BLKmode volatile lvalue as forcing a load. */
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
/* Normally, we do not want to create a temporary for a
TREE_ADDRESSABLE type because such a type should not be
copied by bitwise-assignment. However, we make an
exception here, as all we are doing here is ensuring that
we read the bytes that make up the type. We use
create_tmp_var_raw because create_tmp_var will abort when
given a TREE_ADDRESSABLE type. */
tree tmp = create_tmp_var_raw (type, "vol");
gimple_add_tmp_var (tmp);
gimplify_assign (tmp, *expr_p, pre_p);
*expr_p = NULL;
}
else
/* We can't do anything useful with a volatile reference to
an incomplete type, so just throw it away. Likewise for
a BLKmode type, since any implicit inner load should
already have been turned into an explicit one by the
gimplification process. */
*expr_p = NULL;
The empty struct has BLKmode and so is thrown away, while the struct with
unsigned int : 1; has QImode or so and goes through the "vol" handling.
I guess we should figure out what a volatile load or store of empty non-zero
size type means, if it can be optimized away or not, and depending on that
either add && !is_empty_type (TREE_TYPE (*expr_p)) to the "vol" handling
condition, or stop doing the gimplify_modify_expr optimization if lhs or rhs is
volatile (and either isn't a zero size type or always).