re PR c++/54194 (misleading suggestion about arithmetic in operand of '|')
2012-10-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/54194 * tree.h: Add EXPR_LOC_OR_LOC. c-family/ 2012-10-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/54194 * c-common.c (warn_about_parentheses): Add location_t parameter; use EXPR_LOC_OR_LOC. * c-common.h: Update declaration. c/ 2012-10-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/54194 * c-typeck.c (parser_build_binary_op): Update warn_about_parentheses call. /cp 2012-10-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/54194 * typeck.c (build_x_binary_op): Update warn_about_parentheses call. * parser.c (cp_parser_binary_expression): Use SET_EXPR_LOCATION on current.lhs. /testsuite 2012-10-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/54194 * g++.dg/warn/Wparentheses-26.C: Adjust. * g++.dg/warn/Wparentheses-27.C: New. From-SVN: r192246
This commit is contained in:
parent
3b86789289
commit
5d9de0d0a5
13 changed files with 155 additions and 65 deletions
|
@ -1,3 +1,8 @@
|
|||
2012-10-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/54194
|
||||
* tree.h: Add EXPR_LOC_OR_LOC.
|
||||
|
||||
2012-10-09 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR rtl-optimization/54739
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2012-10-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/54194
|
||||
* c-common.c (warn_about_parentheses): Add location_t parameter;
|
||||
use EXPR_LOC_OR_LOC.
|
||||
* c-common.h: Update declaration.
|
||||
|
||||
2012-10-09 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/54427
|
||||
|
|
|
@ -10527,7 +10527,7 @@ warn_array_subscript_with_type_char (tree index)
|
|||
was enclosed in parentheses. */
|
||||
|
||||
void
|
||||
warn_about_parentheses (enum tree_code code,
|
||||
warn_about_parentheses (location_t loc, enum tree_code code,
|
||||
enum tree_code code_left, tree arg_left,
|
||||
enum tree_code code_right, tree arg_right)
|
||||
{
|
||||
|
@ -10547,104 +10547,147 @@ warn_about_parentheses (enum tree_code code,
|
|||
switch (code)
|
||||
{
|
||||
case LSHIFT_EXPR:
|
||||
if (code_left == PLUS_EXPR || code_right == PLUS_EXPR)
|
||||
warning (OPT_Wparentheses,
|
||||
"suggest parentheses around %<+%> inside %<<<%>");
|
||||
else if (code_left == MINUS_EXPR || code_right == MINUS_EXPR)
|
||||
warning (OPT_Wparentheses,
|
||||
"suggest parentheses around %<-%> inside %<<<%>");
|
||||
if (code_left == PLUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<+%> inside %<<<%>");
|
||||
else if (code_right == PLUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<+%> inside %<<<%>");
|
||||
else if (code_left == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<-%> inside %<<<%>");
|
||||
else if (code_right == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<-%> inside %<<<%>");
|
||||
return;
|
||||
|
||||
case RSHIFT_EXPR:
|
||||
if (code_left == PLUS_EXPR || code_right == PLUS_EXPR)
|
||||
warning (OPT_Wparentheses,
|
||||
"suggest parentheses around %<+%> inside %<>>%>");
|
||||
else if (code_left == MINUS_EXPR || code_right == MINUS_EXPR)
|
||||
warning (OPT_Wparentheses,
|
||||
"suggest parentheses around %<-%> inside %<>>%>");
|
||||
if (code_left == PLUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<+%> inside %<>>%>");
|
||||
else if (code_right == PLUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<+%> inside %<>>%>");
|
||||
else if (code_left == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<-%> inside %<>>%>");
|
||||
else if (code_right == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<-%> inside %<>>%>");
|
||||
return;
|
||||
|
||||
case TRUTH_ORIF_EXPR:
|
||||
if (code_left == TRUTH_ANDIF_EXPR || code_right == TRUTH_ANDIF_EXPR)
|
||||
warning (OPT_Wparentheses,
|
||||
"suggest parentheses around %<&&%> within %<||%>");
|
||||
if (code_left == TRUTH_ANDIF_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<&&%> within %<||%>");
|
||||
else if (code_right == TRUTH_ANDIF_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<&&%> within %<||%>");
|
||||
return;
|
||||
|
||||
case 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,
|
||||
|| code_left == PLUS_EXPR || code_left == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around arithmetic in operand of %<|%>");
|
||||
else if (code_right == BIT_AND_EXPR || code_right == BIT_XOR_EXPR
|
||||
|| code_right == PLUS_EXPR || code_right == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around arithmetic in operand of %<|%>");
|
||||
/* Check cases like x|y==z */
|
||||
else if (TREE_CODE_CLASS (code_left) == tcc_comparison
|
||||
|| TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning (OPT_Wparentheses,
|
||||
else if (TREE_CODE_CLASS (code_left) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<|%>");
|
||||
else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<|%>");
|
||||
/* Check cases like !x | y */
|
||||
else if (code_left == TRUTH_NOT_EXPR
|
||||
&& !APPEARS_TO_BE_BOOLEAN_EXPR_P (code_right, arg_right))
|
||||
warning (OPT_Wparentheses, "suggest parentheses around operand of "
|
||||
"%<!%> or change %<|%> to %<||%> or %<!%> to %<~%>");
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around operand of "
|
||||
"%<!%> or change %<|%> to %<||%> or %<!%> to %<~%>");
|
||||
return;
|
||||
|
||||
case 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,
|
||||
|| code_left == PLUS_EXPR || code_left == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around arithmetic in operand of %<^%>");
|
||||
else if (code_right == BIT_AND_EXPR
|
||||
|| code_right == PLUS_EXPR || code_right == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around arithmetic in operand of %<^%>");
|
||||
/* Check cases like x^y==z */
|
||||
else if (TREE_CODE_CLASS (code_left) == tcc_comparison
|
||||
|| TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning (OPT_Wparentheses,
|
||||
else if (TREE_CODE_CLASS (code_left) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<^%>");
|
||||
else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<^%>");
|
||||
return;
|
||||
|
||||
case BIT_AND_EXPR:
|
||||
if (code_left == PLUS_EXPR || code_right == PLUS_EXPR)
|
||||
warning (OPT_Wparentheses,
|
||||
if (code_left == PLUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<+%> in operand of %<&%>");
|
||||
else if (code_left == MINUS_EXPR || code_right == MINUS_EXPR)
|
||||
warning (OPT_Wparentheses,
|
||||
else if (code_right == PLUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<+%> in operand of %<&%>");
|
||||
else if (code_left == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<-%> in operand of %<&%>");
|
||||
else if (code_right == MINUS_EXPR)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around %<-%> in operand of %<&%>");
|
||||
/* Check cases like x&y==z */
|
||||
else if (TREE_CODE_CLASS (code_left) == tcc_comparison
|
||||
|| TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning (OPT_Wparentheses,
|
||||
else if (TREE_CODE_CLASS (code_left) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<&%>");
|
||||
else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<&%>");
|
||||
/* Check cases like !x & y */
|
||||
else if (code_left == TRUTH_NOT_EXPR
|
||||
&& !APPEARS_TO_BE_BOOLEAN_EXPR_P (code_right, arg_right))
|
||||
warning (OPT_Wparentheses, "suggest parentheses around operand of "
|
||||
"%<!%> or change %<&%> to %<&&%> or %<!%> to %<~%>");
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around operand of "
|
||||
"%<!%> or change %<&%> to %<&&%> or %<!%> to %<~%>");
|
||||
return;
|
||||
|
||||
case EQ_EXPR:
|
||||
if (TREE_CODE_CLASS (code_left) == tcc_comparison
|
||||
|| TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning (OPT_Wparentheses,
|
||||
if (TREE_CODE_CLASS (code_left) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<==%>");
|
||||
else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<==%>");
|
||||
return;
|
||||
case NE_EXPR:
|
||||
if (TREE_CODE_CLASS (code_left) == tcc_comparison
|
||||
|| TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning (OPT_Wparentheses,
|
||||
if (TREE_CODE_CLASS (code_left) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<!=%>");
|
||||
else if (TREE_CODE_CLASS (code_right) == tcc_comparison)
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"suggest parentheses around comparison in operand of %<!=%>");
|
||||
return;
|
||||
|
||||
default:
|
||||
if (TREE_CODE_CLASS (code) == tcc_comparison
|
||||
&& ((TREE_CODE_CLASS (code_left) == tcc_comparison
|
||||
if (TREE_CODE_CLASS (code) == tcc_comparison)
|
||||
{
|
||||
if (TREE_CODE_CLASS (code_left) == tcc_comparison
|
||||
&& code_left != NE_EXPR && code_left != EQ_EXPR
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (arg_left)))
|
||||
|| (TREE_CODE_CLASS (code_right) == tcc_comparison
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_left, loc), OPT_Wparentheses,
|
||||
"comparisons like %<X<=Y<=Z%> do not "
|
||||
"have their mathematical meaning");
|
||||
else if (TREE_CODE_CLASS (code_right) == tcc_comparison
|
||||
&& code_right != NE_EXPR && code_right != EQ_EXPR
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (arg_right)))))
|
||||
warning (OPT_Wparentheses, "comparisons like %<X<=Y<=Z%> do not "
|
||||
"have their mathematical meaning");
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (arg_right)))
|
||||
warning_at (EXPR_LOC_OR_LOC (arg_right, loc), OPT_Wparentheses,
|
||||
"comparisons like %<X<=Y<=Z%> do not "
|
||||
"have their mathematical meaning");
|
||||
}
|
||||
return;
|
||||
}
|
||||
#undef NOT_A_BOOLEAN_EXPR_P
|
||||
|
|
|
@ -989,7 +989,8 @@ extern tree builtin_type_for_size (int, bool);
|
|||
extern void c_common_mark_addressable_vec (tree);
|
||||
|
||||
extern void warn_array_subscript_with_type_char (tree);
|
||||
extern void warn_about_parentheses (enum tree_code,
|
||||
extern void warn_about_parentheses (location_t,
|
||||
enum tree_code,
|
||||
enum tree_code, tree,
|
||||
enum tree_code, tree);
|
||||
extern void warn_for_unused_label (tree label);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2012-10-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/54194
|
||||
* c-typeck.c (parser_build_binary_op): Update warn_about_parentheses
|
||||
call.
|
||||
|
||||
2012-10-09 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/54427
|
||||
|
|
|
@ -3254,7 +3254,8 @@ parser_build_binary_op (location_t location, enum tree_code code,
|
|||
/* Check for cases such as x+y<<z which users are likely
|
||||
to misinterpret. */
|
||||
if (warn_parentheses)
|
||||
warn_about_parentheses (code, code1, arg1.value, code2, arg2.value);
|
||||
warn_about_parentheses (input_location, code,
|
||||
code1, arg1.value, code2, arg2.value);
|
||||
|
||||
if (warn_logical_op)
|
||||
warn_logical_operator (input_location, code, TREE_TYPE (result.value),
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2012-10-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/54194
|
||||
* typeck.c (build_x_binary_op): Update warn_about_parentheses call.
|
||||
* parser.c (cp_parser_binary_expression): Use SET_EXPR_LOCATION
|
||||
on current.lhs.
|
||||
|
||||
2012-10-09 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/54427
|
||||
|
|
|
@ -7472,6 +7472,8 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
|
|||
rhs, rhs_type, &overload,
|
||||
tf_warning_or_error);
|
||||
current.lhs_type = current.tree_type;
|
||||
if (EXPR_P (current.lhs))
|
||||
SET_EXPR_LOCATION (current.lhs, current.loc);
|
||||
|
||||
/* If the binary operator required the use of an overloaded operator,
|
||||
then this expression cannot be an integral constant-expression.
|
||||
|
|
|
@ -3680,7 +3680,8 @@ build_x_binary_op (location_t loc, enum tree_code code, tree arg1,
|
|||
&& !error_operand_p (arg2)
|
||||
&& (code != LSHIFT_EXPR
|
||||
|| !CLASS_TYPE_P (TREE_TYPE (arg1))))
|
||||
warn_about_parentheses (code, arg1_code, orig_arg1, arg2_code, orig_arg2);
|
||||
warn_about_parentheses (loc, code, arg1_code, orig_arg1,
|
||||
arg2_code, orig_arg2);
|
||||
|
||||
if (processing_template_decl && expr != error_mark_node)
|
||||
return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2012-10-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/54194
|
||||
* g++.dg/warn/Wparentheses-26.C: Adjust.
|
||||
* g++.dg/warn/Wparentheses-27.C: New.
|
||||
|
||||
2012-10-09 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR c++/54427
|
||||
|
|
|
@ -4,23 +4,23 @@
|
|||
template<int i, int j = ((i + 7) >> 3)> class foo1 { };
|
||||
typedef foo1<10> bar1;
|
||||
|
||||
template<int i, int j = (i + 7 >> 3)> class foo2 { };
|
||||
typedef foo2<10> bar2; // { dg-warning "suggest parentheses around '\\+'" }
|
||||
template<int i, int j = (i + 7 >> 3)> class foo2 { }; // { dg-warning "suggest parentheses around '\\+'" }
|
||||
typedef foo2<10> bar2;
|
||||
|
||||
template<int i, int j = (100 >> (i + 2))> class foo3 { };
|
||||
typedef foo3<3> bar3;
|
||||
|
||||
template<int i, int j = (100 >> i + 2)> class foo4 { };
|
||||
typedef foo4<3> bar4; // { dg-warning "suggest parentheses around '\\+'" }
|
||||
template<int i, int j = (100 >> i + 2)> class foo4 { }; // { dg-warning "suggest parentheses around '\\+'" }
|
||||
typedef foo4<3> bar4;
|
||||
|
||||
template<int i, int j = (i + 7) | 3> class foo5 { };
|
||||
typedef foo5<10> bar5;
|
||||
|
||||
template<int i, int j = i + 7 | 3> class foo6 { };
|
||||
typedef foo6<10> bar6; // { dg-warning "suggest parentheses around arithmetic" }
|
||||
template<int i, int j = i + 7 | 3> class foo6 { }; // { dg-warning "suggest parentheses around arithmetic" }
|
||||
typedef foo6<10> bar6;
|
||||
|
||||
template<int i, int j = 3 | (i + 7)> class foo7 { };
|
||||
typedef foo7<10> bar7;
|
||||
|
||||
template<int i, int j = 3 | i + 7> class foo8 { };
|
||||
typedef foo8<10> bar8; // { dg-warning "suggest parentheses around arithmetic" }
|
||||
template<int i, int j = 3 | i + 7> class foo8 { }; // { dg-warning "suggest parentheses around arithmetic" }
|
||||
typedef foo8<10> bar8;
|
||||
|
|
8
gcc/testsuite/g++.dg/warn/Wparentheses-27.C
Normal file
8
gcc/testsuite/g++.dg/warn/Wparentheses-27.C
Normal file
|
@ -0,0 +1,8 @@
|
|||
// PR c++/54194
|
||||
// { dg-options "-Wparentheses" }
|
||||
|
||||
int main()
|
||||
{
|
||||
char in[4] = { 0 };
|
||||
in[1] = in[1] & 0x0F | ((in[3] & 0x3C) << 2); // { dg-warning "17:suggest parentheses" }
|
||||
}
|
|
@ -1619,7 +1619,10 @@ struct GTY(()) tree_constructor {
|
|||
!= UNKNOWN_LOCATION)
|
||||
/* The location to be used in a diagnostic about this expression. Do not
|
||||
use this macro if the location will be assigned to other expressions. */
|
||||
#define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ? (NODE)->exp.locus : input_location)
|
||||
#define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) \
|
||||
? (NODE)->exp.locus : input_location)
|
||||
#define EXPR_LOC_OR_LOC(NODE, LOCUS) (EXPR_HAS_LOCATION (NODE) \
|
||||
? (NODE)->exp.locus : (LOCUS))
|
||||
#define EXPR_FILENAME(NODE) LOCATION_FILE (EXPR_CHECK ((NODE))->exp.locus)
|
||||
#define EXPR_LINENO(NODE) LOCATION_LINE (EXPR_CHECK (NODE)->exp.locus)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue