re PR c++/19564 (-Wparentheses does not work with the C++ front-end)

PR c++/19564
	PR c++/19756
gcc/:
	* c-typeck.c (parser_build_binary_op): Move parentheses warnings
	to warn_about_parentheses in c-common.c.
	* c-common.c (warn_about_parentheses): New function.
	* c-common.h (warn_about_parentheses): Declare.
	* doc/invoke.texi (Warning Options): Update -Wparentheses
	description.
gcc/cp/:
	* parser.c (cp_parser_expression_stack_entry): Add field
	lhs_type.
	(cp_parser_binary_expression): Track tree code of left hand side
	of expression.  Use it when calling build_x_binary_op.
	(cp_parser_selection_statement): Add if_p parameter.  Change all
	callers.  Warn about ambiguous else.
	(cp_parser_statement): Add if_p parameter.  Change all callers.
	(cp_parser_implicitly_scoped_statement): Likewise.
	* typeck.c (build_x_binary_op): Add parameters arg1_code and
	arg2_code.  Change all callers.  Call warn_about_parentheses.
	* cp-tree.h (build_x_binary_op): Update declaration.
gcc/testsuite/:
	* g++.dg/warn/Wparentheses-5.C: New test.
	* g++.dg/warn/Wparentheses-6.C: New test.
	* g++.dg/warn/Wparentheses-7.C: New test.
	* g++.dg/warn/Wparentheses-8.C: New test.
	* g++.dg/warn/Wparentheses-9.C: New test.
	* g++.dg/warn/Wparentheses-10.C: New test.
	* g++.dg/warn/Wparentheses-11.C: New test.
	* g++.dg/warn/Wparentheses-12.C: New test.
	* g++.dg/warn/Wparentheses-13.C: New test.
	* g++.dg/warn/Wparentheses-14.C: New test.
	* g++.dg/warn/Wparentheses-15.C: New test.
	* g++.dg/warn/Wparentheses-16.C: New test.
	* g++.dg/warn/Wparentheses-17.C: New test.
	* g++.dg/warn/Wparentheses-18.C: New test.
	* g++.dg/warn/Wparentheses-19.C: New test.
	* g++.dg/warn/Wparentheses-20.C: New test.
	* g++.dg/warn/Wparentheses-21.C: New test.
libstdc++-v3/:
	* include/bits/locale_facets.tcc (num_get<>::_M_extract_float):
	Add parentheses around && within || to avoid warning.
	(num_get<>::_M_extract_int): Likewise.
	(money_get<>::_M_extract): Likewise.
	(num_get<>::do_get(iter_type, iter_type, ios_base&,
	ios_base::iostate&, void*&)): Add parentheses around & within | to
	avoid warning.
	(num_put<>::do_put(iter_type, ios_base&, char_type, const void*)):
	Likewise.
	* include/bits/streambuf_iterator.h (istreambuf_iterator::equal):
	Add parentheses around && within || to avoid warning.
	* libsupc++/tinfo.cc (__do_dyncast): Likewise.
	* src/locale.cc (locale::_S_normalize_category): Likewise.
	* include/bits/stl_tree.h (_Rb_tree<>::_M_insert_unique): Add
	braces to avoid ambiguous else warning.
	* src/strstream.cc (strstreambuf::_M_free): Likewise.
	* src/tree.cc (_Rb_tree_rebalance_for_erase): Likewise.

From-SVN: r119855
This commit is contained in:
Ian Lance Taylor 2006-12-14 05:49:06 +00:00 committed by Ian Lance Taylor
parent 73f30c6308
commit 2a67bec24f
36 changed files with 1633 additions and 141 deletions

View File

@ -1,3 +1,14 @@
2006-12-13 Ian Lance Taylor <iant@google.com>
PR c++/19564
PR c++/19756
* c-typeck.c (parser_build_binary_op): Move parentheses warnings
to warn_about_parentheses in c-common.c.
* c-common.c (warn_about_parentheses): New function.
* c-common.h (warn_about_parentheses): Declare.
* doc/invoke.texi (Warning Options): Update -Wparentheses
description.
2006-12-13 Zdenek Dvorak <dvorakz@suse.cz> 2006-12-13 Zdenek Dvorak <dvorakz@suse.cz>
* tree-ssa-loop-ivopts.c: Include tree-affine.h. * tree-ssa-loop-ivopts.c: Include tree-affine.h.

View File

