Previously the analyzer emitted a -Wanalyzer-null-dereference even when
the target pointer's address space allowed accesses at address 0.

This patch uses the targetm.addr_space.zero_address_valid hook to
correctly ignore such cases.

Tested on x86_64-pc-linux-gnu.

gcc/analyzer/ChangeLog:
        PR analyzer/123981

        * sm-malloc.cc (malloc_state_machine::on_stmt): Check
        if zero access is valid for the pointer's address space.

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.

Signed-off-by: Federico Angelilli <[email protected]>
---
 gcc/analyzer/sm-malloc.cc                            |  5 +++++
 .../gcc.dg/analyzer/null-deref-pr123981-1.c          | 12 ++++++++++++
 .../gcc.dg/analyzer/null-deref-pr123981-2.c          |  8 ++++++++
 3 files changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr123981-1.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr123981-2.c

diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index 6972a55d7fd..fb12b64d4be 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "make-unique.h"
+#include "target.h"
 #include "tree.h"
 #include "function.h"
 #include "basic-block.h"
@@ -2267,6 +2268,10 @@ malloc_state_machine::on_stmt (sm_context &sm_ctxt,
            }
          else if (state == m_null)
            {
+             addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (op));
+             if (targetm.addr_space.zero_address_valid (as))
+               continue;
+
              tree diag_arg = sm_ctxt.get_diagnostic_tree (arg);
              sm_ctxt.warn (node, stmt, arg,
                            make_unique<null_deref> (*this, diag_arg));
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 <immintrin.h>
+#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" } */
+}
-- 
2.52.0

Reply via email to