diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-03-23 22:05:30 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2009-03-23 22:05:30 +0100 |
commit | c5cdb03fb9e13c384901671a424555550ed098f1 (patch) | |
tree | a9fdfdfd88e5b8dd5deaf726ac04e0979d9d8ed9 /gcc | |
parent | 6afcfe0a8080cf3816e841f0f1c2b96a73baed43 (diff) | |
download | gcc-c5cdb03fb9e13c384901671a424555550ed098f1.zip gcc-c5cdb03fb9e13c384901671a424555550ed098f1.tar.gz gcc-c5cdb03fb9e13c384901671a424555550ed098f1.tar.bz2 |
re PR c/39495 (OMP parallel loop w/ unsigned index var rejected)
PR c/39495
* c-parser.c (c_parser_omp_for_loop): Call c_parser_binary_expression
instead of c_parser_expression_conv, if original_code isn't one of the
4 allowed comparison codes, fail.
* semantics.c (handle_omp_for_class_iterator): Swap cond operands and
code if iter is the second operand.
* parser.c (cp_parser_binary_expression): Add no_toplevel_fold_p
argument. If it is set, don't build the toplevel expression with
build_x_binary_op, but build2.
(cp_parser_assignment_expression, cp_parser_omp_for_incr): Adjust
callers.
(cp_parser_omp_for_cond): Don't assume the first operand of the
comparison must be decl.
* gcc.dg/gomp/pr39495-2.c: Remove xfails.
* testsuite/libgomp.c/loop-12.c: New test.
* testsuite/libgomp.c/loop-11.c: New test.
* testsuite/libgomp.c++/loop-11.C: New test.
* testsuite/libgomp.c++/loop-12.C: New test.
* testsuite/libgomp.c++/for-8.C: New test.
From-SVN: r145014
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c-parser.c | 16 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/parser.c | 59 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/gomp/pr39495-2.c | 8 |
7 files changed, 80 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 00290b5..c1f7e6f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-03-23 Jakub Jelinek <jakub@redhat.com> + + PR c/39495 + * c-parser.c (c_parser_omp_for_loop): Call c_parser_binary_expression + instead of c_parser_expression_conv, if original_code isn't one of the + 4 allowed comparison codes, fail. + 2009-03-23 Richard Guenther <rguenther@suse.de> * cgraph.h (struct cgraph_node): Reorder fields for 64-bit hosts. diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 6dfcb60..ea0036c 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -7652,9 +7652,23 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses) if (c_parser_next_token_is_not (parser, CPP_SEMICOLON)) { location_t cond_loc = c_parser_peek_token (parser)->location; + struct c_expr cond_expr = c_parser_binary_expression (parser, NULL); - cond = c_parser_expression_conv (parser).value; + cond = cond_expr.value; cond = c_objc_common_truthvalue_conversion (cond_loc, cond); + switch (cond_expr.original_code) + { + case GT_EXPR: + case GE_EXPR: + case LT_EXPR: + case LE_EXPR: + break; + default: + /* Can't be cond = error_mark_node, because we want to preserve + the location until c_finish_omp_for. */ + cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node); + break; + } protected_set_expr_location (cond, cond_loc); } c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e9e424d..3f10174 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2009-03-23 Jakub Jelinek <jakub@redhat.com> + + PR c/39495 + * semantics.c (handle_omp_for_class_iterator): Swap cond operands and + code if iter is the second operand. + * parser.c (cp_parser_binary_expression): Add no_toplevel_fold_p + argument. If it is set, don't build the toplevel expression with + build_x_binary_op, but build2. + (cp_parser_assignment_expression, cp_parser_omp_for_incr): Adjust + callers. + (cp_parser_omp_for_cond): Don't assume the first operand of the + comparison must be decl. + 2009-03-23 Jason Merrill <jason@redhat.com> * pt.c (make_fnparm_pack): Split out from... diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d3343aa..02a96cc 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1615,7 +1615,7 @@ static tree cp_parser_delete_expression static tree cp_parser_cast_expression (cp_parser *, bool, bool, cp_id_kind *); static tree cp_parser_binary_expression - (cp_parser *, bool, enum cp_parser_prec, cp_id_kind *); + (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *); static tree cp_parser_question_colon_clause (cp_parser *, tree); static tree cp_parser_assignment_expression @@ -6215,6 +6215,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, static tree cp_parser_binary_expression (cp_parser* parser, bool cast_p, + bool no_toplevel_fold_p, enum cp_parser_prec prec, cp_id_kind * pidk) { @@ -6297,6 +6298,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, goto get_rhs; pop: + lookahead_prec = new_prec; /* If the stack is not empty, we have parsed into LHS the right side (`4' in the example above) of an expression we had suspended. We can use the information on the stack to recover the LHS (`3') @@ -6321,8 +6323,14 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, pass the correct tree_code unless the unary expression was surrounded by parentheses. */ - lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type, - &overloaded_p, tf_warning_or_error); + if (no_toplevel_fold_p + && lookahead_prec <= prec + && sp == stack + && TREE_CODE_CLASS (tree_type) == tcc_comparison) + lhs = build2 (tree_type, boolean_type_node, lhs, rhs); + else + lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type, + &overloaded_p, tf_warning_or_error); lhs_type = tree_type; /* If the binary operator required the use of an overloaded operator, @@ -6408,7 +6416,8 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p, else { /* Parse the binary expressions (logical-or-expression). */ - expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR, pidk); + expr = cp_parser_binary_expression (parser, cast_p, false, + PREC_NOT_OPERATOR, pidk); /* If the next token is a `?' then we're actually looking at a conditional-expression. */ if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY)) @@ -21015,41 +21024,39 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok) static tree cp_parser_omp_for_cond (cp_parser *parser, tree decl) { - tree lhs = cp_parser_cast_expression (parser, false, false, NULL), rhs; - enum tree_code op; - cp_token *token; + tree cond = cp_parser_binary_expression (parser, false, true, + PREC_NOT_OPERATOR, NULL); + bool overloaded_p; - if (decl && lhs != decl) + if (cond == error_mark_node + || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) { cp_parser_skip_to_end_of_statement (parser); return error_mark_node; } - token = cp_lexer_peek_token (parser->lexer); - op = binops_by_token [token->type].tree_type; - switch (op) + switch (TREE_CODE (cond)) { - case LT_EXPR: - case LE_EXPR: case GT_EXPR: case GE_EXPR: + case LT_EXPR: + case LE_EXPR: break; default: - cp_parser_skip_to_end_of_statement (parser); return error_mark_node; } - cp_lexer_consume_token (parser->lexer); - rhs = cp_parser_binary_expression (parser, false, - PREC_RELATIONAL_EXPRESSION, NULL); - if (rhs == error_mark_node - || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - { - cp_parser_skip_to_end_of_statement (parser); - return error_mark_node; - } + /* If decl is an iterator, preserve LHS and RHS of the relational + expr until finish_omp_for. */ + if (decl + && (type_dependent_expression_p (decl) + || CLASS_TYPE_P (TREE_TYPE (decl)))) + return cond; - return build2 (op, boolean_type_node, lhs, rhs); + return build_x_binary_op (TREE_CODE (cond), + TREE_OPERAND (cond, 0), ERROR_MARK, + TREE_OPERAND (cond, 1), ERROR_MARK, + &overloaded_p, tf_warning_or_error); } /* Helper function, to parse omp for increment expression. */ @@ -21098,7 +21105,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs); } - lhs = cp_parser_binary_expression (parser, false, + lhs = cp_parser_binary_expression (parser, false, false, PREC_ADDITIVE_EXPRESSION, NULL); token = cp_lexer_peek_token (parser->lexer); decl_first = lhs == decl; @@ -21112,7 +21119,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) { op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR; cp_lexer_consume_token (parser->lexer); - rhs = cp_parser_binary_expression (parser, false, + rhs = cp_parser_binary_expression (parser, false, false, PREC_ADDITIVE_EXPRESSION, NULL); token = cp_lexer_peek_token (parser->lexer); if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c728970..71fc43e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3921,6 +3921,9 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv, case GE_EXPR: case LT_EXPR: case LE_EXPR: + if (TREE_OPERAND (cond, 1) == iter) + cond = build2 (swap_tree_comparison (TREE_CODE (cond)), + TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0)); if (TREE_OPERAND (cond, 0) != iter) cond = error_mark_node; else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 40205fa..cced718 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-03-23 Jakub Jelinek <jakub@redhat.com> + + PR c/39495 + * gcc.dg/gomp/pr39495-2.c: Remove xfails. + 2009-03-23 Jason Merrill <jason@redhat.com> * g++.dg/cpp0x/auto12.C: Add variadic test. diff --git a/gcc/testsuite/gcc.dg/gomp/pr39495-2.c b/gcc/testsuite/gcc.dg/gomp/pr39495-2.c index e463696..a276c24 100644 --- a/gcc/testsuite/gcc.dg/gomp/pr39495-2.c +++ b/gcc/testsuite/gcc.dg/gomp/pr39495-2.c @@ -13,25 +13,25 @@ foo (void) unsigned int u; #pragma omp for - for (i = INT_MIN + 6; i != INT_MIN; i--) /* { dg-error "invalid controlling predicate" "" { xfail *-*-* } } */ + for (i = INT_MIN + 6; i != INT_MIN; i--) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for for (i = INT_MIN + 6; i == INT_MIN; i--) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for - for (i = INT_MAX - 6; i != INT_MAX; i++) /* { dg-error "invalid controlling predicate" "" { xfail *-*-* } } */ + for (i = INT_MAX - 6; i != INT_MAX; i++) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for for (i = INT_MAX - 6; i == INT_MAX; i++) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for - for (u = 6; u != 0; u--) /* { dg-error "invalid controlling predicate" "" { xfail *-*-* } } */ + for (u = 6; u != 0; u--) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for for (u = 6; u == 0; u--) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for - for (u = UINT_MAX - 6; u != UINT_MAX; u++) /* { dg-error "invalid controlling predicate" "" { xfail *-*-* } } */ + for (u = UINT_MAX - 6; u != UINT_MAX; u++) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for for (u = UINT_MAX - 6; u == UINT_MAX; u++) /* { dg-error "invalid controlling predicate" } */ |