From: ian Date: Thu, 14 Dec 2006 05:49:06 +0000 (+0000) Subject: PR c++/19564 X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=e534436e6eabb2900b763cceebab8dcdd2f05fcb 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119855 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7b85b7e72c..83c65d1df16 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2006-12-13 Ian Lance Taylor + + 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 * tree-ssa-loop-ivopts.c: Include tree-affine.h. diff --git a/gcc/c-common.c b/gcc/c-common.c index d2c39bd1077..4771a53ff24 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -6606,5 +6606,87 @@ warn_array_subscript_with_type_char (tree index) warning (OPT_Wchar_subscripts, "array subscript has type %"); } +/* 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" diff --git a/gcc/c-common.h b/gcc/c-common.h index 03cf40081b0..b2b10bd2d7b 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -859,6 +859,9 @@ extern int complete_array_type (tree *, tree, bool); extern tree builtin_type_for_size (int, bool); 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 */ extern void c_genericize (tree); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index ec145334afa..08f7d4a3a79 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -2629,73 +2629,7 @@ parser_build_binary_op (enum tree_code code, struct c_expr arg1, /* Check for cases such as x+y< + + 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 * decl.c (build_enumerator): Update error message to match C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e59586bde77..3f63b8fc8d9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4458,8 +4458,9 @@ extern tree build_x_indirect_ref (tree, const char *); extern tree build_indirect_ref (tree, const char *); extern tree build_array_ref (tree, tree); extern tree get_member_function_from_ptrfunc (tree *, tree); -extern tree build_x_binary_op (enum tree_code, tree, tree, - bool *); +extern tree build_x_binary_op (enum tree_code, tree, + enum tree_code, tree, + enum tree_code, bool *); extern tree build_x_unary_op (enum tree_code, tree); extern tree unary_complex_lvalue (enum tree_code, tree); extern tree build_x_conditional_expr (tree, tree, tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 98bc2e07d28..0521136249b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1158,8 +1158,15 @@ typedef enum cp_parser_status_kind typedef struct cp_parser_expression_stack_entry { + /* Left hand side of the binary operation we are currently + parsing. */ 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; + /* Precedence of the binary operation we are parsing. */ int prec; } cp_parser_expression_stack_entry; @@ -1517,7 +1524,7 @@ static tree cp_parser_builtin_offsetof /* Statements [gram.stmt.stmt] */ static void cp_parser_statement - (cp_parser *, tree, bool); + (cp_parser *, tree, bool, bool *); static void cp_parser_label_for_labeled_statement (cp_parser *); static tree cp_parser_expression_statement @@ -1527,7 +1534,7 @@ static tree cp_parser_compound_statement static void cp_parser_statement_seq_opt (cp_parser *, tree); static tree cp_parser_selection_statement - (cp_parser *); + (cp_parser *, bool *); static tree cp_parser_condition (cp_parser *); static tree cp_parser_iteration_statement @@ -1540,7 +1547,7 @@ static void cp_parser_declaration_statement (cp_parser *); static tree cp_parser_implicitly_scoped_statement - (cp_parser *); + (cp_parser *, bool *); static void cp_parser_already_scoped_statement (cp_parser *); @@ -5685,12 +5692,13 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p) cp_parser_expression_stack_entry *sp = &stack[0]; tree lhs, rhs; 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; bool overloaded_p; /* Parse the first expression. */ lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p); + lhs_type = ERROR_MARK; 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 or the LHS of a new, higher priority expression. */ rhs = cp_parser_simple_cast_expression (parser); + rhs_type = ERROR_MARK; /* Get another operator token. Look up its precedence to avoid 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->tree_type = tree_type; sp->lhs = lhs; + sp->lhs_type = lhs_type; sp++; lhs = rhs; + lhs_type = rhs_type; prec = new_prec; new_prec = lookahead_prec; goto get_rhs; @@ -5756,11 +5767,15 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p) prec = sp->prec; tree_type = sp->tree_type; rhs = lhs; + rhs_type = lhs_type; lhs = sp->lhs; + lhs_type = sp->lhs_type; } 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, then this expression cannot be an integral constant-expression. @@ -6177,17 +6192,23 @@ cp_parser_builtin_offsetof (cp_parser *parser) try-block 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 cp_parser_statement (cp_parser* parser, tree in_statement_expr, - bool in_compound) + bool in_compound, bool *if_p) { tree statement; cp_token *token; location_t statement_location; restart: + if (if_p != NULL) + *if_p = false; /* There is no statement yet. */ statement = NULL_TREE; /* Peek at the next token. */ @@ -6212,7 +6233,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr, case RID_IF: case RID_SWITCH: - statement = cp_parser_selection_statement (parser); + statement = cp_parser_selection_statement (parser, if_p); break; case RID_WHILE: @@ -6477,7 +6498,7 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr) break; /* 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 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 -cp_parser_selection_statement (cp_parser* parser) +cp_parser_selection_statement (cp_parser* parser, bool *if_p) { cp_token *token; enum rid keyword; + if (if_p != NULL) + *if_p = false; + /* Peek at the next token. */ token = cp_parser_require (parser, CPP_KEYWORD, "selection-statement"); @@ -6531,11 +6560,13 @@ cp_parser_selection_statement (cp_parser* parser) if (keyword == RID_IF) { + bool nested_if; + /* Add the condition. */ finish_if_stmt_cond (condition, statement); /* Parse the then-clause. */ - cp_parser_implicitly_scoped_statement (parser); + cp_parser_implicitly_scoped_statement (parser, &nested_if); finish_then_clause (statement); /* 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); begin_else_clause (statement); /* Parse the else-clause. */ - cp_parser_implicitly_scoped_statement (parser); + cp_parser_implicitly_scoped_statement (parser, NULL); 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 %"), + EXPR_LOCUS (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; parser->in_switch_statement_p = true; 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_statement = in_statement; @@ -6744,7 +6795,7 @@ cp_parser_iteration_statement (cp_parser* parser) statement = begin_do_stmt (); /* Parse the body of the do-statement. */ parser->in_statement = IN_ITERATION_STMT; - cp_parser_implicitly_scoped_statement (parser); + cp_parser_implicitly_scoped_statement (parser, NULL); parser->in_statement = in_statement; finish_do_body (statement); /* 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 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. */ static tree -cp_parser_implicitly_scoped_statement (cp_parser* parser) +cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p) { tree statement; + if (if_p != NULL) + *if_p = false; + /* Mark if () ; with a special NOP_EXPR. */ 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. */ statement = begin_compound_stmt (0); /* 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_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 (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 { /* 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 (); 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); 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, though the loop as a whole is a structured block. */ body = push_stmt_list (); - cp_parser_statement (parser, NULL_TREE, false); + cp_parser_statement (parser, NULL_TREE, false, NULL); body = pop_stmt_list (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) { - cp_parser_statement (parser, NULL_TREE, false); + cp_parser_statement (parser, NULL_TREE, false, NULL); tok = cp_lexer_peek_token (parser->lexer); if (tok->pragma_kind == PRAGMA_OMP_SECTION) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2cfcce501d9..f9a728fa4b5 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9105,7 +9105,13 @@ tsubst_copy_and_build (tree t, return build_x_binary_op (TREE_CODE (t), 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)), + (TREE_NO_WARNING (TREE_OPERAND (t, 1)) + ? ERROR_MARK + : TREE_CODE (TREE_OPERAND (t, 1))), /*overloaded_p=*/NULL); case SCOPE_REF: @@ -9114,7 +9120,14 @@ tsubst_copy_and_build (tree t, case ARRAY_REF: op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), 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); case SIZEOF_EXPR: diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 1acd1ffdecf..cb09d4c987c 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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. */ 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. */ - gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 0)) - && !TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1))); + gcc_assert (!TREE_SIDE_EFFECTS (op0) + && !TREE_SIDE_EFFECTS (op1)); return build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR ? LE_EXPR : GE_EXPR), - TREE_OPERAND (t, 0), - TREE_OPERAND (t, 1), + op0, TREE_CODE (op0), + op1, TREE_CODE (op1), /*overloaded_p=*/NULL), - build_unary_op (code, TREE_OPERAND (t, 0), 0), - build_unary_op (code, TREE_OPERAND (t, 1), 0)); + build_unary_op (code, op0, 0), + build_unary_op (code, op1, 0)); } return @@ -2865,11 +2868,19 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags) } /* 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 -build_x_binary_op (enum tree_code code, tree arg1, tree arg2, - bool *overloaded_p) +build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code, + tree arg2, enum tree_code arg2_code, bool *overloaded_p) { tree orig_arg1; 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, overloaded_p); + /* Check for cases such as x+y< + + 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 PR testsuite/30157 diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-10.C b/gcc/testsuite/g++.dg/warn/Wparentheses-10.C new file mode 100644 index 00000000000..c30df090f5e --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-10.C @@ -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)); +} diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-11.C b/gcc/testsuite/g++.dg/warn/Wparentheses-11.C new file mode 100644 index 00000000000..912c3b7ae76 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-11.C @@ -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)); +} diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-12.C b/gcc/testsuite/g++.dg/warn/Wparentheses-12.C new file mode 100644 index 00000000000..b04529827d5 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-12.C @@ -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); + } +} diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-13.C b/gcc/testsuite/g++.dg/warn/Wparentheses-13.C new file mode 100644 index 00000000000..22525cd9d1c --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-13.C @@ -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 +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); // { dg-warning "instantiated" } diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-14.C b/gcc/testsuite/g++.dg/warn/Wparentheses-14.C new file mode 100644 index 00000000000..67bd43ec5cc --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-14.C @@ -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 +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); diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-15.C b/gcc/testsuite/g++.dg/warn/Wparentheses-15.C new file mode 100644 index 00000000000..ab156b757e0 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-15.C @@ -0,0 +1,68 @@ +// { dg-do compile } +// { dg-options "-Wparentheses" } + +// Template version of Wparentheses-6.C. + +int foo (int); + +template +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); // { dg-warning "instantiated" } diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-16.C b/gcc/testsuite/g++.dg/warn/Wparentheses-16.C new file mode 100644 index 00000000000..d8151aecdd1 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-16.C @@ -0,0 +1,86 @@ +// { dg-do compile } +// { dg-options "-Wparentheses" } + +// Template version of Wparentheses-7.C. + +int foo (int); + +template +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); // { dg-warning "instantiated" } diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-17.C b/gcc/testsuite/g++.dg/warn/Wparentheses-17.C new file mode 100644 index 00000000000..def181a12dc --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-17.C @@ -0,0 +1,32 @@ +// { dg-do compile } +// { dg-options "-Wparentheses" } + +// Template version of Wparentheses-8.C. + +int foo (int); + +template +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); // { dg-warning "instantiated" } diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-18.C b/gcc/testsuite/g++.dg/warn/Wparentheses-18.C new file mode 100644 index 00000000000..32fa1fe958f --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-18.C @@ -0,0 +1,122 @@ +// { dg-do compile } +// { dg-options "-Wparentheses" } + +// Template version of Wparentheses-9.C. + +int foo (int); + +template +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); // { dg-warning "instantiated" } diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-19.C b/gcc/testsuite/g++.dg/warn/Wparentheses-19.C new file mode 100644 index 00000000000..c7e45cf1afc --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-19.C @@ -0,0 +1,122 @@ +// { dg-do compile } +// { dg-options "-Wparentheses" } + +// Template version of Wparentheses-10.C. + +int foo (int); + +template +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); // { dg-warning "instantiated" } diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-20.C b/gcc/testsuite/g++.dg/warn/Wparentheses-20.C new file mode 100644 index 00000000000..8789d592f9a --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-20.C @@ -0,0 +1,104 @@ +// { dg-do compile } +// { dg-options "-Wparentheses" } + +// Template version of Wparentheses-11.C. + +int foo (int); + +template +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); // { dg-warning "instantiated" } diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-21.C b/gcc/testsuite/g++.dg/warn/Wparentheses-21.C new file mode 100644 index 00000000000..588b4fdb799 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-21.C @@ -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 +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); diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-5.C b/gcc/testsuite/g++.dg/warn/Wparentheses-5.C new file mode 100644 index 00000000000..2cd05aaaeeb --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-5.C @@ -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" } +} diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-6.C b/gcc/testsuite/g++.dg/warn/Wparentheses-6.C new file mode 100644 index 00000000000..9963d822e05 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-6.C @@ -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)); +} diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-7.C b/gcc/testsuite/g++.dg/warn/Wparentheses-7.C new file mode 100644 index 00000000000..7d549c38c31 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-7.C @@ -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)); +} diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-8.C b/gcc/testsuite/g++.dg/warn/Wparentheses-8.C new file mode 100644 index 00000000000..ddb5e64b4ad --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-8.C @@ -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)); +} diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-9.C b/gcc/testsuite/g++.dg/warn/Wparentheses-9.C new file mode 100644 index 00000000000..bad6fb1c570 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-9.C @@ -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)); +} diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index dd70b8e4020..5b692ea25d9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2006-12-13 Ian Lance Taylor + + 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 PR libstdc++/28265 diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index d3c47ff9b7f..1eba5ae0077 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -314,7 +314,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE int __sep_pos = 0; 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) break; else if (__c == __lit[__num_base::_S_izero]) @@ -556,7 +556,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE int __sep_pos = 0; 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) break; else if (__c == __lit[__num_base::_S_izero] @@ -883,7 +883,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE // Prepare for hex formatted input. typedef ios_base::fmtflags fmtflags; 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; __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 | ios_base::uppercase | 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, reinterpret_cast(__v)); @@ -1377,9 +1377,9 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE == money_base::space))) || (__i == 2 && ((static_cast(__p.field[3]) == money_base::value) - || __mandatory_sign - && (static_cast(__p.field[3]) - == money_base::sign)))) + || (__mandatory_sign + && (static_cast(__p.field[3]) + == money_base::sign))))) { const size_type __len = __lc->_M_curr_symbol_size; size_type __j = 0; diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index d2efb3aa4eb..bbfb252143d 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -1055,10 +1055,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } iterator __j = iterator(__y); if (__comp) - if (__j == begin()) - return pair(_M_insert_(__x, __y, __v), true); - else - --__j; + { + if (__j == begin()) + return pair(_M_insert_(__x, __y, __v), true); + else + --__j; + } if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) return pair(_M_insert_(__x, __y, __v), true); return pair(__j, false); diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index a1cf234a387..c743bb311ba 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -160,7 +160,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { const bool __thiseof = _M_at_eof(); const bool __beof = __b._M_at_eof(); - return (__thiseof && __beof || (!__thiseof && !__beof)); + return ((__thiseof && __beof) || (!__thiseof && !__beof)); } private: diff --git a/libstdc++-v3/libsupc++/tinfo.cc b/libstdc++-v3/libsupc++/tinfo.cc index a153c2d4d4c..89d9e164581 100644 --- a/libstdc++-v3/libsupc++/tinfo.cc +++ b/libstdc++-v3/libsupc++/tinfo.cc @@ -490,9 +490,9 @@ __do_dyncast (ptrdiff_t src2dst, result.whole2dst = __sub_kind (result.whole2dst | result2.whole2dst); } - else if ((result.dst_ptr != 0 & result2.dst_ptr != 0) - || (result.dst_ptr != 0 & result2_ambig) - || (result2.dst_ptr != 0 & result_ambig)) + else if ((result.dst_ptr != 0 && result2.dst_ptr != 0) + || (result.dst_ptr != 0 && result2_ambig) + || (result2.dst_ptr != 0 && result_ambig)) { // Found two different DST_TYPE bases, or a valid one and a set of // ambiguous ones, must disambiguate. See whether SRC_PTR is diff --git a/libstdc++-v3/src/locale.cc b/libstdc++-v3/src/locale.cc index 12070eb2eb2..a7609948a81 100644 --- a/libstdc++-v3/src/locale.cc +++ b/libstdc++-v3/src/locale.cc @@ -146,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) locale::_S_normalize_category(category __cat) { int __ret = 0; - if (__cat == none || (__cat & all) && !(__cat & ~all)) + if (__cat == none || ((__cat & all) && !(__cat & ~all))) __ret = __cat; else { diff --git a/libstdc++-v3/src/strstream.cc b/libstdc++-v3/src/strstream.cc index 5bbb33a441e..f2214549ab7 100644 --- a/libstdc++-v3/src/strstream.cc +++ b/libstdc++-v3/src/strstream.cc @@ -311,10 +311,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std) strstreambuf::_M_free(char* p) { if (p) - if (_M_free_fun) - _M_free_fun(p); - else - delete[] p; + { + if (_M_free_fun) + _M_free_fun(p); + else + delete[] p; + } } void diff --git a/libstdc++-v3/src/tree.cc b/libstdc++-v3/src/tree.cc index 38a30373364..b23ca8e8fa7 100644 --- a/libstdc++-v3/src/tree.cc +++ b/libstdc++-v3/src/tree.cc @@ -316,17 +316,21 @@ _GLIBCXX_BEGIN_NAMESPACE(std) else __z->_M_parent->_M_right = __x; if (__leftmost == __z) - if (__z->_M_right == 0) // __z->_M_left must be null also - __leftmost = __z->_M_parent; - // makes __leftmost == _M_header if __z == __root - else - __leftmost = _Rb_tree_node_base::_S_minimum(__x); + { + if (__z->_M_right == 0) // __z->_M_left must be null also + __leftmost = __z->_M_parent; + // makes __leftmost == _M_header if __z == __root + else + __leftmost = _Rb_tree_node_base::_S_minimum(__x); + } if (__rightmost == __z) - if (__z->_M_left == 0) // __z->_M_right must be null also - __rightmost = __z->_M_parent; - // makes __rightmost == _M_header if __z == __root - else // __x == __z->_M_left - __rightmost = _Rb_tree_node_base::_S_maximum(__x); + { + if (__z->_M_left == 0) // __z->_M_right must be null also + __rightmost = __z->_M_parent; + // makes __rightmost == _M_header if __z == __root + else // __x == __z->_M_left + __rightmost = _Rb_tree_node_base::_S_maximum(__x); + } } if (__y->_M_color != _S_red) {