@ -6606,5 +6606,87 @@ warn_array_subscript_with_type_char (tree index)
warning (OPT_Wchar_subscripts, "array subscript has type %<char%>"); warning (OPT_Wchar_subscripts, "array subscript has type %<char%>");
} }
/* Implement -Wparentheses for the unexpected C precedence rules, to
cover cases like x + y << z which readers are likely to
misinterpret. We have seen an expression in which CODE is a binary
operator used to combine expressions headed by CODE_LEFT and
CODE_RIGHT. CODE_LEFT and CODE_RIGHT may be ERROR_MARK, which
means that that side of the expression was not formed using a
binary operator, or it was enclosed in parentheses. */
void
warn_about_parentheses (enum tree_code code, enum tree_code code_left,
enum tree_code code_right)
{
if (!warn_parentheses)
return;
if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
{
if (code_left == PLUS_EXPR || code_left == MINUS_EXPR
|| code_right == PLUS_EXPR || code_right == MINUS_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around + or - inside shift");
}
if (code == TRUTH_ORIF_EXPR)
{
if (code_left == TRUTH_ANDIF_EXPR
|| code_right == TRUTH_ANDIF_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around && within ||");
}
if (code == BIT_IOR_EXPR)
{
if (code_left == BIT_AND_EXPR || code_left == BIT_XOR_EXPR
|| code_left == PLUS_EXPR || code_left == MINUS_EXPR
|| code_right == BIT_AND_EXPR || code_right == BIT_XOR_EXPR
|| code_right == PLUS_EXPR || code_right == MINUS_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around arithmetic in operand of |");
/* Check cases like x|y==z */
if (TREE_CODE_CLASS (code_left) == tcc_comparison
|| TREE_CODE_CLASS (code_right) == tcc_comparison)
warning (OPT_Wparentheses,
"suggest parentheses around comparison in operand of |");
}
if (code == BIT_XOR_EXPR)
{
if (code_left == BIT_AND_EXPR
|| code_left == PLUS_EXPR || code_left == MINUS_EXPR
|| code_right == BIT_AND_EXPR
|| code_right == PLUS_EXPR || code_right == MINUS_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around arithmetic in operand of ^");
/* Check cases like x^y==z */
if (TREE_CODE_CLASS (code_left) == tcc_comparison
|| TREE_CODE_CLASS (code_right) == tcc_comparison)
warning (OPT_Wparentheses,
"suggest parentheses around comparison in operand of ^");
}
if (code == BIT_AND_EXPR)
{
if (code_left == PLUS_EXPR || code_left == MINUS_EXPR
|| code_right == PLUS_EXPR || code_right == MINUS_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around + or - in operand of &");
/* Check cases like x&y==z */
if (TREE_CODE_CLASS (code_left) == tcc_comparison
|| TREE_CODE_CLASS (code_right) == tcc_comparison)
warning (OPT_Wparentheses,
"suggest parentheses around comparison in operand of &");
}
/* Similarly, check for cases like 1<=i<=10 that are probably errors. */
if (TREE_CODE_CLASS (code) == tcc_comparison
&& (TREE_CODE_CLASS (code_left) == tcc_comparison
|| TREE_CODE_CLASS (code_right) == tcc_comparison))
warning (OPT_Wparentheses, "comparisons like X<=Y<=Z do not "
"have their mathematical meaning");
}
#include "gt-c-common.h" #include "gt-c-common.h"

View File

@ -859,6 +859,9 @@ extern int complete_array_type (tree *, tree, bool);
extern tree builtin_type_for_size (int, bool); extern tree builtin_type_for_size (int, bool);
extern void warn_array_subscript_with_type_char (tree); extern void warn_array_subscript_with_type_char (tree);
extern void warn_about_parentheses (enum tree_code, enum tree_code,
enum tree_code);
/* In c-gimplify.c */ /* In c-gimplify.c */
extern void c_genericize (tree); extern void c_genericize (tree);

View File

@ -2629,73 +2629,7 @@ parser_build_binary_op (enum tree_code code, struct c_expr arg1,
/* Check for cases such as x+y<<z which users are likely /* Check for cases such as x+y<<z which users are likely
to misinterpret. */ to misinterpret. */
if (warn_parentheses) if (warn_parentheses)
{ warn_about_parentheses (code, code1, code2);
if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
{
if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
|| code2 == PLUS_EXPR || code2 == MINUS_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around + or - inside shift");
}
if (code == TRUTH_ORIF_EXPR)
{
if (code1 == TRUTH_ANDIF_EXPR
|| code2 == TRUTH_ANDIF_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around && within ||");
}
if (code == BIT_IOR_EXPR)
{
if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR
|| code1 == PLUS_EXPR || code1 == MINUS_EXPR
|| code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR
|| code2 == PLUS_EXPR || code2 == MINUS_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around arithmetic in operand of |");
/* Check cases like x|y==z */
if (TREE_CODE_CLASS (code1) == tcc_comparison
|| TREE_CODE_CLASS (code2) == tcc_comparison)
warning (OPT_Wparentheses,
"suggest parentheses around comparison in operand of |");
}
if (code == BIT_XOR_EXPR)
{
if (code1 == BIT_AND_EXPR
|| code1 == PLUS_EXPR || code1 == MINUS_EXPR
|| code2 == BIT_AND_EXPR
|| code2 == PLUS_EXPR || code2 == MINUS_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around arithmetic in operand of ^");
/* Check cases like x^y==z */
if (TREE_CODE_CLASS (code1) == tcc_comparison
|| TREE_CODE_CLASS (code2) == tcc_comparison)
warning (OPT_Wparentheses,
"suggest parentheses around comparison in operand of ^");
}
if (code == BIT_AND_EXPR)
{
if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
|| code2 == PLUS_EXPR || code2 == MINUS_EXPR)
warning (OPT_Wparentheses,
"suggest parentheses around + or - in operand of &");
/* Check cases like x&y==z */
if (TREE_CODE_CLASS (code1) == tcc_comparison
|| TREE_CODE_CLASS (code2) == tcc_comparison)
warning (OPT_Wparentheses,
"suggest parentheses around comparison in operand of &");
}
/* Similarly, check for cases like 1<=i<=10 that are probably errors. */
if (TREE_CODE_CLASS (code) == tcc_comparison
&& (TREE_CODE_CLASS (code1) == tcc_comparison
|| TREE_CODE_CLASS (code2) == tcc_comparison))
warning (OPT_Wparentheses, "comparisons like X<=Y<=Z do not "
"have their mathematical meaning");
}
/* Warn about comparisons against string literals, with the exception /* Warn about comparisons against string literals, with the exception
of testing for equality or inequality of a string literal with NULL. */ of testing for equality or inequality of a string literal with NULL. */

View File

@ -1,3 +1,19 @@
2006-12-13 Ian Lance Taylor <iant@google.com>
PR c++/19564
PR c++/19756
* parser.c (cp_parser_expression_stack_entry): Add field
lhs_type.
(cp_parser_binary_expression): Track tree code of left hand side
of expression. Use it when calling build_x_binary_op.
(cp_parser_selection_statement): Add if_p parameter. Change all
callers. Warn about ambiguous else.
(cp_parser_statement): Add if_p parameter. Change all callers.
(cp_parser_implicitly_scoped_statement): Likewise.
* typeck.c (build_x_binary_op): Add parameters arg1_code and
arg2_code. Change all callers. Call warn_about_parentheses.
* cp-tree.h (build_x_binary_op): Update declaration.
2006-12-12 Manuel Lopez-Ibanez <manu@gcc.gnu.org> 2006-12-12 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
* decl.c (build_enumerator): Update error message to match C * decl.c (build_enumerator): Update error message to match C

View File

@ -4458,8 +4458,9 @@ extern tree build_x_indirect_ref (tree, const char *);
extern tree build_indirect_ref (tree, const char *); extern tree build_indirect_ref (tree, const char *);
extern tree build_array_ref (tree, tree); extern tree build_array_ref (tree, tree);
extern tree get_member_function_from_ptrfunc (tree *, tree); extern tree get_member_function_from_ptrfunc (tree *, tree);
extern tree build_x_binary_op (enum tree_code, tree, tree, extern tree build_x_binary_op (enum tree_code, tree,
bool *); enum tree_code, tree,
enum tree_code, bool *);
extern tree build_x_unary_op (enum tree_code, tree); extern tree build_x_unary_op (enum tree_code, tree);
extern tree unary_complex_lvalue (enum tree_code, tree); extern tree unary_complex_lvalue (enum tree_code, tree);
extern tree build_x_conditional_expr (tree, tree, tree); extern tree build_x_conditional_expr (tree, tree, tree);

View File

@ -1158,8 +1158,15 @@ typedef enum cp_parser_status_kind
typedef struct cp_parser_expression_stack_entry typedef struct cp_parser_expression_stack_entry
{ {
/* Left hand side of the binary operation we are currently
parsing. */
tree lhs; tree lhs;
/* Original tree code for left hand side, if it was a binary
expression itself (used for -Wparentheses). */
enum tree_code lhs_type;
/* Tree code for the binary operation we are parsing. */
enum tree_code tree_type; enum tree_code tree_type;
/* Precedence of the binary operation we are parsing. */
int prec; int prec;
} cp_parser_expression_stack_entry; } cp_parser_expression_stack_entry;
@ -1517,7 +1524,7 @@ static tree cp_parser_builtin_offsetof
/* Statements [gram.stmt.stmt] */ /* Statements [gram.stmt.stmt] */
static void cp_parser_statement static void cp_parser_statement
(cp_parser *, tree, bool); (cp_parser *, tree, bool, bool *);
static void cp_parser_label_for_labeled_statement static void cp_parser_label_for_labeled_statement
(cp_parser *); (cp_parser *);
static tree cp_parser_expression_statement static tree cp_parser_expression_statement
@ -1527,7 +1534,7 @@ static tree cp_parser_compound_statement
static void cp_parser_statement_seq_opt static void cp_parser_statement_seq_opt
(cp_parser *, tree); (cp_parser *, tree);
static tree cp_parser_selection_statement static tree cp_parser_selection_statement
(cp_parser *); (cp_parser *, bool *);
static tree cp_parser_condition static tree cp_parser_condition
(cp_parser *); (cp_parser *);
static tree cp_parser_iteration_statement static tree cp_parser_iteration_statement
@ -1540,7 +1547,7 @@ static void cp_parser_declaration_statement
(cp_parser *); (cp_parser *);
static tree cp_parser_implicitly_scoped_statement static tree cp_parser_implicitly_scoped_statement
(cp_parser *); (cp_parser *, bool *);
static void cp_parser_already_scoped_statement static void cp_parser_already_scoped_statement
(cp_parser *); (cp_parser *);
@ -5685,12 +5692,13 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p)
cp_parser_expression_stack_entry *sp = &stack[0]; cp_parser_expression_stack_entry *sp = &stack[0];
tree lhs, rhs; tree lhs, rhs;
cp_token *token; cp_token *token;
enum tree_code tree_type; enum tree_code tree_type, lhs_type, rhs_type;
enum cp_parser_prec prec = PREC_NOT_OPERATOR, new_prec, lookahead_prec; enum cp_parser_prec prec = PREC_NOT_OPERATOR, new_prec, lookahead_prec;
bool overloaded_p; bool overloaded_p;
/* Parse the first expression. */ /* Parse the first expression. */
lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p); lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p);
lhs_type = ERROR_MARK;
for (;;) for (;;)
{ {
@ -5723,6 +5731,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p)
/* Extract another operand. It may be the RHS of this expression /* Extract another operand. It may be the RHS of this expression
or the LHS of a new, higher priority expression. */ or the LHS of a new, higher priority expression. */
rhs = cp_parser_simple_cast_expression (parser); rhs = cp_parser_simple_cast_expression (parser);
rhs_type = ERROR_MARK;
/* Get another operator token. Look up its precedence to avoid /* Get another operator token. Look up its precedence to avoid
building a useless (immediately popped) stack entry for common building a useless (immediately popped) stack entry for common
@ -5738,8 +5747,10 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p)
sp->prec = prec; sp->prec = prec;
sp->tree_type = tree_type; sp->tree_type = tree_type;
sp->lhs = lhs; sp->lhs = lhs;
sp->lhs_type = lhs_type;
sp++; sp++;
lhs = rhs; lhs = rhs;
lhs_type = rhs_type;
prec = new_prec; prec = new_prec;
new_prec = lookahead_prec; new_prec = lookahead_prec;
goto get_rhs; goto get_rhs;
@ -5756,11 +5767,15 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p)
prec = sp->prec; prec = sp->prec;
tree_type = sp->tree_type; tree_type = sp->tree_type;
rhs = lhs; rhs = lhs;
rhs_type = lhs_type;
lhs = sp->lhs; lhs = sp->lhs;
lhs_type = sp->lhs_type;
} }
overloaded_p = false; overloaded_p = false;
lhs = build_x_binary_op (tree_type, lhs, rhs, &overloaded_p); lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
&overloaded_p);
lhs_type = tree_type;
/* If the binary operator required the use of an overloaded operator, /* If the binary operator required the use of an overloaded operator,
then this expression cannot be an integral constant-expression. then this expression cannot be an integral constant-expression.
@ -6177,17 +6192,23 @@ cp_parser_builtin_offsetof (cp_parser *parser)
try-block try-block
IN_COMPOUND is true when the statement is nested inside a IN_COMPOUND is true when the statement is nested inside a
cp_parser_compound_statement; this matters for certain pragmas. */ cp_parser_compound_statement; this matters for certain pragmas.
If IF_P is not NULL, *IF_P is set to indicate whether the statement
is a (possibly labeled) if statement which is not enclosed in braces
and has an else clause. This is used to implement -Wparentheses. */
static void static void
cp_parser_statement (cp_parser* parser, tree in_statement_expr, cp_parser_statement (cp_parser* parser, tree in_statement_expr,
bool in_compound) bool in_compound, bool *if_p)
{ {
tree statement; tree statement;
cp_token *token; cp_token *token;
location_t statement_location; location_t statement_location;
restart: restart:
if (if_p != NULL)
*if_p = false;
/* There is no statement yet. */ /* There is no statement yet. */
statement = NULL_TREE; statement = NULL_TREE;
/* Peek at the next token. */ /* Peek at the next token. */
@ -6212,7 +6233,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
case RID_IF: case RID_IF:
case RID_SWITCH: case RID_SWITCH:
statement = cp_parser_selection_statement (parser); statement = cp_parser_selection_statement (parser, if_p);
break; break;
case RID_WHILE: case RID_WHILE:
@ -6477,7 +6498,7 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
break; break;
/* Parse the statement. */ /* Parse the statement. */
cp_parser_statement (parser, in_statement_expr, true); cp_parser_statement (parser, in_statement_expr, true, NULL);
} }
} }
@ -6488,14 +6509,22 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
if ( condition ) statement else statement if ( condition ) statement else statement
switch ( condition ) statement switch ( condition ) statement
Returns the new IF_STMT or SWITCH_STMT. */ Returns the new IF_STMT or SWITCH_STMT.
If IF_P is not NULL, *IF_P is set to indicate whether the statement
is a (possibly labeled) if statement which is not enclosed in
braces and has an else clause. This is used to implement
-Wparentheses. */
static tree static tree
cp_parser_selection_statement (cp_parser* parser) cp_parser_selection_statement (cp_parser* parser, bool *if_p)
{ {
cp_token *token; cp_token *token;
enum rid keyword; enum rid keyword;
if (if_p != NULL)
*if_p = false;
/* Peek at the next token. */ /* Peek at the next token. */
token = cp_parser_require (parser, CPP_KEYWORD, "selection-statement"); token = cp_parser_require (parser, CPP_KEYWORD, "selection-statement");
@ -6531,11 +6560,13 @@ cp_parser_selection_statement (cp_parser* parser)
if (keyword == RID_IF) if (keyword == RID_IF)
{ {
bool nested_if;
/* Add the condition. */ /* Add the condition. */
finish_if_stmt_cond (condition, statement); finish_if_stmt_cond (condition, statement);
/* Parse the then-clause. */ /* Parse the then-clause. */
cp_parser_implicitly_scoped_statement (parser); cp_parser_implicitly_scoped_statement (parser, &nested_if);
finish_then_clause (statement); finish_then_clause (statement);
/* If the next token is `else', parse the else-clause. */ /* If the next token is `else', parse the else-clause. */
@ -6546,8 +6577,28 @@ cp_parser_selection_statement (cp_parser* parser)
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
begin_else_clause (statement); begin_else_clause (statement);
/* Parse the else-clause. */ /* Parse the else-clause. */
cp_parser_implicitly_scoped_statement (parser); cp_parser_implicitly_scoped_statement (parser, NULL);
finish_else_clause (statement); finish_else_clause (statement);
/* If we are currently parsing a then-clause, then
IF_P will not be NULL. We set it to true to
indicate that this if statement has an else clause.
This may trigger the Wparentheses warning below
when we get back up to the parent if statement. */
if (if_p != NULL)
*if_p = true;
}
else
{
/* This if statement does not have an else clause. If
NESTED_IF is true, then the then-clause is an if
statement which does have an else clause. We warn
about the potential ambiguity. */
if (nested_if)
warning (OPT_Wparentheses,
("%Hsuggest explicit braces "
"to avoid ambiguous %<else%>"),
EXPR_LOCUS (statement));
} }
/* Now we're all done with the if-statement. */ /* Now we're all done with the if-statement. */
@ -6566,7 +6617,7 @@ cp_parser_selection_statement (cp_parser* parser)
in_statement = parser->in_statement; in_statement = parser->in_statement;
parser->in_switch_statement_p = true; parser->in_switch_statement_p = true;
parser->in_statement |= IN_SWITCH_STMT; parser->in_statement |= IN_SWITCH_STMT;
cp_parser_implicitly_scoped_statement (parser); cp_parser_implicitly_scoped_statement (parser, NULL);
parser->in_switch_statement_p = in_switch_statement_p; parser->in_switch_statement_p = in_switch_statement_p;
parser->in_statement = in_statement; parser->in_statement = in_statement;
@ -6744,7 +6795,7 @@ cp_parser_iteration_statement (cp_parser* parser)
statement = begin_do_stmt (); statement = begin_do_stmt ();
/* Parse the body of the do-statement. */ /* Parse the body of the do-statement. */
parser->in_statement = IN_ITERATION_STMT; parser->in_statement = IN_ITERATION_STMT;
cp_parser_implicitly_scoped_statement (parser); cp_parser_implicitly_scoped_statement (parser, NULL);
parser->in_statement = in_statement; parser->in_statement = in_statement;
finish_do_body (statement); finish_do_body (statement);
/* Look for the `while' keyword. */ /* Look for the `while' keyword. */
@ -6986,13 +7037,21 @@ cp_parser_declaration_statement (cp_parser* parser)
but ensures that is in its own scope, even if it is not a but ensures that is in its own scope, even if it is not a
compound-statement. compound-statement.
If IF_P is not NULL, *IF_P is set to indicate whether the statement
is a (possibly labeled) if statement which is not enclosed in
braces and has an else clause. This is used to implement
-Wparentheses.
Returns the new statement. */ Returns the new statement. */
static tree static tree
cp_parser_implicitly_scoped_statement (cp_parser* parser) cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p)
{ {
tree statement; tree statement;
if (if_p != NULL)
*if_p = false;
/* Mark if () ; with a special NOP_EXPR. */ /* Mark if () ; with a special NOP_EXPR. */
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
{ {
@ -7008,7 +7067,7 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser)
/* Create a compound-statement. */ /* Create a compound-statement. */
statement = begin_compound_stmt (0); statement = begin_compound_stmt (0);
/* Parse the dependent-statement. */ /* Parse the dependent-statement. */
cp_parser_statement (parser, NULL_TREE, false); cp_parser_statement (parser, NULL_TREE, false, if_p);
/* Finish the dummy compound-statement. */ /* Finish the dummy compound-statement. */
finish_compound_stmt (statement); finish_compound_stmt (statement);
} }
@ -7027,7 +7086,7 @@ cp_parser_already_scoped_statement (cp_parser* parser)
{ {
/* If the token is a `{', then we must take special action. */ /* If the token is a `{', then we must take special action. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)) if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
cp_parser_statement (parser, NULL_TREE, false); cp_parser_statement (parser, NULL_TREE, false, NULL);
else else
{ {
/* Avoid calling cp_parser_compound_statement, so that we /* Avoid calling cp_parser_compound_statement, so that we
@ -18654,7 +18713,7 @@ cp_parser_omp_structured_block (cp_parser *parser)
tree stmt = begin_omp_structured_block (); tree stmt = begin_omp_structured_block ();
unsigned int save = cp_parser_begin_omp_structured_block (parser); unsigned int save = cp_parser_begin_omp_structured_block (parser);
cp_parser_statement (parser, NULL_TREE, false); cp_parser_statement (parser, NULL_TREE, false, NULL);
cp_parser_end_omp_structured_block (parser, save); cp_parser_end_omp_structured_block (parser, save);
return finish_omp_structured_block (stmt); return finish_omp_structured_block (stmt);
@ -18899,7 +18958,7 @@ cp_parser_omp_for_loop (cp_parser *parser)
/* Note that the grammar doesn't call for a structured block here, /* Note that the grammar doesn't call for a structured block here,
though the loop as a whole is a structured block. */ though the loop as a whole is a structured block. */
body = push_stmt_list (); body = push_stmt_list ();
cp_parser_statement (parser, NULL_TREE, false); cp_parser_statement (parser, NULL_TREE, false, NULL);
body = pop_stmt_list (body); body = pop_stmt_list (body);
return finish_omp_for (loc, decl, init, cond, incr, body, pre_body); return finish_omp_for (loc, decl, init, cond, incr, body, pre_body);
@ -18992,7 +19051,7 @@ cp_parser_omp_sections_scope (cp_parser *parser)
while (1) while (1)
{ {
cp_parser_statement (parser, NULL_TREE, false); cp_parser_statement (parser, NULL_TREE, false, NULL);
tok = cp_lexer_peek_token (parser->lexer); tok = cp_lexer_peek_token (parser->lexer);
if (tok->pragma_kind == PRAGMA_OMP_SECTION) if (tok->pragma_kind == PRAGMA_OMP_SECTION)

View File

@ -9105,7 +9105,13 @@ tsubst_copy_and_build (tree t,
return build_x_binary_op return build_x_binary_op
(TREE_CODE (t), (TREE_CODE (t),
RECUR (TREE_OPERAND (t, 0)), RECUR (TREE_OPERAND (t, 0)),
(TREE_NO_WARNING (TREE_OPERAND (t, 0))
? ERROR_MARK
: TREE_CODE (TREE_OPERAND (t, 0))),
RECUR (TREE_OPERAND (t, 1)), RECUR (TREE_OPERAND (t, 1)),
(TREE_NO_WARNING (TREE_OPERAND (t, 1))
? ERROR_MARK
: TREE_CODE (TREE_OPERAND (t, 1))),
/*overloaded_p=*/NULL); /*overloaded_p=*/NULL);
case SCOPE_REF: case SCOPE_REF:
@ -9114,7 +9120,14 @@ tsubst_copy_and_build (tree t,
case ARRAY_REF: case ARRAY_REF:
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
args, complain, in_decl); args, complain, in_decl);
return build_x_binary_op (ARRAY_REF, op1, RECUR (TREE_OPERAND (t, 1)), return build_x_binary_op (ARRAY_REF, op1,
(TREE_NO_WARNING (TREE_OPERAND (t, 0))
? ERROR_MARK
: TREE_CODE (TREE_OPERAND (t, 0))),
RECUR (TREE_OPERAND (t, 1)),
(TREE_NO_WARNING (TREE_OPERAND (t, 1))
? ERROR_MARK
: TREE_CODE (TREE_OPERAND (t, 1))),
/*overloaded_p=*/NULL); /*overloaded_p=*/NULL);
case SIZEOF_EXPR: case SIZEOF_EXPR:

View File

@ -1648,17 +1648,20 @@ rationalize_conditional_expr (enum tree_code code, tree t)
are equal, so we know what conditional expression this used to be. */ are equal, so we know what conditional expression this used to be. */
if (TREE_CODE (t) == MIN_EXPR || TREE_CODE (t) == MAX_EXPR) if (TREE_CODE (t) == MIN_EXPR || TREE_CODE (t) == MAX_EXPR)
{ {
tree op0 = TREE_OPERAND (t, 0);
tree op1 = TREE_OPERAND (t, 1);
/* The following code is incorrect if either operand side-effects. */ /* The following code is incorrect if either operand side-effects. */
gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 0)) gcc_assert (!TREE_SIDE_EFFECTS (op0)
&& !TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1))); && !TREE_SIDE_EFFECTS (op1));
return return
build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR
? LE_EXPR : GE_EXPR), ? LE_EXPR : GE_EXPR),
TREE_OPERAND (t, 0), op0, TREE_CODE (op0),
TREE_OPERAND (t, 1), op1, TREE_CODE (op1),
/*overloaded_p=*/NULL), /*overloaded_p=*/NULL),
build_unary_op (code, TREE_OPERAND (t, 0), 0), build_unary_op (code, op0, 0),
build_unary_op (code, TREE_OPERAND (t, 1), 0)); build_unary_op (code, op1, 0));
} }
return return
@ -2865,11 +2868,19 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
} }
/* Build a binary-operation expression, after performing default /* Build a binary-operation expression, after performing default
conversions on the operands. CODE is the kind of expression to build. */ conversions on the operands. CODE is the kind of expression to
build. ARG1 and ARG2 are the arguments. ARG1_CODE and ARG2_CODE
are the tree codes which correspond to ARG1 and ARG2 when issuing
warnings about possibly misplaced parentheses. They may differ
from the TREE_CODE of ARG1 and ARG2 if the parser has done constant
folding (e.g., if the parser sees "a | 1 + 1", it may call this
routine with ARG2 being an INTEGER_CST and ARG2_CODE == PLUS_EXPR).
To avoid issuing any parentheses warnings, pass ARG1_CODE and/or
ARG2_CODE as ERROR_MARK. */
tree tree
build_x_binary_op (enum tree_code code, tree arg1, tree arg2, build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code,
bool *overloaded_p) tree arg2, enum tree_code arg2_code, bool *overloaded_p)
{ {
tree orig_arg1; tree orig_arg1;
tree orig_arg2; tree orig_arg2;
@ -2893,6 +2904,17 @@ build_x_binary_op (enum tree_code code, tree arg1, tree arg2,
expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE, expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
overloaded_p); overloaded_p);
/* Check for cases such as x+y<<z which users are likely to
misinterpret. But don't warn about obj << x + y, since that is a
common idiom for I/O. */
if (warn_parentheses
&& !processing_template_decl
&& !error_operand_p (arg1)
&& !error_operand_p (arg2)
&& (code != LSHIFT_EXPR
|| !CLASS_TYPE_P (TREE_TYPE (arg1))))
warn_about_parentheses (code, arg1_code, arg2_code);
if (processing_template_decl && expr != error_mark_node) if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep (code, expr, orig_arg1, orig_arg2); return build_min_non_dep (code, expr, orig_arg1, orig_arg2);

View File

@ -2531,9 +2531,7 @@ Warn if a user-supplied include directory does not exist.
Warn if parentheses are omitted in certain contexts, such Warn if parentheses are omitted in certain contexts, such
as when there is an assignment in a context where a truth value as when there is an assignment in a context where a truth value
is expected, or when operators are nested whose precedence people is expected, or when operators are nested whose precedence people
often get confused about. Only the warning for an assignment used as often get confused about.
a truth value is supported when compiling C++; the other warnings are
only supported when compiling C@.
Also warn if a comparison like @samp{x<=y<=z} appears; this is Also warn if a comparison like @samp{x<=y<=z} appears; this is
equivalent to @samp{(x<=y ? 1 : 0) <= z}, which is a different equivalent to @samp{(x<=y ? 1 : 0) <= z}, which is a different
@ -2555,14 +2553,15 @@ such a case:
@end group @end group
@end smallexample @end smallexample
In C, every @code{else} branch belongs to the innermost possible @code{if} In C/C++, every @code{else} branch belongs to the innermost possible
statement, which in this example is @code{if (b)}. This is often not @code{if} statement, which in this example is @code{if (b)}. This is
what the programmer expected, as illustrated in the above example by often not what the programmer expected, as illustrated in the above
indentation the programmer chose. When there is the potential for this example by indentation the programmer chose. When there is the
confusion, GCC will issue a warning when this flag is specified. potential for this confusion, GCC will issue a warning when this flag
To eliminate the warning, add explicit braces around the innermost is specified. To eliminate the warning, add explicit braces around
@code{if} statement so there is no way the @code{else} could belong to the innermost @code{if} statement so there is no way the @code{else}
the enclosing @code{if}. The resulting code would look like this: could belong to the enclosing @code{if}. The resulting code would
look like this:
@smallexample @smallexample
@group @group

View File

@ -1,3 +1,25 @@
2006-12-13 Ian Lance Taylor <iant@google.com>
PR c++/19564
PR c++/19756
* g++.dg/warn/Wparentheses-5.C: New test.
* g++.dg/warn/Wparentheses-6.C: New test.
* g++.dg/warn/Wparentheses-7.C: New test.
* g++.dg/warn/Wparentheses-8.C: New test.
* g++.dg/warn/Wparentheses-9.C: New test.
* g++.dg/warn/Wparentheses-10.C: New test.
* g++.dg/warn/Wparentheses-11.C: New test.
* g++.dg/warn/Wparentheses-12.C: New test.
* g++.dg/warn/Wparentheses-13.C: New test.
* g++.dg/warn/Wparentheses-14.C: New test.
* g++.dg/warn/Wparentheses-15.C: New test.
* g++.dg/warn/Wparentheses-16.C: New test.
* g++.dg/warn/Wparentheses-17.C: New test.
* g++.dg/warn/Wparentheses-18.C: New test.
* g++.dg/warn/Wparentheses-19.C: New test.
* g++.dg/warn/Wparentheses-20.C: New test.
* g++.dg/warn/Wparentheses-21.C: New test.
2006-12-13 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2006-12-13 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR testsuite/30157 PR testsuite/30157

View File

@ -0,0 +1,119 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// C++ version of gcc.dg/Wparentheses-7.c
int foo (int);
int
bar (int a, int b, int c)
{
foo (a & b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) ^ c);
foo (a & (b ^ c));
foo (1 & 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) ^ c);
foo (1 & (2 ^ c));
foo (1 & 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) ^ 3);
foo (1 & (2 ^ 3));
foo (a ^ b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) & c);
foo (a ^ (b & c));
foo (1 ^ 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) & c);
foo (1 ^ (2 & c));
foo (1 ^ 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) & 3);
foo (1 ^ (2 & 3));
foo (a + b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) ^ c);
foo (a + (b ^ c));
foo (1 + 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) ^ c);
foo (1 + (2 ^ c));
foo (1 + 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) ^ 3);
foo (1 + (2 ^ 3));
foo (a ^ b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) + c);
foo (a ^ (b + c));
foo (1 ^ 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) + c);
foo (1 ^ (2 + c));
foo (1 ^ 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) + 3);
foo (1 ^ (2 + 3));
foo (a - b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) ^ c);
foo (a - (b ^ c));
foo (1 - 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) ^ c);
foo (1 - (2 ^ c));
foo (1 - 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) ^ 3);
foo (1 - (2 ^ 3));
foo (a ^ b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) - c);
foo (a ^ (b - c));
foo (1 ^ 2 - c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) - c);
foo (1 ^ (2 - c));
foo (1 ^ 2 - 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) - 3);
foo (1 ^ (2 - 3));
foo (a >= b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a >= b) ^ c);
foo (a >= (b ^ c));
foo (1 >= 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 >= 2) ^ c);
foo (1 >= (2 ^ c));
foo (1 >= 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 >= 2) ^ 3);
foo (1 >= (2 ^ 3));
foo (a ^ b >= c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) >= c);
foo (a ^ (b >= c));
foo (1 ^ 2 >= c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) >= c);
foo (1 ^ (2 >= c));
foo (1 ^ 2 >= 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) >= 3);
foo (1 ^ (2 >= 3));
foo (a == b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a == b) ^ c);
foo (a == (b ^ c));
foo (1 == 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) ^ c);
foo (1 == (2 ^ c));
foo (1 == 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) ^ 3);
foo (1 == (2 ^ 3));
foo (a ^ b == c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) == c);
foo (a ^ (b == c));
foo (1 ^ 2 == c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) == c);
foo (1 ^ (2 == c));
foo (1 ^ 2 == 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) == 3);
foo (1 ^ (2 == 3));
foo (a < b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a < b) ^ c);
foo (a < (b ^ c));
foo (1 < 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) ^ c);
foo (1 < (2 ^ c));
foo (1 < 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) ^ 3);
foo (1 < (2 ^ 3));
foo (a ^ b < c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) < c);
foo (a ^ (b < c));
foo (1 ^ 2 < c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) < c);
foo (1 ^ (2 < c));
foo (1 ^ 2 < 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) < 3);
foo (1 ^ (2 < 3));
}

View File

@ -0,0 +1,101 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// C++ version of gcc.dg/Wparentheses-8.c
int foo (int);
int
bar (int a, int b, int c)
{
foo (a + b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) & c);
foo (a + (b & c));
foo (1 + 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) & c);
foo (1 + (2 & c));
foo (1 + 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) & 3);
foo (1 + (2 & 3));
foo (a & b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) + c);
foo (a & (b + c));
foo (1 & 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) + c);
foo (1 & (2 + c));
foo (1 & 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) + 3);
foo (1 & (2 + 3));
foo (a - b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) & c);
foo (a - (b & c));
foo (1 - 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) & c);
foo (1 - (2 & c));
foo (1 - 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) & 3);
foo (1 - (2 & 3));
foo (a & b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) - c);
foo (a & (b - c));
foo (1 & 2 - c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) - c);
foo (1 & (2 - c));
foo (1 & 2 - 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) - 3);
foo (1 & (2 - 3));
foo (a < b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a < b) & c);
foo (a < (b & c));
foo (1 < 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) & c);
foo (1 < (2 & c));
foo (1 < 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) & 3);
foo (1 < (2 & 3));
foo (a & b < c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) < c);
foo (a & (b < c));
foo (1 & 2 < c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) < c);
foo (1 & (2 < c));
foo (1 & 2 < 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) < 3);
foo (1 & (2 < 3));
foo (a == b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a == b) & c);
foo (a == (b & c));
foo (1 == 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) & c);
foo (1 == (2 & c));
foo (1 == 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) & 3);
foo (1 == (2 & 3));
foo (a & b == c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) == c);
foo (a & (b == c));
foo (1 & 2 == c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) == c);
foo (1 & (2 == c));
foo (1 & 2 == 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) == 3);
foo (1 & (2 == 3));
foo (a != b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a != b) & c);
foo (a != (b & c));
foo (1 != 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 != 2) & c);
foo (1 != (2 & c));
foo (1 != 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 != 2) & 3);
foo (1 != (2 & 3));
foo (a & b != c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) != c);
foo (a & (b != c));
foo (1 & 2 != c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) != c);
foo (1 & (2 != c));
foo (1 & 2 != 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) != 3);
foo (1 & (2 != 3));
}

