aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/c-parser.c54
-rw-r--r--gcc/c/c-tree.h1
-rw-r--r--gcc/c/c-typeck.c35
3 files changed, 70 insertions, 20 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index fea6a09..7bf91ef 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -7594,6 +7594,8 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
struct c_expr lhs, rhs, ret;
enum tree_code code;
location_t op_location, exp_location;
+ bool save_in_omp_for = c_in_omp_for;
+ c_in_omp_for = false;
gcc_assert (!after || c_dialect_objc ());
lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
op_location = c_parser_peek_token (parser)->location;
@@ -7633,6 +7635,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
code = BIT_IOR_EXPR;
break;
default:
+ c_in_omp_for = save_in_omp_for;
return lhs;
}
c_parser_consume_token (parser);
@@ -7652,6 +7655,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
ret.original_code = ERROR_MARK;
}
ret.original_type = NULL;
+ c_in_omp_for = save_in_omp_for;
return ret;
}
@@ -18119,8 +18123,10 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
if (i > 0)
vec_safe_push (for_block, c_begin_compound_stmt (true));
this_pre_body = push_stmt_list ();
+ c_in_omp_for = true;
c_parser_declaration_or_fndef (parser, true, true, true, true, true,
NULL, vNULL);
+ c_in_omp_for = false;
if (this_pre_body)
{
this_pre_body = pop_stmt_list (this_pre_body);
@@ -18158,9 +18164,11 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
init_exp = c_parser_expr_no_commas (parser, NULL);
init_exp = default_function_array_read_conversion (init_loc,
init_exp);
+ c_in_omp_for = true;
init = build_modify_expr (init_loc, decl, decl_exp.original_type,
NOP_EXPR, init_loc, init_exp.value,
init_exp.original_type);
+ c_in_omp_for = false;
init = c_process_expr_stmt (init_loc, init);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
@@ -18181,19 +18189,13 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
{
location_t cond_loc = c_parser_peek_token (parser)->location;
+ c_in_omp_for = true;
struct c_expr cond_expr
= c_parser_binary_expression (parser, NULL, NULL_TREE);
+ c_in_omp_for = false;
cond = cond_expr.value;
cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
- if (COMPARISON_CLASS_P (cond))
- {
- tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1);
- op0 = c_fully_fold (op0, false, NULL);
- op1 = c_fully_fold (op1, false, NULL);
- TREE_OPERAND (cond, 0) = op0;
- TREE_OPERAND (cond, 1) = op1;
- }
switch (cond_expr.original_code)
{
case GT_EXPR:
@@ -18337,8 +18339,10 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
an error from the initialization parsing. */
if (!fail)
{
+ c_in_omp_for = true;
stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
incrv, body, pre_body, true);
+ c_in_omp_for = false;
/* Check for iterators appearing in lb, b or incr expressions. */
if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
@@ -18348,6 +18352,40 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
{
add_stmt (stmt);
+ for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
+ {
+ tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
+ gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
+ tree decl = TREE_OPERAND (init, 0);
+ tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
+ gcc_assert (COMPARISON_CLASS_P (cond));
+ gcc_assert (TREE_OPERAND (cond, 0) == decl);
+
+ tree op0 = TREE_OPERAND (init, 1);
+ if (!OMP_FOR_NON_RECTANGULAR (stmt)
+ || TREE_CODE (op0) != TREE_VEC)
+ TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
+ else
+ {
+ TREE_VEC_ELT (op0, 1)
+ = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
+ TREE_VEC_ELT (op0, 2)
+ = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
+ }
+
+ tree op1 = TREE_OPERAND (cond, 1);
+ if (!OMP_FOR_NON_RECTANGULAR (stmt)
+ || TREE_CODE (op1) != TREE_VEC)
+ TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
+ else
+ {
+ TREE_VEC_ELT (op1, 1)
+ = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
+ TREE_VEC_ELT (op1, 2)
+ = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
+ }
+ }
+
if (cclauses != NULL
&& cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
{
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 9466886..10938cf 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -657,6 +657,7 @@ extern alias_set_type c_get_alias_set (tree);
extern int in_alignof;
extern int in_sizeof;
extern int in_typeof;
+extern bool c_in_omp_for;
extern tree c_last_sizeof_arg;
extern location_t c_last_sizeof_loc;
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 385bf3a..3be3690c 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -71,6 +71,9 @@ int in_sizeof;
/* The level of nesting inside "typeof". */
int in_typeof;
+/* True when parsing OpenMP loop expressions. */
+bool c_in_omp_for;
+
/* The argument of last parsed sizeof expression, only to be tested
if expr.original_code == SIZEOF_EXPR. */
tree c_last_sizeof_arg;
@@ -6209,15 +6212,20 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
if (!(is_atomic_op && modifycode != NOP_EXPR))
{
tree rhs_semantic_type = NULL_TREE;
- if (TREE_CODE (newrhs) == EXCESS_PRECISION_EXPR)
+ if (!c_in_omp_for)
{
- rhs_semantic_type = TREE_TYPE (newrhs);
- newrhs = TREE_OPERAND (newrhs, 0);
+ if (TREE_CODE (newrhs) == EXCESS_PRECISION_EXPR)
+ {
+ rhs_semantic_type = TREE_TYPE (newrhs);
+ newrhs = TREE_OPERAND (newrhs, 0);
+ }
+ npc = null_pointer_constant_p (newrhs);
+ newrhs = c_fully_fold (newrhs, false, NULL);
+ if (rhs_semantic_type)
+ newrhs = build1 (EXCESS_PRECISION_EXPR, rhs_semantic_type, newrhs);
}
- npc = null_pointer_constant_p (newrhs);
- newrhs = c_fully_fold (newrhs, false, NULL);
- if (rhs_semantic_type)
- newrhs = build1 (EXCESS_PRECISION_EXPR, rhs_semantic_type, newrhs);
+ else
+ npc = null_pointer_constant_p (newrhs);
newrhs = convert_for_assignment (location, rhs_loc, lhstype, newrhs,
rhs_origtype, ic_assign, npc,
NULL_TREE, NULL_TREE, 0);
@@ -7745,12 +7753,15 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
STRIP_TYPE_NOPS (inside_init);
- if (TREE_CODE (inside_init) == EXCESS_PRECISION_EXPR)
+ if (!c_in_omp_for)
{
- semantic_type = TREE_TYPE (inside_init);
- inside_init = TREE_OPERAND (inside_init, 0);
+ if (TREE_CODE (inside_init) == EXCESS_PRECISION_EXPR)
+ {
+ semantic_type = TREE_TYPE (inside_init);
+ inside_init = TREE_OPERAND (inside_init, 0);
+ }
+ inside_init = c_fully_fold (inside_init, require_constant, &maybe_const);
}
- inside_init = c_fully_fold (inside_init, require_constant, &maybe_const);
/* Initialization of an array of chars from a string constant
optionally enclosed in braces. */
@@ -12475,7 +12486,7 @@ build_binary_op (location_t location, enum tree_code code,
converted = 1;
resultcode = xresultcode;
- if (c_inhibit_evaluation_warnings == 0)
+ if (c_inhibit_evaluation_warnings == 0 && !c_in_omp_for)
{
bool op0_maybe_const = true;
bool op1_maybe_const = true;