PR analyzer/106479 notes that we don't always show the region-creation
event for a memmove from an uninitialized stack region.  This occurs
when using kf_memcpy_memmove.  Fix by passing a src_region hint to
region_model::check_for_poison.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-4750-g2fdc8546b5c6cb.

gcc/analyzer/ChangeLog:
        PR analyzer/106479
        * kf.cc (kf_memcpy_memmove::impl_call_pre): Pass in source region
        to region_model::check_for_poison.
        * region-model-asm.cc (region_model::on_asm_stmt): Pass NULL
        region to region_model::check_for_poison.
        * region-model.cc (region_model::check_for_poison): Add
        "src_region" param, and pass it to poisoned_value_diagnostic.
        (region_model::on_assignment): Pass NULL region to
        region_model::check_for_poison.
        (region_model::get_rvalue): Likewise.
        * region-model.h (region_model::check_for_poison): Add
        "src_region" param.
        * sm-fd.cc (fd_state_machine::on_accept): Pass in source region
        to region_model::check_for_poison.
        * varargs.cc (kf_va_copy::impl_call_pre): Pass NULL region to
        region_model::check_for_poison.
        (kf_va_arg::impl_call_pre): Pass in source region to
        region_model::check_for_poison.

gcc/testsuite/ChangeLog:
        PR analyzer/106479
        * gcc.dg/analyzer/pr104308.c (test_memmove_within_uninit): Remove
        xfail on region creation event.

Signed-off-by: David Malcolm <dmalc...@redhat.com>
---
 gcc/analyzer/kf.cc                       |  2 +-
 gcc/analyzer/region-model-asm.cc         |  2 +-
 gcc/analyzer/region-model.cc             | 11 ++++++-----
 gcc/analyzer/region-model.h              |  1 +
 gcc/analyzer/sm-fd.cc                    |  1 +
 gcc/analyzer/varargs.cc                  |  3 ++-
 gcc/testsuite/gcc.dg/analyzer/pr104308.c |  2 +-
 7 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
index ff2f1b1ef9c..6088bfc72c0 100644
--- a/gcc/analyzer/kf.cc
+++ b/gcc/analyzer/kf.cc
@@ -288,7 +288,7 @@ kf_memcpy_memmove::impl_call_pre (const call_details &cd) 
const
   const svalue *src_contents_sval
     = model->get_store_value (sized_src_reg, cd.get_ctxt ());
   model->check_for_poison (src_contents_sval, cd.get_arg_tree (1),
-                          cd.get_ctxt ());
+                          sized_src_reg, cd.get_ctxt ());
   model->set_value (sized_dest_reg, src_contents_sval, cd.get_ctxt ());
 }
 
diff --git a/gcc/analyzer/region-model-asm.cc b/gcc/analyzer/region-model-asm.cc
index 171b2496f58..ac32c6f06f7 100644
--- a/gcc/analyzer/region-model-asm.cc
+++ b/gcc/analyzer/region-model-asm.cc
@@ -226,7 +226,7 @@ region_model::on_asm_stmt (const gasm *stmt, 
region_model_context *ctxt)
 
       tree src_expr = input_tvec[i];
       const svalue *src_sval = get_rvalue (src_expr, ctxt);
