diff options
author | Martin Sebor <msebor@redhat.com> | 2021-10-01 11:50:25 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2021-10-01 11:57:05 -0600 |
commit | 4dc7ce6fb3917958d1a6036d8acf2953b9c1b868 (patch) | |
tree | dbf4c85270f34d710113d1bdeb3883cd32d6ff01 /gcc/c-family/c-common.c | |
parent | f1710910087fb1f4a7706e9ce838163ffcbc50b4 (diff) | |
download | gcc-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.c | 29 |
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; |