Commit f9c59f7e by Jakub Jelinek Committed by Jakub Jelinek

re PR c/66618 (Failure to diagnose non-constant initializer for static object with -O1)

	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.

From-SVN: r254930
parent 4397fc04
2017-11-19 Jakub Jelinek <jakub@redhat.com>
PR c/66618
PR c/69960
* c-common.h (c_fully_fold): Add LVAL argument defaulted to false.
2017-11-16 Joseph Myers <joseph@codesourcery.com>
* c.opt (-std=c17, std=gnu17, -std=iso9899:2017): Refer to 2018
......
......@@ -828,7 +828,7 @@ extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int);
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);
......
2017-11-19 Jakub Jelinek <jakub@redhat.com>
PR c/66618
PR c/69960
* 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.
2017-11-15 Joseph Myers <joseph@codesourcery.com>
PR c/81156
......
......@@ -15312,7 +15312,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
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)
......@@ -15331,7 +15331,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
{
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)
......@@ -15357,7 +15357,7 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
{
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)
......@@ -15378,7 +15378,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))
{
......@@ -15518,15 +15518,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,
true);
swapped = !commutative_tree_code (opcode);
goto stmt_done;
}
......@@ -15545,7 +15549,7 @@ restart:
lhs = NULL_TREE;
expr = default_function_array_read_conversion (eloc, expr);
unfolded_lhs1 = expr.value;
lhs1 = c_fully_fold (unfolded_lhs1, false, NULL);
lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
rhs1 = NULL_TREE;
c_parser_consume_token (parser);
goto restart;
......@@ -15554,7 +15558,7 @@ restart:
{
opcode = NOP_EXPR;
expr = default_function_array_read_conversion (eloc, expr);
rhs = c_fully_fold (expr.value, false, NULL);
rhs = c_fully_fold (expr.value, false, NULL, true);
rhs1 = NULL_TREE;
goto stmt_done;
}
......@@ -15575,7 +15579,7 @@ restart:
expr = c_parser_expression (parser);
expr = default_function_array_read_conversion (eloc, expr);
rhs = expr.value;
rhs = c_fully_fold (rhs, false, NULL);
rhs = c_fully_fold (rhs, false, NULL, true);
break;
}
stmt_done:
......@@ -15585,7 +15589,7 @@ stmt_done:
goto saw_error;
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)
......@@ -15597,7 +15601,7 @@ stmt_done:
lhs1 = expr.value;
expr = default_function_array_read_conversion (eloc, expr);
unfolded_lhs1 = expr.value;
lhs1 = c_fully_fold (lhs1, false, NULL);
lhs1 = c_fully_fold (lhs1, false, NULL, true);
if (lhs1 == error_mark_node)
goto saw_error;
if (!lvalue_p (unfolded_lhs1))
......
......@@ -770,8 +770,6 @@ set_c_expr_source_range (c_expr *expr,
source_range src_range);
/* In c-fold.c */
extern tree decl_constant_value_for_optimization (tree);
extern vec<tree> incomplete_record_decls;
#if CHECKING_P
......
......@@ -4398,7 +4398,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
}
/* Ensure the argument is fully folded inside any SAVE_EXPR. */
arg = c_fully_fold (arg, false, NULL);
arg = c_fully_fold (arg, false, NULL, true);
bool atomic_op;
atomic_op = really_atomic_lvalue (arg);
......@@ -5822,7 +5822,7 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
if (modifycode != NOP_EXPR)
{
lhs = c_fully_fold (lhs, false, NULL);
lhs = c_fully_fold (lhs, false, NULL, true);
lhs = stabilize_reference (lhs);
/* Construct the RHS for any non-atomic compound assignemnt. */
......@@ -7289,7 +7289,6 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
inside_init = TREE_OPERAND (inside_init, 0);
}
inside_init = c_fully_fold (inside_init, require_constant, &maybe_const);
inside_init = decl_constant_value_for_optimization (inside_init);
/* Initialization of an array of chars from a string constant
optionally enclosed in braces. */
......@@ -9899,7 +9898,7 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
{
tree output = TREE_VALUE (tail);
output = c_fully_fold (output, false, NULL);
output = c_fully_fold (output, false, NULL, true);
/* ??? Really, this should not be here. Users should be using a
proper lvalue, dammit. But there's a long history of using casts
......@@ -9957,7 +9956,7 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
mark it addressable. */
if (!allows_reg && allows_mem)
{
input = c_fully_fold (input, false, NULL);
input = c_fully_fold (input, false, NULL, true);
/* Strip the nops as we allow this case. FIXME, this really
should be rejected or made deprecated. */
......@@ -12723,7 +12722,7 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort)
}
if (tem)
first = build2 (COMPOUND_EXPR, TREE_TYPE (first), tem, first);
first = c_fully_fold (first, false, NULL);
first = c_fully_fold (first, false, NULL, true);
OMP_CLAUSE_DECL (c) = first;
}
else
......
2017-11-19 Jakub Jelinek <jakub@redhat.com>
PR c/66618
PR c/69960
* cp-gimplify.c (c_fully_fold): Add LVAL argument, call
cp_fold_maybe_rvalue instead of cp_fold_rvalue and pass it !LVAL.
2017-11-16 Jason Merrill <jason@redhat.com>
PR c++/79092 - non-type args of different types are different
......
......@@ -2048,11 +2048,9 @@ cp_fully_fold (tree x)
C_MAYBE_CONST_EXPR. */
tree
c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/)
c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/, bool lval)
{
/* c_fully_fold is only used on rvalues, and we need to fold CONST_DECL to
INTEGER_CST. */
return cp_fold_rvalue (x);
return cp_fold_maybe_rvalue (x, !lval);
}
static GTY((deletable)) hash_map<tree, tree> *fold_cache;
......
2017-11-19 Jakub Jelinek <jakub@redhat.com>
PR c/66618
PR c/69960
* gcc.dg/pr69960.c: New test.
* gcc.dg/pr66618.c: New test.
* gcc.dg/pr66618-2.c: New test.
2017-11-18 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/44292
......
/* PR c/66618 */
/* { dg-do compile } */
/* { dg-options "-pedantic-errors" } */
int a = "foo"[2];
int b = 1["bar"];
int c = "baz"[__INT_MAX__ * -2]; /* { dg-error "initializer element is not constant" } */
int d = "str"[3]; /* { dg-warning "integer overflow in expression of type" "" { target *-*-* } .-1 } */
int e = "str"[4]; /* { dg-error "initializer element is not constant" } */
int f = "str"[-1]; /* { dg-error "initializer element is not constant" } */
/* PR c/66618 */
/* { dg-do compile } */
/* { dg-options "-O0" } */
int
foo (void)
{
const int a = 0;
static int b = a; /* { dg-bogus "initializer element is not constant" } */
return b;
}
/* PR c/69960 */
/* { dg-do compile { target int32plus } } */
#define TOLOWER(x) (x&~0x20)
#define Word(s) \
s[1] ? s[2] ? s[3] ? \
(TOLOWER(s[0]) << 24) + (TOLOWER(s[1]) << 16) + (TOLOWER(s[2]) << 8) + TOLOWER(s[3]) : \
(TOLOWER(s[0]) << 16) + (TOLOWER(s[1]) << 8) + TOLOWER(s[2]) : \
(TOLOWER(s[0]) << 8) + TOLOWER(s[1]) : \
TOLOWER(s[0])
const unsigned int _the = Word("the");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment