This patch adds the "shrinks buffer" case to the success_with_move modelling of realloc.
2022-08-09 Tim Lange <m...@tim-lange.me> gcc/analyzer/ChangeLog: PR analyzer/106539 * region-model-impl-calls.cc (region_model::impl_call_realloc): Add get_copied_size function and pass the result as the size of the new sized_region. --- gcc/analyzer/region-model-impl-calls.cc | 37 ++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc index 8c38e9206fa..50a19a52a21 100644 --- a/gcc/analyzer/region-model-impl-calls.cc +++ b/gcc/analyzer/region-model-impl-calls.cc @@ -737,9 +737,11 @@ region_model::impl_call_realloc (const call_details &cd) old_size_sval); const svalue *buffer_content_sval = model->get_store_value (sized_old_reg, cd.get_ctxt ()); + const svalue *copied_size_sval + = get_copied_size (old_size_sval, new_size_sval); const region *sized_new_reg = model->m_mgr->get_sized_region (new_reg, NULL, - old_size_sval); + copied_size_sval); model->set_value (sized_new_reg, buffer_content_sval, cd.get_ctxt ()); } @@ -774,6 +776,39 @@ region_model::impl_call_realloc (const call_details &cd) else return true; } + + private: + /* Return the size svalue for the new region allocated by realloc. */ + const svalue *get_copied_size (const svalue *old_size_sval, + const svalue *new_size_sval) const + { + tree old_size_cst = old_size_sval->maybe_get_constant (); + tree new_size_cst = new_size_sval->maybe_get_constant (); + + if (old_size_cst && new_size_cst) + { + /* Both are constants and comparable. */ + tree cmp = fold_binary (LT_EXPR, boolean_type_node, + old_size_cst, new_size_cst); + + if (cmp == boolean_true_node) + return old_size_sval; + else + return new_size_sval; + } + else if (new_size_cst) + { + /* OLD_SIZE_SVAL is symbolic, so return that. */ + return old_size_sval; + } + else + { + /* NEW_SIZE_SVAL is symbolic or both are symbolic. + Return NEW_SIZE_SVAL, because implementations of realloc + probably only moves the buffer if the new size is larger. */ + return new_size_sval; + } + } }; /* Body of region_model::impl_call_realloc. */ -- 2.37.1