-      check_for_poison (src_sval, src_expr, ctxt);
+      check_for_poison (src_sval, src_expr, NULL, ctxt);
       input_svals.quick_push (src_sval);
       reachable_regs.handle_sval (src_sval);
 
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index f6cd34f4c22..55064400a08 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1004,11 +1004,13 @@ due_to_ifn_deferred_init_p (const gassign *assign_stmt)
 
 /* Check for SVAL being poisoned, adding a warning to CTXT.
    Return SVAL, or, if a warning is added, another value, to avoid
-   repeatedly complaining about the same poisoned value in followup code.  */
+   repeatedly complaining about the same poisoned value in followup code.
+   SRC_REGION is a hint about where SVAL came from, and can be NULL.  */
 
 const svalue *
 region_model::check_for_poison (const svalue *sval,
                                tree expr,
+                               const region *src_region,
                                region_model_context *ctxt) const
 {
   if (!ctxt)
@@ -1046,8 +1048,7 @@ region_model::check_for_poison (const svalue *sval,
         the tree other than via the def stmts, using
         fixup_tree_for_diagnostic.  */
       tree diag_arg = fixup_tree_for_diagnostic (expr);
-      const region *src_region = NULL;
-      if (pkind == POISON_KIND_UNINIT)
+      if (src_region == NULL && pkind == POISON_KIND_UNINIT)
        src_region = get_region_for_poisoned_expr (expr);
       if (ctxt->warn (make_unique<poisoned_value_diagnostic> (diag_arg,
                                                              pkind,
@@ -1100,7 +1101,7 @@ region_model::on_assignment (const gassign *assign, 
region_model_context *ctxt)
   if (const svalue *sval = get_gassign_result (assign, ctxt))
     {
       tree expr = get_diagnostic_tree_for_gassign (assign);
-      check_for_poison (sval, expr, ctxt);
+      check_for_poison (sval, expr, NULL, ctxt);
       set_value (lhs_reg, sval, ctxt);
       return;
     }
@@ -2227,7 +2228,7 @@ region_model::get_rvalue (path_var pv, 
region_model_context *ctxt) const
 
   assert_compat_types (result_sval->get_type (), TREE_TYPE (pv.m_tree));
 
-  result_sval = check_for_poison (result_sval, pv.m_tree, ctxt);
+  result_sval = check_for_poison (result_sval, pv.m_tree, NULL, ctxt);
 
   return result_sval;
 }
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 626b10d2538..e8767e5ed41 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -485,6 +485,7 @@ class region_model
 
   const svalue *check_for_poison (const svalue *sval,
                                  tree expr,
+                                 const region *src_region,
                                  region_model_context *ctxt) const;
 
   void check_region_for_write (const region *dest_reg,
diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
index 50e1313f85b..03bcdfa60b4 100644
--- a/gcc/analyzer/sm-fd.cc
+++ b/gcc/analyzer/sm-fd.cc
@@ -1992,6 +1992,7 @@ fd_state_machine::on_accept (const call_details &cd,
                                  build_int_cst (TREE_TYPE (len_ptr), 0));
       old_len_sval = model->check_for_poison (old_len_sval,
                                              star_len_ptr,
+                                             len_reg,
                                              cd.get_ctxt ());
       if (successful)
        {
diff --git a/gcc/analyzer/varargs.cc b/gcc/analyzer/varargs.cc
index 1a3bddee4b2..5414f233ab1 100644
--- a/gcc/analyzer/varargs.cc
+++ b/gcc/analyzer/varargs.cc
@@ -723,6 +723,7 @@ kf_va_copy::impl_call_pre (const call_details &cd) const
   in_va_list
     = model->check_for_poison (in_va_list,
                               get_va_list_diag_arg (cd.get_arg_tree (1)),
+                              NULL,
                               cd.get_ctxt ());
 
   const region *out_dst_reg
@@ -1004,7 +1005,7 @@ kf_va_arg::impl_call_pre (const call_details &cd) const
     ap_sval = cast;
 
   tree va_list_tree = get_va_list_diag_arg (cd.get_arg_tree (0));
-  ap_sval = model->check_for_poison (ap_sval, va_list_tree, ctxt);
+  ap_sval = model->check_for_poison (ap_sval, va_list_tree, ap_reg, ctxt);
 
   if (const region *impl_reg = ap_sval->maybe_get_region ())
     {
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104308.c 
b/gcc/testsuite/gcc.dg/analyzer/pr104308.c
index e6a2c8821bf..a3a0cbb7317 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr104308.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr104308.c
@@ -6,7 +6,7 @@
 
 int test_memmove_within_uninit (void)
 {
-  char s[5]; /* { dg-message "region created on stack here" "" { xfail 
riscv*-*-* } } */
+  char s[5]; /* { dg-message "region created on stack here" } */
   memmove(s, s + 1, 2); /* { dg-warning "use of uninitialized value" } */
   return 0;
 }
-- 
2.26.3

Reply via email to