View File

@ -0,0 +1,60 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// C++ version of gcc.dg/Wparentheses-9.c
int foo (int);
int a, b, c;
int
bar (void)
{
if (a)
foo (0);
if (b)
foo (1);
else
foo (2);
if (c) // { dg-warning "ambiguous" "correct warning" }
if (a)
foo (3);
else
foo (4);
if (a)
if (c)
foo (5);
if (a)
if (b) // { dg-warning "ambiguous" "correct warning" }
if (c)
foo (6);
else
foo (7);
if (a) // { dg-warning "ambiguous" "correct warning" }
if (b)
if (c)
foo (8);
else
foo (9);
else
foo (10);
if (a)
if (b)
if (c)
foo (11);
else
foo (12);
else
foo (13);
else
foo (14);
if (a) {
if (b)
if (c)
foo (15);
else
foo (16);
else
foo (17);
}
}

View File

@ -0,0 +1,69 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-1.C.
int foo (int);
int a, b, c;
bool d;
template<class T>
void
bar (T)
{
if (a = b) // { dg-warning "assignment" "correct warning" }
foo (0);
if ((a = b))
foo (1);
if (a = a) // { dg-warning "assignment" "correct warning" }
foo (2);
if ((a = a))
foo (3);
if (b = c) // { dg-warning "assignment" "correct warning" }
foo (4);
else
foo (5);
if ((b = c))
foo (6);
else
foo (7);
if (b = b) // { dg-warning "assignment" "correct warning" }
foo (8);
else
foo (9);
if ((b = b))
foo (10);
else
foo (11);
while (c = b) // { dg-warning "assignment" "correct warning" }
foo (12);
while ((c = b))
foo (13);
while (c = c) // { dg-warning "assignment" "correct warning" }
foo (14);
while ((c = c))
foo (15);
do foo (16); while (a = b); // { dg-warning "assignment" "correct warning" }
do foo (17); while ((a = b));
do foo (18); while (a = a); // { dg-warning "assignment" "correct warning" }
do foo (19); while ((a = a));
for (;c = b;) // { dg-warning "assignment" "correct warning" }
foo (20);
for (;(c = b);)
foo (21);
for (;c = c;) // { dg-warning "assignment" "correct warning" }
foo (22);
for (;(c = c);)
foo (23);
d = a = b; // { dg-warning "assignment" "correct warning" }
foo (24);
d = (a = b);
foo (25);
d = a = a; // { dg-warning "assignment" "correct warning" }
foo (26);
d = (a = a);
foo (27);
}
template void bar<int> (int); // { dg-warning "instantiated" }

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-2.C.
int foo (int);
int a, b, c;
bool d;
template<class T>
void
bar (T)
{
if (a += b)
foo (0);
if (a -= a)
foo (1);
if (b *= c)
foo (2);
else
foo (3);
if (b /= b)
foo (4);
else
foo (5);
while (c %= b)
foo (6);
while (c <<= c)
foo (7);
do foo (8); while (a >>= b);
do foo (9); while (a &= a);
for (;c ^= b;)
foo (10);
for (;c |= c;)
foo (11);
d = a += b;
foo (12);
d = a -= a;
foo (13);
}
template void bar<int> (int);

