On Thu, Jun 02, 2016 at 11:14:48AM -0400, Jason Merrill wrote: > On Thu, Jun 2, 2016 at 8:13 AM, Jakub Jelinek <ja...@redhat.com> wrote: > > When cp_fold is called on INDIRECT_REF and ARRAY*_REF and any of the > > arguments change in the recursive calls, we fail to copy TREE_THIS_VOLATILE > > flag. > > > > PR c++/71372 > > * cp-gimplify.c (cp_fold): For INDIRECT_REF, if the folded > > expression > > is INDIRECT_REF or MEM_REF, copy over TREE_READONLY, > > TREE_SIDE_EFFECTS > > and TREE_THIS_VOLATILE flags. For ARRAY_REF and ARRAY_RANGE_REF, > > copy > > over TREE_READONLY, TREE_SIDE_EFFECTS and TREE_THIS_VOLATILE flags > > to the newly built tree. > > Hmm, maybe we should be using build_indirect_ref and build_array_ref.
Those look too much front-endish to me (having lots of diagnostics etc. in them for something that should have been already long diagnosed). > Or perhaps factor the simple build and set flags out of > cp_build_indirect_ref and call that. > > If you don't feel like making that change, the patch is also OK as is. I've tried to follow what the C FE does here: if (op0 != orig_op0 && code == ADDR_EXPR && (op1 = get_base_address (op0)) != NULL_TREE && INDIRECT_REF_P (op1) && TREE_CONSTANT (TREE_OPERAND (op1, 0))) ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0)); else if (op0 != orig_op0 || in_init) ret = in_init ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0) : fold_build1_loc (loc, code, TREE_TYPE (expr), op0); else ret = fold (expr); if (code == INDIRECT_REF && ret != expr && INDIRECT_REF_P (ret)) { TREE_READONLY (ret) = TREE_READONLY (expr); TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr); TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); } and similar. Note, we have also the same problem in fold-const.c (fold), though we'd hit that more rarely than this, and there we also should just copy the flags. Jakub