[PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
Hi! Here is an attempt to fix these two PRs. The C++ FE already has an LVAL bool that it propagates through constexpr.c functions, or in cp-gimplify.c through calling cp_fold_{maybe_,}rvalue where appropriate. The C c_fully_fold was instead just calling decl_constant_value_for_optimization in some spots where we've previously called c_fully_fold{_internal,} on some rvalue. decl_constant_value_for_optimization wasn't doing anything when -O0, so we got different behavior between -O0 and -O1+ on what is accepted in static initializers. Furthermore, we needed the hack to ignore vars with ARRAY_TYPE or BLKmode, so that we actually wouldn't fold lvalues to rvalues. This patch adds LVAL to c_fully_fold{_internal,} and does what decl_constant_value_for_optimization did inside of it (without the hacks, furthermore, and additionally for -O0 when in initializers for consistency), of course only if LVAL is false. Additionally, I've added folding of "foo"[2] into 'o'. We have it in gimple-fold.c or so, so that one isn't performed when not in_init. Not sure about the COND_EXPR/VEC_COND_EXPR cases, right now I'm passing false as LVAL for the first operand (condition) and lval as LVAL for the other two (i.e. if called with lval == true on the whole *_COND_EXPR decl_constant_value_for_optimization etc. isn't performed on op1/op2, while without it it is). Can one take address of the whole COND_EXPR, or have it on LHS of anything in C? If not, perhaps I could just pass false in all the 3 calls. Though, then likely it would be called with lval == false anyway. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-11-08 Jakub Jelinek PR c/66618 PR c/69960 c-family/ * c-common.h (c_fully_fold): Add LVAL argument defaulted to false. c/ * c-parser.c (c_parser_omp_atomic): Pass true as LVAL to c_fully_fold where needed. * c-typeck.c (build_unary_op, build_modify_expr, build_asm_expr, handle_omp_array_sections): Likewise. (digest_init): Don't call decl_constant_value_for_optimization. * c-tree.h (decl_constant_value_for_optimization): Removed. * c-fold.c (c_fully_fold_internal): Add LVAL argument, propagate it through recursive calls. For VAR_P call decl_constant_value and unshare if not LVAL and either optimizing or IN_INIT. Remove decl_constant_value_for_optimization calls. If IN_INIT and not LVAL, fold ARRAY_REF with STRING_CST and INTEGER_CST operands. (c_fully_fold): Add LVAL argument, pass it through to c_fully_fold_internal. (decl_constant_value_for_optimization): Removed. cp/ * cp-gimplify.c (c_fully_fold): Add LVAL argument, call cp_fold_maybe_rvalue instead of cp_fold_rvalue and pass it !LVAL. testsuite/ * gcc.dg/pr69960.c: New test. * gcc.dg/pr66618.c: New test. --- gcc/c-family/c-common.h.jj 2017-10-12 20:51:30.0 +0200 +++ gcc/c-family/c-common.h 2017-11-08 12:20:59.874481318 +0100 @@ -827,7 +827,7 @@ extern tree c_build_bitfield_integer_typ extern enum conversion_safety unsafe_conversion_p (location_t, tree, tree, tree, bool); extern bool decl_with_nonnull_addr_p (const_tree); -extern tree c_fully_fold (tree, bool, bool *); +extern tree c_fully_fold (tree, bool, bool *, bool = false); extern tree c_wrap_maybe_const (tree, bool); extern tree c_common_truthvalue_conversion (location_t, tree); extern void c_apply_type_quals_to_decl (int, tree); --- gcc/c/c-parser.c.jj 2017-11-08 12:29:02.0 +0100 +++ gcc/c/c-parser.c2017-11-08 13:53:39.756889500 +0100 @@ -14748,7 +14748,7 @@ c_parser_omp_atomic (location_t loc, c_p case NOP_EXPR: /* atomic write */ v = c_parser_cast_expression (parser, NULL).value; non_lvalue_p = !lvalue_p (v); - v = c_fully_fold (v, false, NULL); + v = c_fully_fold (v, false, NULL, true); if (v == error_mark_node) goto saw_error; if (non_lvalue_p) @@ -14767,7 +14767,7 @@ c_parser_omp_atomic (location_t loc, c_p { lhs = c_parser_cast_expression (parser, NULL).value; non_lvalue_p = !lvalue_p (lhs); - lhs = c_fully_fold (lhs, false, NULL); + lhs = c_fully_fold (lhs, false, NULL, true); if (lhs == error_mark_node) goto saw_error; if (non_lvalue_p) @@ -14793,7 +14793,7 @@ c_parser_omp_atomic (location_t loc, c_p { v = c_parser_cast_expression (parser, NULL).value; non_lvalue_p = !lvalue_p (v); - v = c_fully_fold (v, false, NULL); + v = c_fully_fold (v, false, NULL, true); if (v == error_mark_node) goto saw_error; if (non_lvalue_p) @@ -14814,7 +14814,7 @@ restart: lhs = expr.value; expr = default_function_array_conversion (eloc, expr); unfolded_lhs = expr.value; - lhs = c_fully_fold (lhs, false, NULL); + lhs = c_full
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
On 11/09/2017 11:54 AM, Jakub Jelinek wrote: On Wed, Nov 08, 2017 at 06:57:55PM +0100, Jakub Jelinek wrote: On Wed, Nov 08, 2017 at 06:51:34PM +0100, Marek Polacek wrote: Ok, so like this if it passes bootstrap/regtest? Changes from the last patch: 1) false instead of lval for COMPOUND_EXPR and *COND_EXPR op1/op2 So... Oops, I've hand-edited it in the patch and then regenerated the patch after doing there more changes. Here is updated patch with that in again: FYI, bootstrapped/regtested on x86_64-linux and i686-linux successfully. This caused: PR83590 - [nvptx] openacc reduction C regressions ( https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83590 ). Thanks, - Tom
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
On Wed, Nov 08, 2017 at 05:22:45PM +0100, Jakub Jelinek wrote: > Hi! > > Here is an attempt to fix these two PRs. The C++ FE already has an LVAL Nice! > bool that it propagates through constexpr.c functions, or in > cp-gimplify.c through calling cp_fold_{maybe_,}rvalue where appropriate. > The C c_fully_fold was instead just calling > decl_constant_value_for_optimization > in some spots where we've previously called c_fully_fold{_internal,} on > some rvalue. > decl_constant_value_for_optimization wasn't doing anything when -O0, > so we got different behavior between -O0 and -O1+ on what is accepted > in static initializers. Furthermore, we needed the hack to ignore > vars with ARRAY_TYPE or BLKmode, so that we actually wouldn't fold lvalues > to rvalues. > > This patch adds LVAL to c_fully_fold{_internal,} and does what > decl_constant_value_for_optimization did inside of it (without the hacks, > furthermore, and additionally for -O0 when in initializers for consistency), > of course only if LVAL is false. Additionally, I've added folding of > "foo"[2] into 'o'. We have it in gimple-fold.c or so, so that one > isn't performed when not in_init. > > Not sure about the COND_EXPR/VEC_COND_EXPR cases, right now I'm passing > false as LVAL for the first operand (condition) and lval as LVAL for the > other two (i.e. if called with lval == true on the whole *_COND_EXPR > decl_constant_value_for_optimization etc. isn't performed on op1/op2, while > without it it is). Can one take address of the whole COND_EXPR, or > have it on LHS of anything in C? I don't think so, the ?: operator does not yield an lvalue. > @@ -218,12 +235,51 @@ c_fully_fold_internal (tree expr, bool i >op2 = TREE_OPERAND (expr, 2); >op3 = TREE_OPERAND (expr, 3); >op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, > -maybe_const_itself, for_int_const); > +maybe_const_itself, for_int_const, lval); >STRIP_TYPE_NOPS (op0); >op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, > -maybe_const_itself, for_int_const); > +maybe_const_itself, for_int_const, false); >STRIP_TYPE_NOPS (op1); > - op1 = decl_constant_value_for_optimization (op1); > + /* Fold "foo"[2] in initializers. */ > + if (!lval > + && in_init > + && TREE_CODE (op0) == STRING_CST > + && TREE_CODE (op1) == INTEGER_CST > + && TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE Does this also handle 2["foobar"]? > + && tree_fits_uhwi_p (op1)) > + { > + tree ary = op0; > + tree index = op1; > + unsigned len = 0; > + tree elem_type = TREE_TYPE (TREE_TYPE (ary)); > + unsigned elem_nchars = (TYPE_PRECISION (elem_type) > + / TYPE_PRECISION (char_type_node)); > + len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars; > + > + tree nelts = array_type_nelts (TREE_TYPE (ary)); > + bool dummy1 = true, dummy2 = true; > + nelts = c_fully_fold_internal (nelts, in_init, &dummy1, &dummy2, > + for_int_const, false); > + unsigned HOST_WIDE_INT i = tree_to_uhwi (index); > + if (tree_int_cst_le (index, nelts) > + && i < len > + && i + elem_nchars <= len) > + { > + tree type = TREE_TYPE (expr); > + if (elem_nchars == 1) > + ret = build_int_cst (type, > + TREE_STRING_POINTER (ary)[i]); > + else > + { > + const unsigned char *ptr > + = ((const unsigned char *)TREE_STRING_POINTER (ary) > ++ i * elem_nchars); > + ret = native_interpret_expr (type, ptr, elem_nchars); > + } > + if (ret) > + goto out; > + } > + } So this code comes from gimple-fold.c? I would probably move it to a new function. Marek
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
On Wed, Nov 08, 2017 at 05:42:07PM +0100, Marek Polacek wrote: > > Not sure about the COND_EXPR/VEC_COND_EXPR cases, right now I'm passing > > false as LVAL for the first operand (condition) and lval as LVAL for the > > other two (i.e. if called with lval == true on the whole *_COND_EXPR > > decl_constant_value_for_optimization etc. isn't performed on op1/op2, while > > without it it is). Can one take address of the whole COND_EXPR, or > > have it on LHS of anything in C? > > I don't think so, the ?: operator does not yield an lvalue. Ok, I'll pass false then. > > @@ -218,12 +235,51 @@ c_fully_fold_internal (tree expr, bool i > >op2 = TREE_OPERAND (expr, 2); > >op3 = TREE_OPERAND (expr, 3); > >op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, > > - maybe_const_itself, for_int_const); > > + maybe_const_itself, for_int_const, lval); > >STRIP_TYPE_NOPS (op0); > >op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, > > - maybe_const_itself, for_int_const); > > + maybe_const_itself, for_int_const, false); > >STRIP_TYPE_NOPS (op1); > > - op1 = decl_constant_value_for_optimization (op1); > > + /* Fold "foo"[2] in initializers. */ > > + if (!lval > > + && in_init > > + && TREE_CODE (op0) == STRING_CST > > + && TREE_CODE (op1) == INTEGER_CST > > + && TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE > > Does this also handle 2["foobar"]? Yes, because build_array_ref has: 2607 if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE 2608 && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE 2609 /* Allow vector[index] but not index[vector]. */ 2610 && !VECTOR_TYPE_P (TREE_TYPE (array))) 2611{ 2612 if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE 2613 && TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE) 2614{ 2615 error_at (loc, 2616"subscripted value is neither array nor pointer nor vector"); 2617 2618 return error_mark_node; 2619} 2620 std::swap (array, index); 2621 swapped = true; 2622} > > + && tree_fits_uhwi_p (op1)) > > + { > > + tree ary = op0; > > + tree index = op1; > > + unsigned len = 0; > > + tree elem_type = TREE_TYPE (TREE_TYPE (ary)); > > + unsigned elem_nchars = (TYPE_PRECISION (elem_type) > > + / TYPE_PRECISION (char_type_node)); > > + len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars; > > + > > + tree nelts = array_type_nelts (TREE_TYPE (ary)); > > + bool dummy1 = true, dummy2 = true; > > + nelts = c_fully_fold_internal (nelts, in_init, &dummy1, &dummy2, > > +for_int_const, false); > > + unsigned HOST_WIDE_INT i = tree_to_uhwi (index); > > + if (tree_int_cst_le (index, nelts) > > + && i < len > > + && i + elem_nchars <= len) > > + { > > + tree type = TREE_TYPE (expr); > > + if (elem_nchars == 1) > > + ret = build_int_cst (type, > > +TREE_STRING_POINTER (ary)[i]); > > + else > > + { > > + const unsigned char *ptr > > + = ((const unsigned char *)TREE_STRING_POINTER (ary) > > + + i * elem_nchars); > > + ret = native_interpret_expr (type, ptr, elem_nchars); > > + } > > + if (ret) > > + goto out; > > + } > > + } > > So this code comes from gimple-fold.c? I would probably move it to a new > function. No, this comes from very simplified cp/constexpr.c (extract_string_elt, cxx_eval_array_reference). Can outline it into a separate function, sure. Jakub
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
On Wed, 8 Nov 2017, Jakub Jelinek wrote: > of course only if LVAL is false. Additionally, I've added folding of > "foo"[2] into 'o'. We have it in gimple-fold.c or so, so that one Note that if the 2 there comes from an overflowing expression that's not valid as an extension to constant expressions in initializers (that is, static char c = "foo"[INT_MAX * -2]; should result in an error with -pedantic-errors because of the overflow, just as INT_MAX * -2 by itself wouldn't be a valid initializer in that case). > Not sure about the COND_EXPR/VEC_COND_EXPR cases, right now I'm passing > false as LVAL for the first operand (condition) and lval as LVAL for the > other two (i.e. if called with lval == true on the whole *_COND_EXPR > decl_constant_value_for_optimization etc. isn't performed on op1/op2, while > without it it is). Can one take address of the whole COND_EXPR, or > have it on LHS of anything in C? If not, perhaps I could just pass false > in all the 3 calls. Though, then likely it would be called with lval == false > anyway. Conditional and compound expressions are never valid lvalues in C. -- Joseph S. Myers jos...@codesourcery.com
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
On Wed, Nov 08, 2017 at 05:17:50PM +, Joseph Myers wrote: > On Wed, 8 Nov 2017, Jakub Jelinek wrote: > > > of course only if LVAL is false. Additionally, I've added folding of > > "foo"[2] into 'o'. We have it in gimple-fold.c or so, so that one > > Note that if the 2 there comes from an overflowing expression that's not > valid as an extension to constant expressions in initializers (that is, > > static char c = "foo"[INT_MAX * -2]; > > should result in an error with -pedantic-errors because of the overflow, > just as INT_MAX * -2 by itself wouldn't be a valid initializer in that > case). > > > Not sure about the COND_EXPR/VEC_COND_EXPR cases, right now I'm passing > > false as LVAL for the first operand (condition) and lval as LVAL for the > > other two (i.e. if called with lval == true on the whole *_COND_EXPR > > decl_constant_value_for_optimization etc. isn't performed on op1/op2, while > > without it it is). Can one take address of the whole COND_EXPR, or > > have it on LHS of anything in C? If not, perhaps I could just pass false > > in all the 3 calls. Though, then likely it would be called with lval == > > false > > anyway. > > Conditional and compound expressions are never valid lvalues in C. Ok, so like this if it passes bootstrap/regtest? Changes from the last patch: 1) false instead of lval for COMPOUND_EXPR and *COND_EXPR op1/op2 2) outlined the "foo"[2] folding into c_fold_array_ref 3) added !TREE_OVERFLOW check there 4) added another testcase 2017-11-08 Jakub Jelinek PR c/66618 PR c/69960 c-family/ * c-common.h (c_fully_fold): Add LVAL argument defaulted to false. c/ * c-parser.c (c_parser_omp_atomic): Pass true as LVAL to c_fully_fold where needed. * c-typeck.c (build_unary_op, build_modify_expr, build_asm_expr, handle_omp_array_sections): Likewise. (digest_init): Don't call decl_constant_value_for_optimization. * c-tree.h (decl_constant_value_for_optimization): Removed. * c-fold.c (c_fold_array_ref): New function. (c_fully_fold_internal): Add LVAL argument, propagate it through recursive calls. For VAR_P call decl_constant_value and unshare if not LVAL and either optimizing or IN_INIT. Remove decl_constant_value_for_optimization calls. If IN_INIT and not LVAL, fold ARRAY_REF with STRING_CST and INTEGER_CST operands. (c_fully_fold): Add LVAL argument, pass it through to c_fully_fold_internal. (decl_constant_value_for_optimization): Removed. cp/ * cp-gimplify.c (c_fully_fold): Add LVAL argument, call cp_fold_maybe_rvalue instead of cp_fold_rvalue and pass it !LVAL. testsuite/ * gcc.dg/pr69960.c: New test. * gcc.dg/pr66618.c: New test. * gcc.dg/pr66618-2.c: New test. --- gcc/c-family/c-common.h.jj 2017-11-08 16:19:30.309488815 +0100 +++ gcc/c-family/c-common.h 2017-11-08 17:49:00.548178246 +0100 @@ -827,7 +827,7 @@ extern tree c_build_bitfield_integer_typ extern enum conversion_safety unsafe_conversion_p (location_t, tree, tree, tree, bool); extern bool decl_with_nonnull_addr_p (const_tree); -extern tree c_fully_fold (tree, bool, bool *); +extern tree c_fully_fold (tree, bool, bool *, bool = false); extern tree c_wrap_maybe_const (tree, bool); extern tree c_common_truthvalue_conversion (location_t, tree); extern void c_apply_type_quals_to_decl (int, tree); --- gcc/c/c-parser.c.jj 2017-11-08 16:19:30.569485632 +0100 +++ gcc/c/c-parser.c2017-11-08 17:49:00.552178196 +0100 @@ -14748,7 +14748,7 @@ c_parser_omp_atomic (location_t loc, c_p case NOP_EXPR: /* atomic write */ v = c_parser_cast_expression (parser, NULL).value; non_lvalue_p = !lvalue_p (v); - v = c_fully_fold (v, false, NULL); + v = c_fully_fold (v, false, NULL, true); if (v == error_mark_node) goto saw_error; if (non_lvalue_p) @@ -14767,7 +14767,7 @@ c_parser_omp_atomic (location_t loc, c_p { lhs = c_parser_cast_expression (parser, NULL).value; non_lvalue_p = !lvalue_p (lhs); - lhs = c_fully_fold (lhs, false, NULL); + lhs = c_fully_fold (lhs, false, NULL, true); if (lhs == error_mark_node) goto saw_error; if (non_lvalue_p) @@ -14793,7 +14793,7 @@ c_parser_omp_atomic (location_t loc, c_p { v = c_parser_cast_expression (parser, NULL).value; non_lvalue_p = !lvalue_p (v); - v = c_fully_fold (v, false, NULL); + v = c_fully_fold (v, false, NULL, true); if (v == error_mark_node) goto saw_error; if (non_lvalue_p) @@ -14814,7 +14814,7 @@ restart: lhs = expr.value; expr = default_function_array_conversion (eloc, expr); unfolded_lhs = expr.value; - lhs = c_fully_fold (lhs, false, NULL); + lhs = c_fully_fold (lhs, false, NULL, true); orig_lhs = lhs; switch
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
On Wed, Nov 08, 2017 at 06:38:21PM +0100, Jakub Jelinek wrote: > On Wed, Nov 08, 2017 at 05:17:50PM +, Joseph Myers wrote: > > On Wed, 8 Nov 2017, Jakub Jelinek wrote: > > > > > of course only if LVAL is false. Additionally, I've added folding of > > > "foo"[2] into 'o'. We have it in gimple-fold.c or so, so that one > > > > Note that if the 2 there comes from an overflowing expression that's not > > valid as an extension to constant expressions in initializers (that is, > > > > static char c = "foo"[INT_MAX * -2]; > > > > should result in an error with -pedantic-errors because of the overflow, > > just as INT_MAX * -2 by itself wouldn't be a valid initializer in that > > case). > > > > > Not sure about the COND_EXPR/VEC_COND_EXPR cases, right now I'm passing > > > false as LVAL for the first operand (condition) and lval as LVAL for the > > > other two (i.e. if called with lval == true on the whole *_COND_EXPR > > > decl_constant_value_for_optimization etc. isn't performed on op1/op2, > > > while > > > without it it is). Can one take address of the whole COND_EXPR, or > > > have it on LHS of anything in C? If not, perhaps I could just pass false > > > in all the 3 calls. Though, then likely it would be called with lval == > > > false > > > anyway. > > > > Conditional and compound expressions are never valid lvalues in C. > > Ok, so like this if it passes bootstrap/regtest? > > Changes from the last patch: > 1) false instead of lval for COMPOUND_EXPR and *COND_EXPR op1/op2 So... > @@ -278,21 +339,16 @@ c_fully_fold_internal (tree expr, bool i >orig_op0 = op0 = TREE_OPERAND (expr, 0); >orig_op1 = op1 = TREE_OPERAND (expr, 1); >op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, > -maybe_const_itself, for_int_const); > +maybe_const_itself, for_int_const, > +op0_lval); >STRIP_TYPE_NOPS (op0); > - if (code != MODIFY_EXPR > - && code != PREDECREMENT_EXPR > - && code != PREINCREMENT_EXPR > - && code != POSTDECREMENT_EXPR > - && code != POSTINCREMENT_EXPR) > - op0 = decl_constant_value_for_optimization (op0); >/* The RHS of a MODIFY_EXPR was fully folded when building that >expression for the sake of conversion warnings. */ >if (code != MODIFY_EXPR) > op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, > - maybe_const_itself, for_int_const); > + maybe_const_itself, for_int_const, > + code == COMPOUND_EXPR ? lval : false); ...shouldn't we be passing just false here? Marek
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
On Wed, Nov 08, 2017 at 06:51:34PM +0100, Marek Polacek wrote: > > Ok, so like this if it passes bootstrap/regtest? > > > > Changes from the last patch: > > 1) false instead of lval for COMPOUND_EXPR and *COND_EXPR op1/op2 > > So... Oops, I've hand-edited it in the patch and then regenerated the patch after doing there more changes. Here is updated patch with that in again: 2017-11-08 Jakub Jelinek PR c/66618 PR c/69960 c-family/ * c-common.h (c_fully_fold): Add LVAL argument defaulted to false. c/ * c-parser.c (c_parser_omp_atomic): Pass true as LVAL to c_fully_fold where needed. * c-typeck.c (build_unary_op, build_modify_expr, build_asm_expr, handle_omp_array_sections): Likewise. (digest_init): Don't call decl_constant_value_for_optimization. * c-tree.h (decl_constant_value_for_optimization): Removed. * c-fold.c (c_fold_array_ref): New function. (c_fully_fold_internal): Add LVAL argument, propagate it through recursive calls. For VAR_P call decl_constant_value and unshare if not LVAL and either optimizing or IN_INIT. Remove decl_constant_value_for_optimization calls. If IN_INIT and not LVAL, fold ARRAY_REF with STRING_CST and INTEGER_CST operands. (c_fully_fold): Add LVAL argument, pass it through to c_fully_fold_internal. (decl_constant_value_for_optimization): Removed. cp/ * cp-gimplify.c (c_fully_fold): Add LVAL argument, call cp_fold_maybe_rvalue instead of cp_fold_rvalue and pass it !LVAL. testsuite/ * gcc.dg/pr69960.c: New test. * gcc.dg/pr66618.c: New test. * gcc.dg/pr66618-2.c: New test. --- gcc/c-family/c-common.h.jj 2017-11-08 16:19:30.309488815 +0100 +++ gcc/c-family/c-common.h 2017-11-08 17:49:00.548178246 +0100 @@ -827,7 +827,7 @@ extern tree c_build_bitfield_integer_typ extern enum conversion_safety unsafe_conversion_p (location_t, tree, tree, tree, bool); extern bool decl_with_nonnull_addr_p (const_tree); -extern tree c_fully_fold (tree, bool, bool *); +extern tree c_fully_fold (tree, bool, bool *, bool = false); extern tree c_wrap_maybe_const (tree, bool); extern tree c_common_truthvalue_conversion (location_t, tree); extern void c_apply_type_quals_to_decl (int, tree); --- gcc/c/c-parser.c.jj 2017-11-08 16:19:30.569485632 +0100 +++ gcc/c/c-parser.c2017-11-08 17:49:00.552178196 +0100 @@ -14748,7 +14748,7 @@ c_parser_omp_atomic (location_t loc, c_p case NOP_EXPR: /* atomic write */ v = c_parser_cast_expression (parser, NULL).value; non_lvalue_p = !lvalue_p (v); - v = c_fully_fold (v, false, NULL); + v = c_fully_fold (v, false, NULL, true); if (v == error_mark_node) goto saw_error; if (non_lvalue_p) @@ -14767,7 +14767,7 @@ c_parser_omp_atomic (location_t loc, c_p { lhs = c_parser_cast_expression (parser, NULL).value; non_lvalue_p = !lvalue_p (lhs); - lhs = c_fully_fold (lhs, false, NULL); + lhs = c_fully_fold (lhs, false, NULL, true); if (lhs == error_mark_node) goto saw_error; if (non_lvalue_p) @@ -14793,7 +14793,7 @@ c_parser_omp_atomic (location_t loc, c_p { v = c_parser_cast_expression (parser, NULL).value; non_lvalue_p = !lvalue_p (v); - v = c_fully_fold (v, false, NULL); + v = c_fully_fold (v, false, NULL, true); if (v == error_mark_node) goto saw_error; if (non_lvalue_p) @@ -14814,7 +14814,7 @@ restart: lhs = expr.value; expr = default_function_array_conversion (eloc, expr); unfolded_lhs = expr.value; - lhs = c_fully_fold (lhs, false, NULL); + lhs = c_fully_fold (lhs, false, NULL, true); orig_lhs = lhs; switch (TREE_CODE (lhs)) { @@ -14954,15 +14954,19 @@ restart: if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs)) { opcode = TREE_CODE (rhs1); - rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL); - rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL); + rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL, + true); + rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL, + true); goto stmt_done; } if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs)) { opcode = TREE_CODE (rhs1); - rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL); - rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL); + rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL, + true); + rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
On Wed, Nov 08, 2017 at 06:57:55PM +0100, Jakub Jelinek wrote: > On Wed, Nov 08, 2017 at 06:51:34PM +0100, Marek Polacek wrote: > > > Ok, so like this if it passes bootstrap/regtest? > > > > > > Changes from the last patch: > > > 1) false instead of lval for COMPOUND_EXPR and *COND_EXPR op1/op2 > > > > So... > > Oops, I've hand-edited it in the patch and then regenerated the patch > after doing there more changes. > > Here is updated patch with that in again: FYI, bootstrapped/regtested on x86_64-linux and i686-linux successfully. Jakub
Re: [PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)
On Wed, 8 Nov 2017, Jakub Jelinek wrote: > On Wed, Nov 08, 2017 at 06:51:34PM +0100, Marek Polacek wrote: > > > Ok, so like this if it passes bootstrap/regtest? > > > > > > Changes from the last patch: > > > 1) false instead of lval for COMPOUND_EXPR and *COND_EXPR op1/op2 > > > > So... > > Oops, I've hand-edited it in the patch and then regenerated the patch > after doing there more changes. > > Here is updated patch with that in again: > > 2017-11-08 Jakub Jelinek > > PR c/66618 > PR c/69960 OK. -- Joseph S. Myers jos...@codesourcery.com