View File

@ -0,0 +1,68 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-6.C.
int foo (int);
template<class T>
void
bar (T a, T b, T c)
{
foo (a <= b <= c); // { dg-warning "comparison" "correct warning" }
foo ((a <= b) <= c);
foo (a <= (b <= c));
foo (1 <= 2 <= c); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) <= c);
foo (1 <= (2 <= c));
foo (1 <= 2 <= 3); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) <= 3);
foo (1 <= (2 <= 3));
foo (a > b > c); // { dg-warning "comparison" "correct warning" }
foo ((a > b) > c);
foo (a > (b > c));
foo (1 > 2 > c); // { dg-warning "comparison" "correct warning" }
foo ((1 > 2) > c);
foo (1 > (2 > c));
foo (1 > 2 > 3); // { dg-warning "comparison" "correct warning" }
foo ((1 > 2) > 3);
foo (1 > (2 > 3));
foo (a < b <= c); // { dg-warning "comparison" "correct warning" }
foo ((a < b) <= c);
foo (a < (b <= c));
foo (1 < 2 <= c); // { dg-warning "comparison" "correct warning" }
foo ((1 < 2) <= c);
foo (1 < (2 <= c));
foo (1 < 2 <= 3); // { dg-warning "comparison" "correct warning" }
foo ((1 < 2) <= 3);
foo (1 < (2 <= 3));
foo (a <= b > c); // { dg-warning "comparison" "correct warning" }
foo ((a <= b) > c);
foo (a <= (b > c));
foo (1 <= 2 > c); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) > c);
foo (1 <= (2 > c));
foo (1 <= 2 > 3); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) > 3);
foo (1 <= (2 > 3));
foo (a <= b == c); // { dg-warning "comparison" "correct warning" }
foo ((a <= b) == c);
foo (a <= (b == c));
foo (1 <= 2 == c); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) == c);
foo (1 <= (2 == c));
foo (1 <= 2 == 3); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) == 3);
foo (1 <= (2 == 3));
foo (a != b != c); // { dg-warning "comparison" "correct warning" }
foo ((a != b) != c);
foo (a != (b != c));
foo (1 != 2 != c); // { dg-warning "comparison" "correct warning" }
foo ((1 != 2) != c);
foo (1 != (2 != c));
foo (1 != 2 != 3); // { dg-warning "comparison" "correct warning" }
foo ((1 != 2) != 3);
foo (1 != (2 != 3));
}
template void bar<int> (int, int, int); // { dg-warning "instantiated" }

View File

@ -0,0 +1,86 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-7.C.
int foo (int);
template<class T>
void
bar (T a, T b, T c)
{
foo (a + b << c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) << c);
foo (a + (b << c));
foo (1 + 2 << c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) << c);
foo (1 + (2 << c));
foo (1 + 2 << 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) << 3);
foo (1 + (2 << 3));
foo (a << b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a << b) + c);
foo (a << (b + c));
foo (1 << 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 << 2) + c);
foo (1 << (2 + c));
foo (1 << 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 << 2) + 3);
foo (1 << (2 + 3));
foo (a + b >> c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) >> c);
foo (a + (b >> c));
foo (1 + 2 >> c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) >> c);
foo (1 + (2 >> c));
foo (1 + 2 >> 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) >> 3);
foo (1 + (2 >> 3));
foo (a >> b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a >> b) + c);
foo (a >> (b + c));
foo (1 >> 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 >> 2) + c);
foo (1 >> (2 + c));
foo (1 >> 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 >> 2) + 3);
foo (1 >> (2 + 3));
foo (a - b << c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) << c);
foo (a - (b << c));
foo (6 - 5 << c); // { dg-warning "parentheses" "correct warning" }
foo ((6 - 5) << c);
foo (6 - (5 << c));
foo (6 - 5 << 4); // { dg-warning "parentheses" "correct warning" }
foo ((6 - 5) << 4);
foo (6 - (5 << 4));
foo (a << b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a << b) - c);
foo (a << (b - c));
foo (6 << 5 - c); // { dg-warning "parentheses" "correct warning" }
foo ((6 << 5) - c);
foo (6 << (5 - c));
foo (6 << 5 - 4); // { dg-warning "parentheses" "correct warning" }
foo ((6 << 5) - 4);
foo (6 << (5 - 4));
foo (a - b >> c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) >> c);
foo (a - (b >> c));
foo (6 - 5 >> c); // { dg-warning "parentheses" "correct warning" }
foo ((6 - 5) >> c);
foo (6 - (5 >> c));
foo (6 - 5 >> 4); // { dg-warning "parentheses" "correct warning" }
foo ((6 - 5) >> 4);
foo (6 - (5 >> 4));
foo (a >> b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a >> b) - c);
foo (a >> (b - c));
foo (6 >> 5 - c); // { dg-warning "parentheses" "correct warning" }
foo ((6 >> 5) - c);
foo (6 >> (5 - c));
foo (6 >> 5 - 4); // { dg-warning "parentheses" "correct warning" }
foo ((6 >> 5) - 4);
foo (6 >> (5 - 4));
}
template void bar<int> (int, int, int); // { dg-warning "instantiated" }

