Verify that arguments are pointers before calling handling code
that calls deref_rvalue on them.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to master as r11-3341-g1e19ecd79b45af6df87a6869d1936b857c9f71fc.

gcc/analyzer/ChangeLog:
        PR analyzer/97130
        * region-model-impl-calls.cc (call_details::get_arg_type): New.
        * region-model.cc (region_model::on_call_pre): Check that the
        initial arg is a pointer before calling impl_call_memset and
        impl_call_strlen.
        * region-model.h (call_details::get_arg_type): New decl.

gcc/testsuite/ChangeLog:
        PR analyzer/97130
        * gcc.dg/analyzer/pr97130.c: New test.
---
 gcc/analyzer/region-model-impl-calls.cc |  8 ++++++++
 gcc/analyzer/region-model.cc            |  6 ++++--
 gcc/analyzer/region-model.h             |  1 +
 gcc/testsuite/gcc.dg/analyzer/pr97130.c | 10 ++++++++++
 4 files changed, 23 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr97130.c

diff --git a/gcc/analyzer/region-model-impl-calls.cc 
b/gcc/analyzer/region-model-impl-calls.cc
index 6582ffb3c95..423f74a4152 100644
--- a/gcc/analyzer/region-model-impl-calls.cc
+++ b/gcc/analyzer/region-model-impl-calls.cc
@@ -103,6 +103,14 @@ call_details::get_arg_tree (unsigned idx) const
   return gimple_call_arg (m_call, idx);
 }
 
+/* Get the type of argument IDX.  */
+
+tree
+call_details::get_arg_type (unsigned idx) const
+{
+  return TREE_TYPE (gimple_call_arg (m_call, idx));
+}
+
 /* Get argument IDX at the callsite as an svalue.  */
 
 const svalue *
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 1312391557d..6f04904a74e 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -737,12 +737,14 @@ region_model::on_call_pre (const gcall *call, 
region_model_context *ctxt)
          /* No side-effects (tracking stream state is out-of-scope
             for the analyzer).  */
        }
-      else if (is_named_call_p (callee_fndecl, "memset", call, 3))
+      else if (is_named_call_p (callee_fndecl, "memset", call, 3)
+              && POINTER_TYPE_P (cd.get_arg_type (0)))
        {
          impl_call_memset (cd);
          return false;
        }
-      else if (is_named_call_p (callee_fndecl, "strlen", call, 1))
+      else if (is_named_call_p (callee_fndecl, "strlen", call, 1)
+              && POINTER_TYPE_P (cd.get_arg_type (0)))
        {
          if (impl_call_strlen (cd))
            return false;
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 1bb9798ae58..4859df369cf 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -2482,6 +2482,7 @@ public:
   bool maybe_set_lhs (const svalue *result) const;
 
   tree get_arg_tree (unsigned idx) const;
+  tree get_arg_type (unsigned idx) const;
   const svalue *get_arg_svalue (unsigned idx) const;
 
   void dump_to_pp (pretty_printer *pp, bool simple) const;
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr97130.c 
b/gcc/testsuite/gcc.dg/analyzer/pr97130.c
new file mode 100644
index 00000000000..f437b763c94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr97130.c
@@ -0,0 +1,10 @@
+/* { dg-additional-options "-Wno-builtin-declaration-mismatch" } */
+
+void *
+memset (int, int, __SIZE_TYPE__);
+
+void
+mp (int xl)
+{
+  memset (xl, 0, sizeof xl);
+}
-- 
2.26.2

Reply via email to