aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-03-23 22:05:30 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2009-03-23 22:05:30 +0100
commitc5cdb03fb9e13c384901671a424555550ed098f1 (patch)
treea9fdfdfd88e5b8dd5deaf726ac04e0979d9d8ed9 /gcc
parent6afcfe0a8080cf3816e841f0f1c2b96a73baed43 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/c-parser.c16
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/parser.c59
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr39495-2.c8
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" } */