Commit d166d4c3 by Andi Kleen Committed by Manuel López-Ibáñez

c-parser.c (c_parser_conditional_expression): Call warn_for_omitted_condop.

2010-06-24  Andi Kleen  <ak@linux.intel.com>

	* c-parser.c (c_parser_conditional_expression):
        Call warn_for_omitted_condop.
        * doc/invoke.texi: Document omitted condop warning.
c-family/	
        * c-common.c (warn_for_omitted_condop): New.
        * c-common.h (warn_for_omitted_condop): Add prototype.
testsuite/
        * c-c++-common/warn-omitted-condop.c: New.
cp/
	* parser.c: (cp_parser_question_colon_clause):
        Switch to use cp_lexer_peek_token.
        Call warn_for_omitted_condop. Call pedwarn for omitted
        middle operand.

From-SVN: r161318
parent b27c1cde
2010-06-24 Andi Kleen <ak@linux.intel.com>
* c-parser.c (c_parser_conditional_expression):
Call warn_for_omitted_condop.
* doc/invoke.texi: Document omitted condop warning.
2010-06-24 Nick Clifton<nickc@redhat.com> 2010-06-24 Nick Clifton<nickc@redhat.com>
* loop-unswitch.c (compare_and_jump_seq): Assert that the last * loop-unswitch.c (compare_and_jump_seq): Assert that the last
......
2010-06-24 Andi Kleen <ak@linux.intel.com>
* c-common.c (warn_for_omitted_condop): New.
* c-common.h (warn_for_omitted_condop): Add prototype.
2010-06-21 Joseph Myers <joseph@codesourcery.com> 2010-06-21 Joseph Myers <joseph@codesourcery.com>
* c.opt (lang-objc): Remove. * c.opt (lang-objc): Remove.
......
...@@ -8405,6 +8405,18 @@ fold_offsetof (tree expr, tree stop_ref) ...@@ -8405,6 +8405,18 @@ fold_offsetof (tree expr, tree stop_ref)
return convert (size_type_node, fold_offsetof_1 (expr, stop_ref)); return convert (size_type_node, fold_offsetof_1 (expr, stop_ref));
} }
/* Warn for A ?: C expressions (with B omitted) where A is a boolean
expression, because B will always be true. */
void
warn_for_omitted_condop (location_t location, tree cond)
{
if (truth_value_p (TREE_CODE (cond)))
warning_at (location, OPT_Wparentheses,
"the omitted middle operand in ?: will always be %<true%>, "
"suggest explicit middle operand");
}
/* Print an error message for an invalid lvalue. USE says /* Print an error message for an invalid lvalue. USE says
how the lvalue is being used and so selects the error message. */ how the lvalue is being used and so selects the error message. */
......
...@@ -736,6 +736,7 @@ extern void c_parse_file (void); ...@@ -736,6 +736,7 @@ extern void c_parse_file (void);
/* This is misnamed, it actually performs end-of-compilation processing. */ /* This is misnamed, it actually performs end-of-compilation processing. */
extern void finish_file (void); extern void finish_file (void);
extern void warn_for_omitted_condop (location_t, tree);
/* These macros provide convenient access to the various _STMT nodes. */ /* These macros provide convenient access to the various _STMT nodes. */
......
...@@ -4795,7 +4795,7 @@ static struct c_expr ...@@ -4795,7 +4795,7 @@ static struct c_expr
c_parser_conditional_expression (c_parser *parser, struct c_expr *after) c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
{ {
struct c_expr cond, exp1, exp2, ret; struct c_expr cond, exp1, exp2, ret;
location_t cond_loc, colon_loc; location_t cond_loc, colon_loc, middle_loc;
gcc_assert (!after || c_dialect_objc ()); gcc_assert (!after || c_dialect_objc ());
...@@ -4809,8 +4809,11 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after) ...@@ -4809,8 +4809,11 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
if (c_parser_next_token_is (parser, CPP_COLON)) if (c_parser_next_token_is (parser, CPP_COLON))
{ {
tree eptype = NULL_TREE; tree eptype = NULL_TREE;
pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
middle_loc = c_parser_peek_token (parser)->location;
pedwarn (middle_loc, OPT_pedantic,
"ISO C forbids omitting the middle term of a ?: expression"); "ISO C forbids omitting the middle term of a ?: expression");
warn_for_omitted_condop (middle_loc, cond.value);
if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR) if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
{ {
eptype = TREE_TYPE (cond.value); eptype = TREE_TYPE (cond.value);
......
2010-06-24 Andi Kleen <ak@linux.intel.com>
* parser.c: (cp_parser_question_colon_clause):
Switch to use cp_lexer_peek_token.
Call warn_for_omitted_condop. Call pedwarn for omitted
middle operand.
2010-06-22 Jakub Jelinek <jakub@redhat.com> 2010-06-22 Jakub Jelinek <jakub@redhat.com>
PR c++/44619 PR c++/44619
......
...@@ -6815,15 +6815,20 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) ...@@ -6815,15 +6815,20 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
{ {
tree expr; tree expr;
tree assignment_expr; tree assignment_expr;
struct cp_token *token;
/* Consume the `?' token. */ /* Consume the `?' token. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
token = cp_lexer_peek_token (parser->lexer);
if (cp_parser_allow_gnu_extensions_p (parser) if (cp_parser_allow_gnu_extensions_p (parser)
&& cp_lexer_next_token_is (parser->lexer, CPP_COLON)) && token->type == CPP_COLON)
{ {
pedwarn (token->location, OPT_pedantic,
"ISO C++ does not allow ?: with omitted middle operand");
/* Implicit true clause. */ /* Implicit true clause. */
expr = NULL_TREE; expr = NULL_TREE;
c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node; c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node;
warn_for_omitted_condop (token->location, logical_or_expr);
} }
else else
{ {
......
...@@ -3275,6 +3275,12 @@ look like this: ...@@ -3275,6 +3275,12 @@ look like this:
@end group @end group
@end smallexample @end smallexample
Also warn for dangerous uses of the
?: with omitted middle operand GNU extension. When the condition
in the ?: operator is a boolean expression the omitted value will
be always 1. Often the user expects it to be a value computed
inside the conditional expression instead.
This warning is enabled by @option{-Wall}. This warning is enabled by @option{-Wall}.
@item -Wsequence-point @item -Wsequence-point
......
2010-06-24 Andi Kleen <ak@linux.intel.com>
* c-c++-common/warn-omitted-condop.c: New.
2010-06-24 Tobias Burnus <burnus@net-b.de> 2010-06-24 Tobias Burnus <burnus@net-b.de>
PR fortran/44614 PR fortran/44614
......
/* { dg-options "-Wparentheses" } */
extern void f2 (int);
void bar (int x, int y, int z)
{
#define T(op) f2 (x op y ? : 1)
#define T2(op) f2 (x op y ? 2 : 1)
T(<); /* { dg-warning "omitted middle operand" } */
T(>); /* { dg-warning "omitted middle operand" } */
T(<=); /* { dg-warning "omitted middle operand" } */
T(>=); /* { dg-warning "omitted middle operand" } */
T(==); /* { dg-warning "omitted middle operand" } */
T(!=); /* { dg-warning "omitted middle operand" } */
T(||); /* { dg-warning "omitted middle operand" } */
T(&&); /* { dg-warning "omitted middle operand" } */
f2 (!x ? : 1); /* { dg-warning "omitted middle operand" } */
T2(<); /* { dg-bogus "omitted middle operand" } */
T2(>); /* { dg-bogus "omitted middle operand" } */
T2(==); /* { dg-bogus "omitted middle operand" } */
T2(||); /* { dg-bogus "omitted middle operand" } */
T2(&&); /* { dg-bogus "omitted middle operand" } */
T(+); /* { dg-bogus "omitted middle operand" } */
T(-); /* { dg-bogus "omitted middle operand" } */
T(*); /* { dg-bogus "omitted middle operand" } */
T(/); /* { dg-bogus "omitted middle operand" } */
T(^); /* { dg-bogus "omitted middle operand" } */
}
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