From: Federico Angelilli Date: Mon, 9 Feb 2026 23:41:22 +0000 (-0500) Subject: Suppress -Wanalyzer-{possible}-null-deref in some address spaces [PR123981] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f206c5cfc5581b700ddefbadde473bc6da5e849;p=thirdparty%2Fgcc.git Suppress -Wanalyzer-{possible}-null-deref in some address spaces [PR123981] gcc/analyzer/ChangeLog: PR analyzer/123981 * sm-malloc.cc: Include "target.h". (zero_address_valid_p): New. (malloc_state_machine::on_stmt): Guard possible_null_deref and null_deref with !zero_address_valid_p. gcc/testsuite/ChangeLog: PR analyzer/123981 * gcc.dg/analyzer/null-deref-pr123981-1.c: New test. * gcc.dg/analyzer/null-deref-pr123981-2.c: New test. Co-Authored-By: David Malcolm Signed-off-by: Federico Angelilli Signed-off-by: David Malcolm --- diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc index 657ebd3aff7..2c036fc7d8b 100644 --- a/gcc/analyzer/sm-malloc.cc +++ b/gcc/analyzer/sm-malloc.cc @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "stringpool.h" #include "attribs.h" #include "xml-printer.h" +#include "target.h" #include "analyzer/analyzer-logging.h" #include "analyzer/sm.h" @@ -2087,6 +2088,25 @@ malloc_state_machine::handle_nonnull (sm_context &sm_ctxt, maybe_assume_non_null (sm_ctxt, arg); } +/* Return true if it's valid to dereference the zero value of PTR_TYPE, + or false if we should warn on it. */ + +static bool +zero_address_valid_p (const_tree ptr_type) +{ + gcc_assert (POINTER_TYPE_P (ptr_type)); + + /* Some targets have address spaces in which it's valid + to dereference zero. */ + addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (ptr_type)); + if (!ADDR_SPACE_GENERIC_P (as) + && targetm.addr_space.zero_address_valid (as)) + return true; + + /* Invalid. */ + return false; +} + /* Implementation of state_machine::on_stmt vfunc for malloc_state_machine. */ bool @@ -2250,19 +2270,25 @@ malloc_state_machine::on_stmt (sm_context &sm_ctxt, maybe_assume_non_null (sm_ctxt, arg); else if (unchecked_p (state)) { - tree diag_arg = sm_ctxt.get_diagnostic_tree (arg); - sm_ctxt.warn (arg, - std::make_unique (*this, - diag_arg)); - const allocation_state *astate = as_a_allocation_state (state); - sm_ctxt.set_next_state (arg, astate->get_nonnull ()); + if (!zero_address_valid_p (TREE_TYPE (arg))) + { + tree diag_arg = sm_ctxt.get_diagnostic_tree (arg); + sm_ctxt.warn (arg, + std::make_unique (*this, + diag_arg)); + const allocation_state *astate = as_a_allocation_state (state); + sm_ctxt.set_next_state (arg, astate->get_nonnull ()); + } } else if (state == m_null) { - tree diag_arg = sm_ctxt.get_diagnostic_tree (arg); - sm_ctxt.warn (arg, - std::make_unique (*this, diag_arg)); - sm_ctxt.set_next_state (arg, m_stop); + if (!zero_address_valid_p (TREE_TYPE (arg))) + { + tree diag_arg = sm_ctxt.get_diagnostic_tree (arg); + sm_ctxt.warn (arg, + std::make_unique (*this, diag_arg)); + sm_ctxt.set_next_state (arg, m_stop); + } } else if (freed_p (state)) { diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr123981-1.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr123981-1.c new file mode 100644 index 00000000000..2df9d7813d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr123981-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-additional-options "-mfsgsbase" } */ + +#include +#define getgs() ((int __seg_gs *)0) + +int main() +{ + static int gsval = 42; + _writegsbase_u64((unsigned long long)&gsval); + return *getgs(); /* { dg-bogus "-Wanalyzer-null-dereference" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr123981-2.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr123981-2.c new file mode 100644 index 00000000000..03a48349244 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr123981-2.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ + +#define getfs() ((int __seg_fs *)0) + +int main() +{ + return *getfs(); /* { dg-bogus "-Wanalyzer-null-dereference" } */ +}