PATCH RFA: C++ frontend warning: comparing function pointer to NULL
Ian Lance Taylor
iant@google.com
Thu Jan 4 15:23:00 GMT 2007
If you write code like this:
extern int foo();
if (foo == 0)
...
the C frontend will issue a warning:
the address of 'foo' will never be NULL
This is useful for the case where somebody wrote "foo" instead of
"foo()".
The C++ frontend does not issue this warning. This patch adds the
warning to the C++ frontend.
In the testsuite I added a couple of tests for
if (foo)
which is a warning which the C++ frontend already generates.
Tested with bootstrap and testsuite run on i686-pc-linux-gnu.
OK for mainline?
Ian
cp/ChangeLog:
2007-01-04 Ian Lance Taylor <iant@google.com>
* typeck.c (build_binary_op): Warn about comparing a non-weak
address to NULL.
testsuite/ChangeLog:
2007-01-04 Ian Lance Taylor <iant@google.com>
* g++.dg/warn/Walways-true-1.C: New test.
* g++.dg/warn/Walways-true-2.C: New test.
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c (revision 120376)
+++ gcc/cp/typeck.c (working copy)
@@ -3334,10 +3334,24 @@ build_binary_op (enum tree_code code, tr
"comparison");
else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0))
&& null_ptr_cst_p (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 || TYPE_PTRMEM_P (type1))
&& null_ptr_cst_p (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: gcc/testsuite/g++.dg/warn/Walways-true-1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Walways-true-1.C (revision 0)
+++ gcc/testsuite/g++.dg/warn/Walways-true-1.C (revision 0)
@@ -0,0 +1,30 @@
+// Test -Walways-true for testing an address against NULL.
+// Origin: Ian Lance Taylor <iant@google.com>
+
+// { dg-do compile}
+// { dg-options "-Walways-true" }
+
+extern int foo (int);
+
+int i;
+
+void
+bar ()
+{
+ if (foo) // { dg-warning "always evaluate as" "correct warning" }
+ foo (0);
+ if (foo (1))
+ foo (1);
+ if (&i) // { dg-warning "always evaluate as" "correct warning" }
+ foo (2);
+ if (i)
+ foo (3);
+ if (foo == 0) // { dg-warning "never be NULL" "correct warning" }
+ foo (4);
+ if (foo (1) == 0)
+ foo (5);
+ if (&i == 0) // { dg-warning "never be NULL" "correct warning" }
+ foo (6);
+ if (i == 0)
+ foo (7);
+}
Index: gcc/testsuite/g++.dg/warn/Walways-true-2.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Walways-true-2.C (revision 0)
+++ gcc/testsuite/g++.dg/warn/Walways-true-2.C (revision 0)
@@ -0,0 +1,33 @@
+// Make sure we don't assume that a weak symbol is always non-NULL.
+// This is just like Walways-true-1.C, except that it uses a weak
+// symbol.
+// Origin: Ian Lance Taylor <iant@google.com>
+
+// { dg-do compile}
+// { dg-options "-Walways-true" }
+// { dg-require-weak "" }
+
+extern int foo (int) __attribute__ ((weak));
+
+int i __attribute__ ((weak));
+
+void
+bar ()
+{
+ if (foo)
+ foo (0);
+ if (foo (1))
+ foo (1);
+ if (&i)
+ foo (2);
+ if (i)
+ foo (3);
+ if (foo == 0)
+ foo (4);
+ if (foo (1) == 0)
+ foo (5);
+ if (&i == 0)
+ foo (6);
+ if (i == 0)
+ foo (7);
+}
More information about the Gcc-patches
mailing list