aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-01-05 19:05:46 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2007-01-05 19:05:46 +0000
commitb3c6d2ea006d4c688964c044a081ddea7884148a (patch)
tree5758b8cb24576b1e3eb71016f81cfeab25bbd494
parent97af925ba7b16e64c9f8b48cbfd5b4ccaa905f36 (diff)
downloadgcc-b3c6d2ea006d4c688964c044a081ddea7884148a.zip
gcc-b3c6d2ea006d4c688964c044a081ddea7884148a.tar.gz
gcc-b3c6d2ea006d4c688964c044a081ddea7884148a.tar.bz2
c-common.c (decl_with_nonnull_addr_p): New function.
./: * c-common.c (decl_with_nonnull_addr_p): New function. (c_common_truthvalue_conversion): Call it. * c-typeck.c (build_binary_op): Likewise. * c-common.h (decl_with_nonnull_addr_p): Declare. cp/: * typeck.c (build_binary_op): Warn about comparing a non-weak address to NULL. testsuite/: * gcc.dg/Walways-true-1.c: New test. * gcc.dg/Walways-true-2.c: New test. * g++.dg/warn/Walways-true-1.C: New test. * g++.dg/warn/Walways-true-2.C: New test. From-SVN: r120493
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/c-common.c35
-rw-r--r--gcc/c-common.h1
-rw-r--r--gcc/c-typeck.c10
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/typeck.c16
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/warn/Walways-true-1.C57
-rw-r--r--gcc/testsuite/g++.dg/warn/Walways-true-2.C60
-rw-r--r--gcc/testsuite/gcc.dg/Walways-true-1.c57
-rw-r--r--gcc/testsuite/gcc.dg/Walways-true-2.c60
11 files changed, 293 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c894c72..9292512 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2007-01-05 Ian Lance Taylor <iant@google.com>
+
+ * c-common.c (decl_with_nonnull_addr_p): New function.
+ (c_common_truthvalue_conversion): Call it.
+ * c-typeck.c (build_binary_op): Likewise.
+ * c-common.h (decl_with_nonnull_addr_p): Declare.
+
2007-01-05 Jakub Jelinek <jakub@redhat.com>
PR c/30360
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 2fd2a81..1794bd8 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -2591,6 +2591,18 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
return fold_build2 (resultcode, result_type, ptrop, intop);
}
+/* Return whether EXPR is a declaration whose address can never be
+ NULL. */
+
+bool
+decl_with_nonnull_addr_p (tree expr)
+{
+ return (DECL_P (expr)
+ && (TREE_CODE (expr) == PARM_DECL
+ || TREE_CODE (expr) == LABEL_DECL
+ || !DECL_WEAK (expr)));
+}
+
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
or for an `if' or `while' statement or ?..: exp. It should already
have been validated to be of suitable type; otherwise, a bad
@@ -2656,23 +2668,22 @@ c_common_truthvalue_conversion (tree expr)
case ADDR_EXPR:
{
tree inner = TREE_OPERAND (expr, 0);
- if (DECL_P (inner)
- && (TREE_CODE (inner) == PARM_DECL
- || TREE_CODE (inner) == LABEL_DECL
- || !DECL_WEAK (inner)))
+ if (decl_with_nonnull_addr_p (inner))
{
- /* Common Ada/Pascal programmer's mistake. We always warn
- about this since it is so bad. */
- warning (OPT_Walways_true, "the address of %qD will always evaluate as %<true%>",
+ /* Common Ada/Pascal programmer's mistake. */
+ warning (OPT_Walways_true,
+ "the address of %qD will always evaluate as %<true%>",
inner);
return truthvalue_true_node;
}
- /* If we are taking the address of an external decl, it might be
- zero if it is weak, so we cannot optimize. */
- if (DECL_P (inner)
- && DECL_EXTERNAL (inner))
- break;
+ /* If we still have a decl, it is possible for its address to
+ be NULL, so we cannot optimize. */
+ if (DECL_P (inner))
+ {
+ gcc_assert (DECL_WEAK (inner));
+ break;
+ }
if (TREE_SIDE_EFFECTS (inner))
return build2 (COMPOUND_EXPR, truthvalue_type_node,
diff --git a/gcc/c-common.h b/gcc/c-common.h
index b2b10bd..86b4487 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -652,6 +652,7 @@ extern tree c_common_unsigned_type (tree);
extern tree c_common_signed_type (tree);
extern tree c_common_signed_or_unsigned_type (int, tree);
extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int);
+extern bool decl_with_nonnull_addr_p (tree);
extern tree c_common_truthvalue_conversion (tree);
extern void c_apply_type_quals_to_decl (int, tree);
extern tree c_sizeof_or_alignof_type (tree, bool, int);
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 955bfd9..28d023d 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -8013,10 +8013,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
{
if (TREE_CODE (op0) == ADDR_EXPR
- && DECL_P (TREE_OPERAND (op0, 0))
- && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL
- || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL
- || !DECL_WEAK (TREE_OPERAND (op0, 0))))
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
warning (OPT_Walways_true, "the address of %qD will never be NULL",
TREE_OPERAND (op0, 0));
result_type = type0;
@@ -8024,10 +8021,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
{
if (TREE_CODE (op1) == ADDR_EXPR
- && DECL_P (TREE_OPERAND (op1, 0))
- && (TREE_CODE (TREE_OPERAND (op1, 0)) == PARM_DECL
- || TREE_CODE (TREE_OPERAND (op1, 0)) == LABEL_DECL
- || !DECL_WEAK (TREE_OPERAND (op1, 0))))
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
warning (OPT_Walways_true, "the address of %qD will never be NULL",
TREE_OPERAND (op1, 0));
result_type = type1;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 79dce74..1f7945d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2007-01-05 Ian Lance Taylor <iant@google.com>
+
+ * typeck.c (build_binary_op): Warn about comparing a non-weak
+ address to NULL.
+
2007-01-05 Douglas Gregor <doug.gregor@gmail.com>
* pt.c (tsubst): Propagate the need for structural equality checks
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 6c05b9f..061241d 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3334,10 +3334,22 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
"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_with_nonnull_addr_p (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_with_nonnull_addr_p (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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4636099..8856b7e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2007-01-05 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/Walways-true-1.c: New test.
+ * gcc.dg/Walways-true-2.c: New test.
+ * g++.dg/warn/Walways-true-1.C: New test.
+ * g++.dg/warn/Walways-true-2.C: New test.
+
2007-01-05 Jakub Jelinek <jakub@redhat.com>
PR c/30360
diff --git a/gcc/testsuite/g++.dg/warn/Walways-true-1.C b/gcc/testsuite/g++.dg/warn/Walways-true-1.C
new file mode 100644
index 0000000..5102ca1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Walways-true-1.C
@@ -0,0 +1,57 @@
+// 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 (int a)
+{
+ lab:
+ if (foo) // { dg-warning "always evaluate as" "correct warning" }
+ foo (0);
+ if (foo (1))
+ ;
+ if (&i) // { dg-warning "always evaluate as" "correct warning" }
+ foo (2);
+ if (i)
+ foo (3);
+ if (&a) // { dg-warning "always evaluate as" "correct warning" }
+ foo (4);
+ if (a)
+ foo (5);
+ if (&&lab) // { dg-warning "always evaluate as" "correct warning" }
+ foo (6);
+ if (foo == 0) // { dg-warning "never be NULL" "correct warning" }
+ foo (7);
+ if (foo (1) == 0)
+ foo (8);
+ if (&i == 0) // { dg-warning "never be NULL" "correct warning" }
+ foo (9);
+ if (i == 0)
+ foo (10);
+ if (&a == 0) // { dg-warning "never be NULL" "correct warning" }
+ foo (11);
+ if (a == 0)
+ foo (12);
+ if (&&lab == 0) // { dg-warning "never be NULL" "correct warning" }
+ foo (13);
+ if (0 == foo) // { dg-warning "never be NULL" "correct warning" }
+ foo (14);
+ if (0 == foo (1))
+ foo (15);
+ if (0 == &i) // { dg-warning "never be NULL" "correct warning" }
+ foo (16);
+ if (0 == i)
+ foo (17);
+ if (0 == &a) // { dg-warning "never be NULL" "correct warning" }
+ foo (18);
+ if (0 == a)
+ foo (19);
+ if (0 == &&lab) // { dg-warning "never be NULL" "correct warning" }
+ foo (20);
+}
diff --git a/gcc/testsuite/g++.dg/warn/Walways-true-2.C b/gcc/testsuite/g++.dg/warn/Walways-true-2.C
new file mode 100644
index 0000000..54085665
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Walways-true-2.C
@@ -0,0 +1,60 @@
+// 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 (int a)
+{
+ lab:
+ if (foo)
+ foo (0);
+ if (foo (1))
+ ;
+ if (&i)
+ foo (2);
+ if (i)
+ foo (3);
+ if (&a) // { dg-warning "always evaluate as" "correct warning" }
+ foo (4);
+ if (a)
+ foo (5);
+ if (&&lab) // { dg-warning "always evaluate as" "correct warning" }
+ foo (6);
+ if (foo == 0)
+ foo (7);
+ if (foo (1) == 0)
+ foo (8);
+ if (&i == 0)
+ foo (9);
+ if (i == 0)
+ foo (10);
+ if (&a == 0) // { dg-warning "never be NULL" "correct warning" }
+ foo (11);
+ if (a == 0)
+ foo (12);
+ if (&&lab == 0) // { dg-warning "never be NULL" "correct warning" }
+ foo (13);
+ if (0 == foo)
+ foo (14);
+ if (0 == foo (1))
+ foo (15);
+ if (0 == &i)
+ foo (16);
+ if (0 == i)
+ foo (17);
+ if (0 == &a) // { dg-warning "never be NULL" "correct warning" }
+ foo (18);
+ if (0 == a)
+ foo (19);
+ if (0 == &&lab) // { dg-warning "never be NULL" "correct warning" }
+ foo (20);
+}
diff --git a/gcc/testsuite/gcc.dg/Walways-true-1.c b/gcc/testsuite/gcc.dg/Walways-true-1.c
new file mode 100644
index 0000000..f531e8f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walways-true-1.c
@@ -0,0 +1,57 @@
+/* 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 (int a)
+{
+ lab:
+ if (foo) /* { dg-warning "always evaluate as" "correct warning" } */
+ foo (0);
+ if (foo (1))
+ ;
+ if (&i) /* { dg-warning "always evaluate as" "correct warning" } */
+ foo (2);
+ if (i)
+ foo (3);
+ if (&a) /* { dg-warning "always evaluate as" "correct warning" } */
+ foo (4);
+ if (a)
+ foo (5);
+ if (&&lab) /* { dg-warning "always evaluate as" "correct warning" } */
+ foo (6);
+ if (foo == 0) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (7);
+ if (foo (1) == 0)
+ foo (8);
+ if (&i == 0) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (9);
+ if (i == 0)
+ foo (10);
+ if (&a == 0) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (11);
+ if (a == 0)
+ foo (12);
+ if (&&lab == 0) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (13);
+ if (0 == foo) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (14);
+ if (0 == foo (1))
+ foo (15);
+ if (0 == &i) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (16);
+ if (0 == i)
+ foo (17);
+ if (0 == &a) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (18);
+ if (0 == a)
+ foo (19);
+ if (0 == &&lab) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (20);
+}
diff --git a/gcc/testsuite/gcc.dg/Walways-true-2.c b/gcc/testsuite/gcc.dg/Walways-true-2.c
new file mode 100644
index 0000000..cab897b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Walways-true-2.c
@@ -0,0 +1,60 @@
+/* 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 (int a)
+{
+ lab:
+ if (foo)
+ foo (0);
+ if (foo (1))
+ ;
+ if (&i)
+ foo (2);
+ if (i)
+ foo (3);
+ if (&a) /* { dg-warning "always evaluate as" "correct warning" } */
+ foo (4);
+ if (a)
+ foo (5);
+ if (&&lab) /* { dg-warning "always evaluate as" "correct warning" } */
+ foo (6);
+ if (foo == 0)
+ foo (7);
+ if (foo (1) == 0)
+ foo (8);
+ if (&i == 0)
+ foo (9);
+ if (i == 0)
+ foo (10);
+ if (&a == 0) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (11);
+ if (a == 0)
+ foo (12);
+ if (&&lab == 0) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (13);
+ if (0 == foo)
+ foo (14);
+ if (0 == foo (1))
+ foo (15);
+ if (0 == &i)
+ foo (16);
+ if (0 == i)
+ foo (17);
+ if (0 == &a) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (18);
+ if (0 == a)
+ foo (19);
+ if (0 == &&lab) /* { dg-warning "never be NULL" "correct warning" } */
+ foo (20);
+}