From 1e19ecd79b45af6df87a6869d1936b857c9f71fc Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 21 Sep 2020 11:59:26 -0400 Subject: [PATCH] analyzer: fix ICE on bogus decl of memset [PR97130] Verify that arguments are pointers before calling handling code that calls deref_rvalue on them. 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.30.2