View File

@ -0,0 +1,32 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-8.C.
int foo (int);
template<class T>
void
bar (T a, T b, T c)
{
foo (a && b || c); // { dg-warning "parentheses" "correct warning" }
foo ((a && b) || c);
foo (a && (b || c));
foo (1 && 2 || c); // { dg-warning "parentheses" "correct warning" }
foo ((1 && 2) || c);
foo (1 && (2 || c));
foo (1 && 2 || 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 && 2) || 3);
foo (1 && (2 || 3));
foo (a || b && c); // { dg-warning "parentheses" "correct warning" }
foo ((a || b) && c);
foo (a || (b && c));
foo (1 || 2 && c); // { dg-warning "parentheses" "correct warning" }
foo ((1 || 2) && c);
foo (1 || (2 && c));
foo (1 || 2 && 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 || 2) && 3);
foo (1 || (2 && 3));
}
template void bar<int> (int, int, int); // { dg-warning "instantiated" }

View File

@ -0,0 +1,122 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-9.C.
int foo (int);
template<class T>
void
bar (T a, T b, T c)
{
foo (a & b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) | c);
foo (a & (b | c));
foo (1 & 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) | c);
foo (1 & (2 | c));
foo (1 & 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) | 3);
foo (1 & (2 | 3));
foo (a | b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) & c);
foo (a | (b & c));
foo (1 | 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) & c);
foo (1 | (2 & c));
foo (1 | 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) & 3);
foo (1 | (2 & 3));
foo (a ^ b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) | c);
foo (a ^ (b | c));
foo (1 ^ 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) | c);
foo (1 ^ (2 | c));
foo (1 ^ 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) | 3);
foo (1 ^ (2 | 3));
foo (a | b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) ^ c);
foo (a | (b ^ c));
foo (1 | 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) ^ c);
foo (1 | (2 ^ c));
foo (1 | 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) ^ 3);
foo (1 | (2 ^ 3));
foo (a + b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) | c);
foo (a + (b | c));
foo (1 + 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) | c);
foo (1 + (2 | c));
foo (1 + 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) | 3);
foo (1 + (2 | 3));
foo (a | b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) + c);
foo (a | (b + c));
foo (1 | 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) + c);
foo (1 | (2 + c));
foo (1 | 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) + 3);
foo (1 | (2 + 3));
foo (a - b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) | c);
foo (a - (b | c));
foo (1 - 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) | c);
foo (1 - (2 | c));
foo (1 - 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) | 3);
foo (1 - (2 | 3));
foo (a | b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) - c);
foo (a | (b - c));
foo (1 | 2 - c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) - c);
foo (1 | (2 - c));
foo (1 | 2 - 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) - 3);
foo (1 | (2 - 3));
foo (a > b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a > b) | c);
foo (a > (b | c));
foo (1 > 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 > 2) | c);
foo (1 > (2 | c));
foo (1 > 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 > 2) | 3);
foo (1 > (2 | 3));
foo (a | b > c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) > c);
foo (a | (b > c));
foo (1 | 2 > c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) > c);
foo (1 | (2 > c));
foo (1 | 2 > 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) > 3);
foo (1 | (2 > 3));
foo (a <= b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a <= b) | c);
foo (a <= (b | c));
foo (1 <= 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 <= 2) | c);
foo (1 <= (2 | c));
foo (1 <= 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 <= 2) | 3);
foo (1 <= (2 | 3));
foo (a | b <= c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) <= c);
foo (a | (b <= c));
foo (1 | 2 <= c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) <= c);
foo (1 | (2 <= c));
foo (1 | 2 <= 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) <= 3);
foo (1 | (2 <= 3));
}
template void bar<int> (int, int, int); // { dg-warning "instantiated" }

View File

@ -0,0 +1,122 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-10.C.
int foo (int);
template<class T>
void
bar (T a, T b, T c)
{
foo (a & b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) ^ c);
foo (a & (b ^ c));
foo (1 & 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) ^ c);
foo (1 & (2 ^ c));
foo (1 & 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) ^ 3);
foo (1 & (2 ^ 3));
foo (a ^ b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) & c);
foo (a ^ (b & c));
foo (1 ^ 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) & c);
foo (1 ^ (2 & c));
foo (1 ^ 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) & 3);
foo (1 ^ (2 & 3));
foo (a + b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) ^ c);
foo (a + (b ^ c));
foo (1 + 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) ^ c);
foo (1 + (2 ^ c));
foo (1 + 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) ^ 3);
foo (1 + (2 ^ 3));
foo (a ^ b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) + c);
foo (a ^ (b + c));
foo (1 ^ 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) + c);
foo (1 ^ (2 + c));
foo (1 ^ 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) + 3);
foo (1 ^ (2 + 3));
foo (a - b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) ^ c);
foo (a - (b ^ c));
foo (1 - 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) ^ c);
foo (1 - (2 ^ c));
foo (1 - 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) ^ 3);
foo (1 - (2 ^ 3));
foo (a ^ b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) - c);
foo (a ^ (b - c));
foo (1 ^ 2 - c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) - c);
foo (1 ^ (2 - c));
foo (1 ^ 2 - 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) - 3);
foo (1 ^ (2 - 3));
foo (a >= b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a >= b) ^ c);
foo (a >= (b ^ c));
foo (1 >= 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 >= 2) ^ c);
foo (1 >= (2 ^ c));
foo (1 >= 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 >= 2) ^ 3);
foo (1 >= (2 ^ 3));
foo (a ^ b >= c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) >= c);
foo (a ^ (b >= c));
foo (1 ^ 2 >= c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) >= c);
foo (1 ^ (2 >= c));
foo (1 ^ 2 >= 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) >= 3);
foo (1 ^ (2 >= 3));
foo (a == b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a == b) ^ c);
foo (a == (b ^ c));
foo (1 == 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) ^ c);
foo (1 == (2 ^ c));
foo (1 == 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) ^ 3);
foo (1 == (2 ^ 3));
foo (a ^ b == c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) == c);
foo (a ^ (b == c));
foo (1 ^ 2 == c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) == c);
foo (1 ^ (2 == c));
foo (1 ^ 2 == 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) == 3);
foo (1 ^ (2 == 3));
foo (a < b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a < b) ^ c);
foo (a < (b ^ c));
foo (1 < 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) ^ c);
foo (1 < (2 ^ c));
foo (1 < 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) ^ 3);
foo (1 < (2 ^ 3));
foo (a ^ b < c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) < c);
foo (a ^ (b < c));
foo (1 ^ 2 < c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) < c);
foo (1 ^ (2 < c));
foo (1 ^ 2 < 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) < 3);
foo (1 ^ (2 < 3));
}
template void bar<int> (int, int, int); // { dg-warning "instantiated" }

View File

@ -0,0 +1,104 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-11.C.
int foo (int);
template<class T>
void
bar (T a, T b, T c)
{
foo (a + b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) & c);
foo (a + (b & c));
foo (1 + 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) & c);
foo (1 + (2 & c));
foo (1 + 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) & 3);
foo (1 + (2 & 3));
foo (a & b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) + c);
foo (a & (b + c));
foo (1 & 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) + c);
foo (1 & (2 + c));
foo (1 & 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) + 3);
foo (1 & (2 + 3));
foo (a - b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) & c);
foo (a - (b & c));
foo (1 - 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) & c);
foo (1 - (2 & c));
foo (1 - 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) & 3);
foo (1 - (2 & 3));
foo (a & b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) - c);
foo (a & (b - c));
foo (1 & 2 - c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) - c);
foo (1 & (2 - c));
foo (1 & 2 - 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) - 3);
foo (1 & (2 - 3));
foo (a < b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a < b) & c);
foo (a < (b & c));
foo (1 < 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) & c);
foo (1 < (2 & c));
foo (1 < 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 < 2) & 3);
foo (1 < (2 & 3));
foo (a & b < c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) < c);
foo (a & (b < c));
foo (1 & 2 < c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) < c);
foo (1 & (2 < c));
foo (1 & 2 < 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) < 3);
foo (1 & (2 < 3));
foo (a == b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a == b) & c);
foo (a == (b & c));
foo (1 == 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) & c);
foo (1 == (2 & c));
foo (1 == 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 == 2) & 3);
foo (1 == (2 & 3));
foo (a & b == c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) == c);
foo (a & (b == c));
foo (1 & 2 == c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) == c);
foo (1 & (2 == c));
foo (1 & 2 == 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) == 3);
foo (1 & (2 == 3));
foo (a != b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a != b) & c);
foo (a != (b & c));
foo (1 != 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 != 2) & c);
foo (1 != (2 & c));
foo (1 != 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 != 2) & 3);
foo (1 != (2 & 3));
foo (a & b != c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) != c);
foo (a & (b != c));
foo (1 & 2 != c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) != c);
foo (1 & (2 != c));
foo (1 & 2 != 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) != 3);
foo (1 & (2 != 3));
}
template void bar<int> (int, int, int); // { dg-warning "instantiated" }

