From 29584285c784cfba40e744451bf036df59956fc3 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 4 Jun 2020 18:02:43 -0400 Subject: [PATCH 200/293] FIXME: data-model-20.c --- gcc/analyzer/region-model2.cc | 18 +++++++++++- gcc/analyzer/region-model2.h | 12 ++++++++ gcc/analyzer/store2.cc | 6 +++- gcc/analyzer/store2.h | 2 ++ gcc/testsuite/gcc.dg/analyzer/data-model-20.c | 28 +++++++++++++++++++ 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-20.c diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc index 00e1cdad920..eaf879c6052 100644 --- a/gcc/analyzer/region-model2.cc +++ b/gcc/analyzer/region-model2.cc @@ -6431,7 +6431,23 @@ region_model2::get_representative_path_var (const region2 *reg, } case region2::RK_OFFSET: - gcc_unreachable (); // TODO + { + const offset_region2 *offset_reg + = as_a (reg); + path_var parent_pv + = get_representative_path_var (reg->get_parent_region (), visited); + if (!parent_pv) + return path_var (NULL_TREE, 0); + path_var offset_pv + = get_representative_path_var (offset_reg->get_byte_offset (), + visited); + if (!offset_pv) + return path_var (NULL_TREE, 0); + return path_var (build2 (MEM_REF, + reg->get_type (), + parent_pv.m_tree, offset_pv.m_tree), + parent_pv.m_stack_depth); + } case region2::RK_CAST: { diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h index 1d201882efd..2a711c9d7d8 100644 --- a/gcc/analyzer/region-model2.h +++ b/gcc/analyzer/region-model2.h @@ -1535,6 +1535,18 @@ private: const svalue2 *m_byte_offset; }; +} // namespace ana + +template <> +template <> +inline bool +is_a_helper ::test (const region2 *reg) +{ + return reg->get_kind () == region2::RK_OFFSET; +} + +namespace ana { + /* A region that views another region using a different type. */ class cast_region2 : public region2 diff --git a/gcc/analyzer/store2.cc b/gcc/analyzer/store2.cc index 3afe1a40b64..d4bfd655322 100644 --- a/gcc/analyzer/store2.cc +++ b/gcc/analyzer/store2.cc @@ -738,7 +738,11 @@ binding_cluster2::get_representative_path_vars (const region_model2 *model, } else { - gcc_unreachable (); + const symbolic_binding2 *skey = (const symbolic_binding2 *)key; + if (path_var pv + = model->get_representative_path_var (skey->get_region (), + visited)) + out_pvs->safe_push (pv); } } } diff --git a/gcc/analyzer/store2.h b/gcc/analyzer/store2.h index eb9d59e323a..97435ea9524 100644 --- a/gcc/analyzer/store2.h +++ b/gcc/analyzer/store2.h @@ -261,6 +261,8 @@ public: void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE; + const region2 *get_region () const { return m_region; } + private: const region2 *m_region; }; diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-20.c b/gcc/testsuite/gcc.dg/analyzer/data-model-20.c new file mode 100644 index 00000000000..0072371c57d --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-20.c @@ -0,0 +1,28 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ +// TODO: we shouldn't need this ^^^ + +#include + +struct foo { int dummy; }; + +struct foo ** +test (int n) { + struct foo **arr; + int i; + + if ((arr = (struct foo **)malloc(n * sizeof(struct foo *))) == NULL) + return NULL; + + for (i = 0; i < n; i++) { + if ((arr[i] = (struct foo *)malloc(sizeof(struct foo))) == NULL) { + for (; i >= 0; i++) { + free(arr[i]); /* { dg-bogus "double-'free'" "" { xfail *-*-* } } */ + /* TODO(xfail): it's getting confused between frees of + different iterations of the loop. */ + } + free(arr); + return NULL; + } + } + return arr; +} -- 2.26.2