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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108489
138bc75d-0d04-0410-961f-
82ee72b054a4
+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,
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;
}
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. */
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;
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
@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
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
+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
--- /dev/null
+/* { 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;
+}