]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-common.c (c_common_truthvalue_conversion): Generalise warning for addresses convert...
authorBen Elliston <bje@au.ibm.com>
Tue, 13 Dec 2005 23:33:26 +0000 (23:33 +0000)
committerBen Elliston <bje@gcc.gnu.org>
Tue, 13 Dec 2005 23:33:26 +0000 (10:33 +1100)
* 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

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 bc139b27691ec27bcccae6ddf831e85fbe32bc05..417d69f8be2a42ca39b46f9c8b1e342c766d925d 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 557cd554a8fa83ebaae8c8afc104262f17512498..5f97a9759339d644e441dc1fa6d23ed4dcc367d6 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 86f224407be025a0b02a28527cc8566918c1c1b8..9968c9b187b00ca4a198c30cccbdb89ad3c1a4b8 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 36c9bc0702c811c8741381a293c7ec55551e2f75..a38ce6c5ca92c2d8d2f38dc1e30bfe78273ed7d1 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 e49838ae5f0e77bcb7fe870a65957893246a9da9..495042b3f3ae4590c2924bcddda7fc8117e39679 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 d51aef0346966a76bab1981c53d9c61c3b3b92ca..67a674972399b8a04d894389b4b3b4284fb1d558 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 9d5c287fe808d20c3e205af1aa31169283ba082d..aaf07473c87361e072e3819993c491a845c764dd 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;
+}