c-common.c (c_common_truthvalue_conversion): Generalise warning for addresses converted to booleans; not just function addresses.

* c-common.c (c_common_truthvalue_conversion): Generalise warning
	for addresses converted to booleans; not just function addresses.
	* c-typeck.c (build_binary_op): Warn for address comparisons which
	can never be NULL (eg. func == NULL or &var == NULL).
	* common.opt (Walways-true): New option.
	* c-opts.c (c_common_handle_option): Set it with -Wall.
	* doc/invoke.texi: Document it.
testsuite/
	* gcc.dg/warn-addr-cmp.c: New test.

From-SVN: r108489
This commit is contained in:
Ben Elliston 2005-12-13 23:33:26 +00:00 committed by Ben Elliston
parent 383eca9cce
commit 690a704a4e
8 changed files with 122 additions and 5 deletions

View File

@ -1,3 +1,13 @@
2005-12-14 Ben Elliston <bje@au.ibm.com>
* c-common.c (c_common_truthvalue_conversion): Generalise warning
for addresses converted to booleans; not just function addresses.
* c-typeck.c (build_binary_op): Warn for address comparisons which
can never be NULL (eg. func == NULL or &var == NULL).
* common.opt (Walways-true): New option.
* c-opts.c (c_common_handle_option): Set it with -Wall.
* doc/invoke.texi: Document it.
2005-12-13 Paul Brook <paul@codesourcery.com>
* config/m68k/fpgnulib.c (__unordsf2, __unorddf2, __unordxf2,

View File

@ -2407,12 +2407,12 @@ c_common_truthvalue_conversion (tree expr)
case ADDR_EXPR:
{
if (TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL
if (DECL_P (TREE_OPERAND (expr, 0))
&& !DECL_WEAK (TREE_OPERAND (expr, 0)))
{
/* Common Ada/Pascal programmer's mistake. We always warn
about this since it is so bad. */
warning (0, "the address of %qD, will always evaluate as %<true%>",
warning (OPT_Walways_true, "the address of %qD, will always evaluate as %<true%>",
TREE_OPERAND (expr, 0));
return truthvalue_true_node;
}

View File

@ -387,6 +387,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
warn_switch = value;
warn_strict_aliasing = value;
warn_string_literal_comparison = value;
warn_always_true = value;
/* Only warn about unknown pragmas that are not in system
headers. */

View File

@ -7939,9 +7939,23 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
result_type = ptr_type_node;
}
else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
result_type = type0;
{
if (TREE_CODE (op0) == ADDR_EXPR
&& DECL_P (TREE_OPERAND (op0, 0))
&& !DECL_WEAK (TREE_OPERAND (op0, 0)))
warning (OPT_Walways_true, "the address of %qD will never be NULL",
TREE_OPERAND (op0, 0));
result_type = type0;
}
else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
result_type = type1;
{
if (TREE_CODE (op1) == ADDR_EXPR
&& DECL_P (TREE_OPERAND (op1, 0))
&& !DECL_WEAK (TREE_OPERAND (op1, 0)))
warning (OPT_Walways_true, "the address of %qD will never be NULL",
TREE_OPERAND (op1, 0));
result_type = type1;
}
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;

View File

@ -57,6 +57,10 @@ Waggregate-return
Common Var(warn_aggregate_return)
Warn about returning structures, unions or arrays
Walways-true
Common Var(warn_always_true)
Warn about comparisons that always evaluate to true
Wattributes
Common Var(warn_attributes) Init(1)
Warn about inappropriate attribute usage

View File

@ -222,7 +222,7 @@ Objective-C and Objective-C++ Dialects}.
@item Warning Options
@xref{Warning Options,,Options to Request or Suppress Warnings}.
@gccoptlist{-fsyntax-only -pedantic -pedantic-errors @gol
-w -Wextra -Wall -Waggregate-return -Wno-attributes @gol
-w -Wextra -Wall -Waggregate-return -Walways-true -Wno-attributes @gol
-Wc++-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment @gol
-Wconversion -Wno-deprecated-declarations @gol
-Wdisabled-optimization -Wno-div-by-zero -Wno-endif-labels @gol
@ -3112,6 +3112,11 @@ Warn if any functions that return structures or unions are defined or
called. (In languages where you can return an array, this also elicits
a warning.)
@item -Walways-true
@opindex Walways-true
Warn about comparisons which are always true such as testing if unsigned
values are greater than zero.
@item -Wno-attributes
@opindex Wno-attributes
@opindex Wattributes

View File

@ -1,3 +1,7 @@
2005-12-14 Ben Elliston <bje@au.ibm.com>
* gcc.dg/warn-addr-cmp.c: New test.
2005-12-13 Jakub Jelinek <jakub@redhat.com>
PR debug/25023

View File

@ -0,0 +1,79 @@
/* { dg-do compile } */
/* { dg-require-weak "" } */
/* { dg-options "-Walways-true" } */
/* Warning when addr convert to bool always gives known result.
Ada/Pascal programmers sometimes write 0-param functions without
(), and might as well warn on variables, too. */
int func (void);
extern int var;
int weak_func (void) __attribute__ ((weak));
extern int weak_var __attribute__ ((weak));
int
test_func_cmp (void)
{
if (func) /* { dg-warning "the address of 'func'" } */
return 1;
if (!func) /* { dg-warning "the address of 'func'" } */
return 1;
if (&var) /* { dg-warning "the address of 'var'" } */
return 1;
if (!&var) /* { dg-warning "the address of 'var'" } */
return 1;
if (weak_func)
return 1;
if (!weak_func)
return 1;
if (&weak_var)
return 1;
if (!&weak_var)
return 1;
return 0;
}
/* Test equality with 0 on the right hand side. */
int
test_func_cmp_rhs_zero (void)
{
if (func == 0) /* { dg-warning "the address of 'func'" } */
return 1;
if (func != 0) /* { dg-warning "the address of 'func'" } */
return 1;
if (&var == 0) /* { dg-warning "the address of 'var'" } */
return 1;
if (&var != 0) /* { dg-warning "the address of 'var'" } */
return 1;
if (weak_func == 0)
return 1;
if (weak_func != 0)
return 1;
if (&weak_var == 0)
return 1;
if (&weak_var != 0)
return 1;
return 0;
}
/* Test equality with 0 on the left hand side. */
int
test_func_cmp_lhs_zero (void)
{
if (0 == func) /* { dg-warning "the address of 'func'" } */
return 1;
if (0 != func) /* { dg-warning "the address of 'func'" } */
return 1;
if (0 == &var) /* { dg-warning "the address of 'var'" } */
return 1;
if (0 != &var) /* { dg-warning "the address of 'var'" } */
return 1;
if (0 == weak_func)
return 1;
if (0 != weak_func)
return 1;
if (0 == &weak_var)
return 1;
if (0 != &weak_var)
return 1;
return 0;
}