View File

@ -0,0 +1,66 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-12.C. Note that we currently warn
// when we initially parse the template, not when we are instantiating
// it. That seems reasonable since the template parameters can not
// affect the syntax parsing.
int foo (int);
int a, b, c;
template<class T>
void
bar (T)
{
if (a)
foo (0);
if (b)
foo (1);
else
foo (2);
if (c) // { dg-warning "ambiguous" "correct warning" }
if (a)
foo (3);
else
foo (4);
if (a)
if (c)
foo (5);
if (a)
if (b) // { dg-warning "ambiguous" "correct warning" }
if (c)
foo (6);
else
foo (7);
if (a) // { dg-warning "ambiguous" "correct warning" }
if (b)
if (c)
foo (8);
else
foo (9);
else
foo (10);
if (a)
if (b)
if (c)
foo (11);
else
foo (12);
else
foo (13);
else
foo (14);
if (a) {
if (b)
if (c)
foo (15);
else
foo (16);
else
foo (17);
}
}
template void bar<int> (int);

View File

@ -0,0 +1,12 @@
// { dg-do compile }
// { dg-options -Wparentheses }
// C++ version of gcc.dg/Wparentheses-1.c.
int foo (int a, int b)
{
int c = (a && b) || 0; // { dg-bogus "suggest parentheses" }
c = a && b || 0; // { dg-warning "suggest parentheses" }
return (a && b && 1) || 0; // { dg-bogus "suggest parentheses" }
}

View File

@ -0,0 +1,65 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// C++ version of gcc.dg/Wparentheses-2.c.
int foo (int);
int
bar (int a, int b, int c)
{
foo (a <= b <= c); // { dg-warning "comparison" "correct warning" }
foo ((a <= b) <= c);
foo (a <= (b <= c));
foo (1 <= 2 <= c); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) <= c);
foo (1 <= (2 <= c));
foo (1 <= 2 <= 3); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) <= 3);
foo (1 <= (2 <= 3));
foo (a > b > c); // { dg-warning "comparison" "correct warning" }
foo ((a > b) > c);
foo (a > (b > c));
foo (1 > 2 > c); // { dg-warning "comparison" "correct warning" }
foo ((1 > 2) > c);
foo (1 > (2 > c));
foo (1 > 2 > 3); // { dg-warning "comparison" "correct warning" }
foo ((1 > 2) > 3);
foo (1 > (2 > 3));
foo (a < b <= c); // { dg-warning "comparison" "correct warning" }
foo ((a < b) <= c);
foo (a < (b <= c));
foo (1 < 2 <= c); // { dg-warning "comparison" "correct warning" }
foo ((1 < 2) <= c);
foo (1 < (2 <= c));
foo (1 < 2 <= 3); // { dg-warning "comparison" "correct warning" }
foo ((1 < 2) <= 3);
foo (1 < (2 <= 3));
foo (a <= b > c); // { dg-warning "comparison" "correct warning" }
foo ((a <= b) > c);
foo (a <= (b > c));
foo (1 <= 2 > c); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) > c);
foo (1 <= (2 > c));
foo (1 <= 2 > 3); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) > 3);
foo (1 <= (2 > 3));
foo (a <= b == c); // { dg-warning "comparison" "correct warning" }
foo ((a <= b) == c);
foo (a <= (b == c));
foo (1 <= 2 == c); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) == c);
foo (1 <= (2 == c));
foo (1 <= 2 == 3); // { dg-warning "comparison" "correct warning" }
foo ((1 <= 2) == 3);
foo (1 <= (2 == 3));
foo (a != b != c); // { dg-warning "comparison" "correct warning" }
foo ((a != b) != c);
foo (a != (b != c));
foo (1 != 2 != c); // { dg-warning "comparison" "correct warning" }
foo ((1 != 2) != c);
foo (1 != (2 != c));
foo (1 != 2 != 3); // { dg-warning "comparison" "correct warning" }
foo ((1 != 2) != 3);
foo (1 != (2 != 3));
}

View File

@ -0,0 +1,83 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// C++ copy of gcc.dg/Wparentheses-4.c
int foo (int);
int
bar (int a, int b, int c)
{
foo (a + b << c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) << c);
foo (a + (b << c));
foo (1 + 2 << c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) << c);
foo (1 + (2 << c));
foo (1 + 2 << 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) << 3);
foo (1 + (2 << 3));
foo (a << b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a << b) + c);
foo (a << (b + c));
foo (1 << 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 << 2) + c);
foo (1 << (2 + c));
foo (1 << 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 << 2) + 3);
foo (1 << (2 + 3));
foo (a + b >> c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) >> c);
foo (a + (b >> c));
foo (1 + 2 >> c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) >> c);
foo (1 + (2 >> c));
foo (1 + 2 >> 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) >> 3);
foo (1 + (2 >> 3));
foo (a >> b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a >> b) + c);
foo (a >> (b + c));
foo (1 >> 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 >> 2) + c);
foo (1 >> (2 + c));
foo (1 >> 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 >> 2) + 3);
foo (1 >> (2 + 3));
foo (a - b << c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) << c);
foo (a - (b << c));
foo (6 - 5 << c); // { dg-warning "parentheses" "correct warning" }
foo ((6 - 5) << c);
foo (6 - (5 << c));
foo (6 - 5 << 4); // { dg-warning "parentheses" "correct warning" }
foo ((6 - 5) << 4);
foo (6 - (5 << 4));
foo (a << b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a << b) - c);
foo (a << (b - c));
foo (6 << 5 - c); // { dg-warning "parentheses" "correct warning" }
foo ((6 << 5) - c);
foo (6 << (5 - c));
foo (6 << 5 - 4); // { dg-warning "parentheses" "correct warning" }
foo ((6 << 5) - 4);
foo (6 << (5 - 4));
foo (a - b >> c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) >> c);
foo (a - (b >> c));
foo (6 - 5 >> c); // { dg-warning "parentheses" "correct warning" }
foo ((6 - 5) >> c);
foo (6 - (5 >> c));
foo (6 - 5 >> 4); // { dg-warning "parentheses" "correct warning" }
foo ((6 - 5) >> 4);
foo (6 - (5 >> 4));
foo (a >> b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a >> b) - c);
foo (a >> (b - c));
foo (6 >> 5 - c); // { dg-warning "parentheses" "correct warning" }
foo ((6 >> 5) - c);
foo (6 >> (5 - c));
foo (6 >> 5 - 4); // { dg-warning "parentheses" "correct warning" }
foo ((6 >> 5) - 4);
foo (6 >> (5 - 4));
}

View File

@ -0,0 +1,29 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// C++ version of gcc.dg/Wparentheses-5.c
int foo (int);
int
bar (int a, int b, int c)
{
foo (a && b || c); // { dg-warning "parentheses" "correct warning" }
foo ((a && b) || c);
foo (a && (b || c));
foo (1 && 2 || c); // { dg-warning "parentheses" "correct warning" }
foo ((1 && 2) || c);
foo (1 && (2 || c));
foo (1 && 2 || 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 && 2) || 3);
foo (1 && (2 || 3));
foo (a || b && c); // { dg-warning "parentheses" "correct warning" }
foo ((a || b) && c);
foo (a || (b && c));
foo (1 || 2 && c); // { dg-warning "parentheses" "correct warning" }
foo ((1 || 2) && c);
foo (1 || (2 && c));
foo (1 || 2 && 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 || 2) && 3);
foo (1 || (2 && 3));
}

View File

@ -0,0 +1,119 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// C++ version of gcc.dg/Wparentheses-6.c
int foo (int);
int
bar (int a, int b, int c)
{
foo (a & b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a & b) | c);
foo (a & (b | c));
foo (1 & 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) | c);
foo (1 & (2 | c));
foo (1 & 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 & 2) | 3);
foo (1 & (2 | 3));
foo (a | b & c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) & c);
foo (a | (b & c));
foo (1 | 2 & c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) & c);
foo (1 | (2 & c));
foo (1 | 2 & 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) & 3);
foo (1 | (2 & 3));
foo (a ^ b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a ^ b) | c);
foo (a ^ (b | c));
foo (1 ^ 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) | c);
foo (1 ^ (2 | c));
foo (1 ^ 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 ^ 2) | 3);
foo (1 ^ (2 | 3));
foo (a | b ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) ^ c);
foo (a | (b ^ c));
foo (1 | 2 ^ c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) ^ c);
foo (1 | (2 ^ c));
foo (1 | 2 ^ 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) ^ 3);
foo (1 | (2 ^ 3));
foo (a + b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a + b) | c);
foo (a + (b | c));
foo (1 + 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) | c);
foo (1 + (2 | c));
foo (1 + 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 + 2) | 3);
foo (1 + (2 | 3));
foo (a | b + c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) + c);
foo (a | (b + c));
foo (1 | 2 + c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) + c);
foo (1 | (2 + c));
foo (1 | 2 + 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) + 3);
foo (1 | (2 + 3));
foo (a - b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a - b) | c);
foo (a - (b | c));
foo (1 - 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) | c);
foo (1 - (2 | c));
foo (1 - 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 - 2) | 3);
foo (1 - (2 | 3));
foo (a | b - c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) - c);
foo (a | (b - c));
foo (1 | 2 - c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) - c);
foo (1 | (2 - c));
foo (1 | 2 - 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) - 3);
foo (1 | (2 - 3));
foo (a > b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a > b) | c);
foo (a > (b | c));
foo (1 > 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 > 2) | c);
foo (1 > (2 | c));
foo (1 > 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 > 2) | 3);
foo (1 > (2 | 3));
foo (a | b > c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) > c);
foo (a | (b > c));
foo (1 | 2 > c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) > c);
foo (1 | (2 > c));
foo (1 | 2 > 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) > 3);
foo (1 | (2 > 3));
foo (a <= b | c); // { dg-warning "parentheses" "correct warning" }
foo ((a <= b) | c);
foo (a <= (b | c));
foo (1 <= 2 | c); // { dg-warning "parentheses" "correct warning" }
foo ((1 <= 2) | c);
foo (1 <= (2 | c));
foo (1 <= 2 | 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 <= 2) | 3);
foo (1 <= (2 | 3));
foo (a | b <= c); // { dg-warning "parentheses" "correct warning" }
foo ((a | b) <= c);
foo (a | (b <= c));
foo (1 | 2 <= c); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) <= c);
foo (1 | (2 <= c));
foo (1 | 2 <= 3); // { dg-warning "parentheses" "correct warning" }
foo ((1 | 2) <= 3);
foo (1 | (2 <= 3));
}

View File

@ -1,3 +1,25 @@
2006-12-13 Ian Lance Taylor <iant@google.com>
PR c++/19564
PR c++/19756
* include/bits/locale_facets.tcc (num_get<>::_M_extract_float):
Add parentheses around && within || to avoid warning.
(num_get<>::_M_extract_int): Likewise.
(money_get<>::_M_extract): Likewise.
(num_get<>::do_get(iter_type, iter_type, ios_base&,
ios_base::iostate&, void*&)): Add parentheses around & within | to
avoid warning.
(num_put<>::do_put(iter_type, ios_base&, char_type, const void*)):
Likewise.
* include/bits/streambuf_iterator.h (istreambuf_iterator::equal):
Add parentheses around && within || to avoid warning.
* libsupc++/tinfo.cc (__do_dyncast): Likewise.
* src/locale.cc (locale::_S_normalize_category): Likewise.
* include/bits/stl_tree.h (_Rb_tree<>::_M_insert_unique): Add
braces to avoid ambiguous else warning.
* src/strstream.cc (strstreambuf::_M_free): Likewise.
* src/tree.cc (_Rb_tree_rebalance_for_erase): Likewise.
2006-12-12 Benjamin Kosnik <bkoz@redhat.com> 2006-12-12 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/28265 PR libstdc++/28265

View File

@ -314,7 +314,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
int __sep_pos = 0; int __sep_pos = 0;
while (!__testeof) while (!__testeof)
{ {
if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
|| __c == __lc->_M_decimal_point) || __c == __lc->_M_decimal_point)
break; break;
else if (__c == __lit[__num_base::_S_izero]) else if (__c == __lit[__num_base::_S_izero])
@ -556,7 +556,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
int __sep_pos = 0; int __sep_pos = 0;
while (!__testeof) while (!__testeof)
{ {
if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
|| __c == __lc->_M_decimal_point) || __c == __lc->_M_decimal_point)
break; break;
else if (__c == __lit[__num_base::_S_izero] else if (__c == __lit[__num_base::_S_izero]
@ -883,7 +883,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
// Prepare for hex formatted input. // Prepare for hex formatted input.
typedef ios_base::fmtflags fmtflags; typedef ios_base::fmtflags fmtflags;
const fmtflags __fmt = __io.flags(); const fmtflags __fmt = __io.flags();
__io.flags(__fmt & ~ios_base::basefield | ios_base::hex); __io.flags((__fmt & ~ios_base::basefield) | ios_base::hex);
unsigned long __ul; unsigned long __ul;
__beg = _M_extract_int(__beg, __end, __io, __err, __ul); __beg = _M_extract_int(__beg, __end, __io, __err, __ul);
@ -1305,7 +1305,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
const ios_base::fmtflags __fmt = ~(ios_base::basefield const ios_base::fmtflags __fmt = ~(ios_base::basefield
| ios_base::uppercase | ios_base::uppercase
| ios_base::internal); | ios_base::internal);
__io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); __io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase));
__s = _M_insert_int(__s, __io, __fill, __s = _M_insert_int(__s, __io, __fill,
reinterpret_cast<unsigned long>(__v)); reinterpret_cast<unsigned long>(__v));
@ -1377,9 +1377,9 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
== money_base::space))) == money_base::space)))
|| (__i == 2 && ((static_cast<part>(__p.field[3]) || (__i == 2 && ((static_cast<part>(__p.field[3])
== money_base::value) == money_base::value)
|| __mandatory_sign || (__mandatory_sign
&& (static_cast<part>(__p.field[3]) && (static_cast<part>(__p.field[3])
== money_base::sign)))) == money_base::sign)))))
{ {
const size_type __len = __lc->_M_curr_symbol_size; const size_type __len = __lc->_M_curr_symbol_size;
size_type __j = 0; size_type __j = 0;

View File

@ -1055,10 +1055,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
} }
iterator __j = iterator(__y); iterator __j = iterator(__y);
if (__comp) if (__comp)
if (__j == begin()) {
return pair<iterator, bool>(_M_insert_(__x, __y, __v), true); if (__j == begin())
else return pair<iterator, bool>(_M_insert_(__x, __y, __v), true);
--__j; else
--__j;
}
if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))
return pair<iterator, bool>(_M_insert_(__x, __y, __v), true); return pair<iterator, bool>(_M_insert_(__x, __y, __v), true);
return pair<iterator, bool>(__j, false); return pair<iterator, bool>(__j, false);

View File

@ -160,7 +160,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{ {
const bool __thiseof = _M_at_eof(); const bool __thiseof = _M_at_eof();
const bool __beof = __b._M_at_eof(); const bool __beof = __b._M_at_eof();
return (__thiseof && __beof || (!__thiseof && !__beof)); return ((__thiseof && __beof) || (!__thiseof && !__beof));
} }
private: private:

View File

@ -490,9 +490,9 @@ __do_dyncast (ptrdiff_t src2dst,
result.whole2dst = result.whole2dst =
__sub_kind (result.whole2dst | result2.whole2dst); __sub_kind (result.whole2dst | result2.whole2dst);
} }
else if ((result.dst_ptr != 0 & result2.dst_ptr != 0) else if ((result.dst_ptr != 0 && result2.dst_ptr != 0)
|| (result.dst_ptr != 0 & result2_ambig) || (result.dst_ptr != 0 && result2_ambig)
|| (result2.dst_ptr != 0 & result_ambig)) || (result2.dst_ptr != 0 && result_ambig))
{ {
// Found two different DST_TYPE bases, or a valid one and a set of // Found two different DST_TYPE bases, or a valid one and a set of
// ambiguous ones, must disambiguate. See whether SRC_PTR is // ambiguous ones, must disambiguate. See whether SRC_PTR is

View File

@ -146,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
locale::_S_normalize_category(category __cat) locale::_S_normalize_category(category __cat)
{ {
int __ret = 0; int __ret = 0;
if (__cat == none || (__cat & all) && !(__cat & ~all)) if (__cat == none || ((__cat & all) && !(__cat & ~all)))
__ret = __cat; __ret = __cat;
else else
{ {

View File

@ -311,10 +311,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
strstreambuf::_M_free(char* p) strstreambuf::_M_free(char* p)
{ {
if (p) if (p)
if (_M_free_fun) {
_M_free_fun(p); if (_M_free_fun)
else _M_free_fun(p);
delete[] p; else
delete[] p;
}
} }
void void

View File

@ -316,17 +316,21 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
else else
__z->_M_parent->_M_right = __x; __z->_M_parent->_M_right = __x;
if (__leftmost == __z) if (__leftmost == __z)
if (__z->_M_right == 0) // __z->_M_left must be null also {
__leftmost = __z->_M_parent; if (__z->_M_right == 0) // __z->_M_left must be null also
// makes __leftmost == _M_header if __z == __root __leftmost = __z->_M_parent;
else // makes __leftmost == _M_header if __z == __root
__leftmost = _Rb_tree_node_base::_S_minimum(__x); else
__leftmost = _Rb_tree_node_base::_S_minimum(__x);
}
if (__rightmost == __z) if (__rightmost == __z)
if (__z->_M_left == 0) // __z->_M_right must be null also {
__rightmost = __z->_M_parent; if (__z->_M_left == 0) // __z->_M_right must be null also
// makes __rightmost == _M_header if __z == __root __rightmost = __z->_M_parent;
else // __x == __z->_M_left // makes __rightmost == _M_header if __z == __root
__rightmost = _Rb_tree_node_base::_S_maximum(__x); else // __x == __z->_M_left
__rightmost = _Rb_tree_node_base::_S_maximum(__x);
}
} }
if (__y->_M_color != _S_red) if (__y->_M_color != _S_red)
{ {