* c-common.c (c_common_truthvalue_conversion): Generalise warning
authorbje <bje@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Dec 2005 23:33:26 +0000 (23:33 +0000)
committerbje <bje@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Dec 2005 23:33:26 +0000 (23:33 +0000)
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

gcc/ChangeLog
gcc/c-common.c
gcc/c-opts.c
gcc/c-typeck.c
gcc/common.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/warn-addr-cmp.c [new file with mode: 0644]

index bc139b2..417d69f 100644 (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,
index 557cd55..5f97a97 100644 (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;
          }
index 86f2244..9968c9b 100644 (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.  */
index 36c9bc0..a38ce6c 100644 (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;
index e49838a..495042b 100644 (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
index d51aef0..67a6749 100644 (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
index 9d5c287..aaf0747 100644 (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
diff --git a/gcc/testsuite/gcc.dg/warn-addr-cmp.c b/gcc/testsuite/gcc.dg/warn-addr-cmp.c
new file mode 100644 (file)
index 0000000..d8c9a21
--- /dev/null
@@ -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;
+}