https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121670
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |jason at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The difference is in store_init_value doing 927 const_init = (reduced_constant_expression_p (value) 928 || error_operand_p (value)); 929 DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = const_init; Now, the initializers aren't valid constant expressions due to the reinterpret_cast, which is why we fail to simplify those early. reduced_constant_expression_p under the hood for scalars calls the middle-end initializer_constant_valid_p function, which as an extension will handle some casts, POINTER_PLUS_EXPR etc. In the q0 case the POINTER_PLUS_EXPR second argument is INTEGER_CST 4, so initializer_constant_valid_p is happy with it and we set const_init to true. In the q1 case the POINTER_PLUS_EXPR second argument is SIZEOF_EXPR with NOP_EXPR to int argument (that is the representation of sizeof on types; not folded early for the benefit of -Wsizeof-mem* warnings etc.). But SIZEOF_EXPR is a FE tree that the middle-end has no idea about, so reduced_constant_expression_p returns false. Given that neither of these initializers are valid constant expressions, I wonder if we shouldn't test TREE_CONSTANT (value) && reduced_constant_expression_p (value) instead of just reduced_constant_expression_p (value). BTW, I think we eventually in cp_fully_fold_init will fold the SIZEOF_EXPR, but pedantically it is not initialized by constant expression. And neither is q0 or p.