Commit 5c4abbb8 by Marek Polacek Committed by Marek Polacek

re PR c/65345 (ICE with _Generic selection on _Atomic int)

	PR c/65345
	* c-decl.c (set_labels_context_r): New function.
	(store_parm_decls): Call it via walk_tree_without_duplicates.
	* c-typeck.c (convert_lvalue_to_rvalue): Use create_tmp_var_raw
	instead of create_tmp_var.  Build TARGET_EXPR instead of
	COMPOUND_EXPR.
	(build_atomic_assign): Use create_tmp_var_raw instead of
	create_tmp_var.  Build TARGET_EXPRs instead of MODIFY_EXPR.

	* gcc.dg/pr65345-1.c: New test.
	* gcc.dg/pr65345-2.c: New test.

From-SVN: r222370
parent 0f9b95df
2015-04-23 Marek Polacek <polacek@redhat.com>
PR c/65345
* c-decl.c (set_labels_context_r): New function.
(store_parm_decls): Call it via walk_tree_without_duplicates.
* c-typeck.c (convert_lvalue_to_rvalue): Use create_tmp_var_raw
instead of create_tmp_var. Build TARGET_EXPR instead of
COMPOUND_EXPR.
(build_atomic_assign): Use create_tmp_var_raw instead of
create_tmp_var. Build TARGET_EXPRs instead of MODIFY_EXPR.
2015-04-20 Ilya Verbin <ilya.verbin@intel.com>
* c-parser.c (c_parser_oacc_enter_exit_data): Remove excess semicolon.
......
......@@ -8796,6 +8796,21 @@ store_parm_decls_from (struct c_arg_info *arg_info)
store_parm_decls ();
}
/* Called by walk_tree to look for and update context-less labels. */
static tree
set_labels_context_r (tree *tp, int *walk_subtrees, void *data)
{
if (TREE_CODE (*tp) == LABEL_EXPR
&& DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) == NULL_TREE)
{
DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) = static_cast<tree>(data);
*walk_subtrees = 0;
}
return NULL_TREE;
}
/* Store the parameter declarations into the current function declaration.
This is called after parsing the parameter declarations, before
digesting the body of the function.
......@@ -8850,7 +8865,21 @@ store_parm_decls (void)
thus won't naturally see the SAVE_EXPR containing the increment. All
other pending sizes would be handled by gimplify_parameters. */
if (arg_info->pending_sizes)
add_stmt (arg_info->pending_sizes);
{
/* In very special circumstances, e.g. for code like
_Atomic int i = 5;
void f (int a[i += 2]) {}
we need to execute the atomic assignment on function entry.
But in this case, it is not just a straight store, it has the
op= form, which means that build_atomic_assign has generated
gotos, labels, etc. Because at that time the function decl
for F has not been created yet, those labels do not have any
function context. But we have the fndecl now, so update the
labels accordingly. gimplify_expr would crash otherwise. */
walk_tree_without_duplicates (&arg_info->pending_sizes,
set_labels_context_r, fndecl);
add_stmt (arg_info->pending_sizes);
}
}
/* Store PARM_DECLs in PARMS into scope temporarily. Used for
......
......@@ -2039,7 +2039,7 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp,
/* Remove the qualifiers for the rest of the expressions and
create the VAL temp variable to hold the RHS. */
nonatomic_type = build_qualified_type (expr_type, TYPE_UNQUALIFIED);
tmp = create_tmp_var (nonatomic_type);
tmp = create_tmp_var_raw (nonatomic_type);
tmp_addr = build_unary_op (loc, ADDR_EXPR, tmp, 0);
TREE_ADDRESSABLE (tmp) = 1;
TREE_NO_WARNING (tmp) = 1;
......@@ -2055,7 +2055,8 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp,
mark_exp_read (exp.value);
/* Return tmp which contains the value loaded. */
exp.value = build2 (COMPOUND_EXPR, nonatomic_type, func_call, tmp);
exp.value = build4 (TARGET_EXPR, nonatomic_type, tmp, func_call,
NULL_TREE, NULL_TREE);
}
return exp;
}
......@@ -3686,10 +3687,11 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
the VAL temp variable to hold the RHS. */
nonatomic_lhs_type = build_qualified_type (lhs_type, TYPE_UNQUALIFIED);
nonatomic_rhs_type = build_qualified_type (rhs_type, TYPE_UNQUALIFIED);
val = create_tmp_var (nonatomic_rhs_type);
val = create_tmp_var_raw (nonatomic_rhs_type);
TREE_ADDRESSABLE (val) = 1;
TREE_NO_WARNING (val) = 1;
rhs = build2 (MODIFY_EXPR, nonatomic_rhs_type, val, rhs);
rhs = build4 (TARGET_EXPR, nonatomic_rhs_type, val, rhs, NULL_TREE,
NULL_TREE);
SET_EXPR_LOCATION (rhs, loc);
add_stmt (rhs);
......@@ -3715,12 +3717,12 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
}
/* Create the variables and labels required for the op= form. */
old = create_tmp_var (nonatomic_lhs_type);
old = create_tmp_var_raw (nonatomic_lhs_type);
old_addr = build_unary_op (loc, ADDR_EXPR, old, 0);
TREE_ADDRESSABLE (old) = 1;
TREE_NO_WARNING (old) = 1;
newval = create_tmp_var (nonatomic_lhs_type);
newval = create_tmp_var_raw (nonatomic_lhs_type);
newval_addr = build_unary_op (loc, ADDR_EXPR, newval, 0);
TREE_ADDRESSABLE (newval) = 1;
......@@ -3736,7 +3738,9 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
params->quick_push (old_addr);
params->quick_push (seq_cst);
func_call = c_build_function_call_vec (loc, vNULL, fndecl, params, NULL);
add_stmt (func_call);
old = build4 (TARGET_EXPR, nonatomic_lhs_type, old, func_call, NULL_TREE,
NULL_TREE);
add_stmt (old);
params->truncate (0);
/* Create the expressions for floating-point environment
......@@ -3755,12 +3759,14 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
/* newval = old + val; */
rhs = build_binary_op (loc, modifycode, old, val, 1);
rhs = c_fully_fold (rhs, false, NULL);
rhs = convert_for_assignment (loc, UNKNOWN_LOCATION, nonatomic_lhs_type,
rhs, NULL_TREE, ic_assign, false, NULL_TREE,
NULL_TREE, 0);
if (rhs != error_mark_node)
{
rhs = build2 (MODIFY_EXPR, nonatomic_lhs_type, newval, rhs);
rhs = build4 (TARGET_EXPR, nonatomic_lhs_type, newval, rhs, NULL_TREE,
NULL_TREE);
SET_EXPR_LOCATION (rhs, loc);
add_stmt (rhs);
}
......@@ -3782,7 +3788,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
stmt = build3 (COND_EXPR, void_type_node, func_call, goto_stmt, NULL_TREE);
SET_EXPR_LOCATION (stmt, loc);
add_stmt (stmt);
if (clear_call)
add_stmt (clear_call);
......@@ -3790,7 +3796,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
goto_stmt = build1 (GOTO_EXPR, void_type_node, loop_decl);
SET_EXPR_LOCATION (goto_stmt, loc);
add_stmt (goto_stmt);
/* done: */
add_stmt (done_label);
......
2015-04-23 Marek Polacek <polacek@redhat.com>
PR c/65345
* gcc.dg/pr65345-1.c: New test.
* gcc.dg/pr65345-2.c: New test.
2015-04-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* gcc.target/powerpc/crypto-builtin-2.c: New.
......
/* PR c/65345 */
/* { dg-do compile } */
/* { dg-options "" } */
_Atomic int i = 3;
int a1 = sizeof (i + 1);
int a2 = sizeof (i = 0);
int a3 = sizeof (i++);
int a4 = sizeof (i--);
int a5 = sizeof (-i);
int b1 = _Alignof (i + 1);
int b2 = _Alignof (i = 0);
int b3 = _Alignof (i++);
int b4 = _Alignof (i--);
int b5 = _Alignof (-i);
int c1 = i; /* { dg-error "initializer element is not constant" } */
int c2 = (i ? 1 : 2); /* { dg-error "initializer element is not constant" } */
int c3[i]; /* { dg-error "variably modified" } */
int c4 = 0 || i; /* { dg-error "initializer element is not constant" } */
int c5 = (i += 10); /* { dg-error "initializer element is not constant" } */
_Static_assert (_Generic (i, int: 1, default: 0) == 1, "1");
_Static_assert (_Generic (i + 1, int: 1, default: 0) == 1, "2");
_Static_assert (_Generic (i = 0, int: 1, default: 0) == 1, "3");
_Static_assert (_Generic (i++, int: 1, default: 0) == 1, "4");
_Static_assert (_Generic (i--, int: 1, default: 0) == 1, "5");
void fn1 (int a[i + 1]);
void fn2 (int a[i = 0]);
void fn3 (int a[i++]);
void fn4 (int a[i--]);
void fn5 (int a[-i]);
/* PR c/65345 */
/* { dg-do run } */
/* { dg-options "" } */
#define CHECK(X) if (!(X)) __builtin_abort ()
_Atomic int i = 5;
_Atomic int j = 2;
void
fn1 (int a[i = 0])
{
}
void
fn2 (int a[i += 2])
{
}
void
fn3 (int a[++i])
{
}
void
fn4 (int a[++i])
{
}
void
fn5 (int a[++i][j = 10])
{
}
void
fn6 (int a[i = 7][j--])
{
}
int
main ()
{
int a[10];
int aa[10][10];
fn1 (a);
CHECK (i == 0);
fn2 (a);
CHECK (i == 2);
fn3 (a);
CHECK (i == 3);
fn4 (a);
CHECK (i == 4);
fn5 (aa);
CHECK (i == 5);
CHECK (j == 10);
fn6 (aa);
CHECK (i == 7);
CHECK (j == 9);
}
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