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