[PATCH] Add LVAL argument to c_fully_fold* and propagate it through (PR c/66618, PR c/69960)

2017-11-08 Thread Jakub Jelinek
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)

2017-12-25 Thread Tom de Vries

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)

2017-11-08 Thread Marek Polacek
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)

2017-11-08 Thread Jakub Jelinek
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)

2017-11-08 Thread Joseph Myers
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)

2017-11-08 Thread Jakub Jelinek
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)

2017-11-08 Thread Marek Polacek
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)

2017-11-08 Thread Jakub Jelinek
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)

2017-11-09 Thread Jakub Jelinek
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)

2017-11-17 Thread Joseph Myers
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