aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-common.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-10-01 11:50:25 -0600
committerMartin Sebor <msebor@redhat.com>2021-10-01 11:57:05 -0600
commit4dc7ce6fb3917958d1a6036d8acf2953b9c1b868 (patch)
treedbf4c85270f34d710113d1bdeb3883cd32d6ff01 /gcc/c-family/c-common.c
parentf1710910087fb1f4a7706e9ce838163ffcbc50b4 (diff)
downloadgcc-4dc7ce6fb3917958d1a6036d8acf2953b9c1b868.zip
gcc-4dc7ce6fb3917958d1a6036d8acf2953b9c1b868.tar.gz
gcc-4dc7ce6fb3917958d1a6036d8acf2953b9c1b868.tar.bz2
Enhance -Waddress to detect more suspicious expressions [PR102103].
Resolves: PR c/102103 - missing warning comparing array address to null gcc/ChangeLog: PR c/102103 * doc/invoke.texi (-Waddress): Update. * gengtype.c (write_types): Avoid -Waddress. * poly-int.h (POLY_SET_COEFF): Avoid using null. gcc/c-family/ChangeLog: PR c/102103 * c-common.c (decl_with_nonnull_addr_p): Handle members. Check and perform warning suppression. (c_common_truthvalue_conversion): Enhance warning suppression. gcc/c/ChangeLog: PR c/102103 * c-typeck.c (maybe_warn_for_null_address): New function. (build_binary_op): Call it. gcc/cp/ChangeLog: PR c/102103 * typeck.c (warn_for_null_address): Enhance. (cp_build_binary_op): Call it also for member pointers. gcc/fortran/ChangeLog: PR c/102103 * array.c: Remove an unnecessary test. * trans-array.c: Same. gcc/testsuite/ChangeLog: PR c/102103 * g++.dg/cpp0x/constexpr-array-ptr10.C: Suppress a valid warning. * g++.dg/warn/Wreturn-local-addr-6.C: Correct a cast. * gcc.dg/Waddress.c: Expect a warning. * c-c++-common/Waddress-3.c: New test. * c-c++-common/Waddress-4.c: New test. * g++.dg/warn/Waddress-5.C: New test. * g++.dg/warn/Waddress-6.C: New test. * g++.dg/warn/pr101219.C: Expect a warning. * gcc.dg/Waddress-3.c: New test.
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r--gcc/c-family/c-common.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 5845c67..9d19e35 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -3393,14 +3393,16 @@ c_wrap_maybe_const (tree expr, bool non_const)
return expr;
}
-/* Return whether EXPR is a declaration whose address can never be
- NULL. */
+/* Return whether EXPR is a declaration whose address can never be NULL.
+ The address of the first struct member could be NULL only if it were
+ accessed through a NULL pointer, and such an access would be invalid. */
bool
decl_with_nonnull_addr_p (const_tree expr)
{
return (DECL_P (expr)
- && (TREE_CODE (expr) == PARM_DECL
+ && (TREE_CODE (expr) == FIELD_DECL
+ || TREE_CODE (expr) == PARM_DECL
|| TREE_CODE (expr) == LABEL_DECL
|| !DECL_WEAK (expr)));
}
@@ -3488,13 +3490,17 @@ c_common_truthvalue_conversion (location_t location, tree expr)
case ADDR_EXPR:
{
tree inner = TREE_OPERAND (expr, 0);
- if (decl_with_nonnull_addr_p (inner))
+ if (decl_with_nonnull_addr_p (inner)
+ /* Check both EXPR and INNER for suppression. */
+ && !warning_suppressed_p (expr, OPT_Waddress)
+ && !warning_suppressed_p (inner, OPT_Waddress))
{
- /* Common Ada programmer's mistake. */
+ /* Common Ada programmer's mistake. */
warning_at (location,
OPT_Waddress,
"the address of %qD will always evaluate as %<true%>",
inner);
+ suppress_warning (inner, OPT_Waddress);
return truthvalue_true_node;
}
break;
@@ -3627,8 +3633,17 @@ c_common_truthvalue_conversion (location_t location, tree expr)
break;
/* If this isn't narrowing the argument, we can ignore it. */
if (TYPE_PRECISION (totype) >= TYPE_PRECISION (fromtype))
- return c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr, 0));
+ {
+ tree op0 = TREE_OPERAND (expr, 0);
+ if ((TREE_CODE (fromtype) == POINTER_TYPE
+ && TREE_CODE (totype) == INTEGER_TYPE)
+ || warning_suppressed_p (expr, OPT_Waddress))
+ /* Suppress -Waddress for casts to intptr_t, propagating
+ any suppression from the enclosing expression to its
+ operand. */
+ suppress_warning (op0, OPT_Waddress);
+ return c_common_truthvalue_conversion (location, op0);
+ }
}
break;