From 967bf3ceef6aaef81280e7dbbbc74434c91cba66 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 3 Jun 2019 18:02:08 -0400 Subject: [PATCH 25/28] FIXME: WIP on data-model-5.c --- gcc/analyzer/impl-4.cc | 5 ++--- gcc/analyzer/region-model.cc | 31 +++++++++++++++++++++++++++- gcc/analyzer/region-model.h | 2 ++ gcc/testsuite/gcc.dg/analyzer/data-model-1.c | 22 ++++++++++++-------- gcc/testsuite/gcc.dg/analyzer/data-model-5.c | 8 ++++--- 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/gcc/analyzer/impl-4.cc b/gcc/analyzer/impl-4.cc index 5089c16..fd76d06 100644 --- a/gcc/analyzer/impl-4.cc +++ b/gcc/analyzer/impl-4.cc @@ -5543,11 +5543,10 @@ state_purge_per_ssa_name::process_point (const program_point &point, pred, call_string ()), worklist, logger); - /* If no preds and it's the initial BB, add it, to ensure that we + /* If it's the initial BB, add it, to ensure that we have "before supernode" for the initial ENTRY block, and don't erroneously purge SSA names for initial values of parameters. */ - if (snode->entry_p () - && snode->m_preds.length () == 0) + if (snode->entry_p ()) { add_to_worklist (program_point::before_supernode (snode, diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index bc49e5d..770f145 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -704,7 +704,16 @@ region::get_value (region_model &model, bool non_null) ancestor = model.get_region (ancestor->m_parent_rid)) { if (!ancestor->m_sval_id.null_p ()) - return ancestor->m_sval_id; + { + /* Clone the ancestor value, so that attempts to update it + (e.g giving a specific value to an inherited "uninitialized" + value) touch the child, and not the ancestor. */ + svalue *ancestor_value = model.get_svalue (ancestor->m_sval_id); + svalue *new_child_value = ancestor_value->clone (); + svalue_id new_child_sid = model.add_svalue (new_child_value); + m_sval_id = new_child_sid; + return new_child_sid; + } } /* If a non-null value has been requested, then generate @@ -1517,6 +1526,14 @@ root_region::ensure_stack_region (region_model *model) /* FIXME. */ +stack_region * +root_region::get_stack_region (const region_model *model) const +{ + return model->get_region (m_stack_rid); +} + +/* FIXME. */ + region_id root_region::ensure_globals_region (region_model *model) { @@ -1847,6 +1864,18 @@ region_model::validate () const } // TODO: anything else? + + /* Verify that the stack region (if any) has an "uninitialized" value. */ + region *stack_region = get_root_region ()->get_stack_region (this); + if (stack_region) + { + svalue_id stack_value_sid = stack_region->get_value_direct (); + svalue *stack_value = get_svalue (stack_value_sid); + gcc_assert (stack_value->get_kind () == SK_POISONED); + poisoned_svalue *subclass = stack_value->dyn_cast_poisoned_svalue (); + gcc_assert (subclass); + gcc_assert (subclass->get_poison_kind () == POISON_KIND_UNINIT); + } } /* FIXME. */ diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index dc20d6b..457cd12 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -655,6 +655,8 @@ public: svalue_id pop_frame (region_model *model, purge_stats *stats); region_id ensure_stack_region (region_model *model); + stack_region *get_stack_region (const region_model *model) const; + region_id ensure_globals_region (region_model *model); region_id ensure_heap_region (region_model *model); diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c index f85317e..54ddcbc 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c @@ -178,13 +178,19 @@ int test_12d (struct coord c) { struct coord d; d = c; - __analyzer_eval (d.x == c.x); /* { dg-warning "TRUE" } */ - __analyzer_eval (d.y == c.y); /* { dg-warning "TRUE" } */ - __analyzer_eval (d.x == d.y); /* { dg-warning "UNKNOWN" "" { xfail *-*-* } } */ - /* { dg-warning "TRUE" "" { target *-*-* } .-1 } */ - /* TODO(xfail): d and c share an unknown value of type "struct coord". + __analyzer_eval (d.x == c.x); /* { dg-warning "TRUE" "" { xfail *-*-* } } */ + /* { dg-warning "UNKNOWN" "" { target *-*-* } .-1 } */ + /* TODO(xfail): c and d share the same unknown value of type "coord", but + attempts to access the fields lead to different unknown values. */ + + __analyzer_eval (d.y == c.y); /* { dg-warning "TRUE" "" { xfail *-*-* } } */ + /* { dg-warning "UNKNOWN" "" { target *-*-* } .-1 } */ + // TODO(xfail): likewise + + __analyzer_eval (d.x == d.y); /* { dg-warning "UNKNOWN" } */ + /* d and c share an unknown value of type "struct coord". But d.x and d.y should be different unknown values (although they inherit - from d's region. */ + from d's region). */ } /* Nested structs. */ @@ -330,9 +336,7 @@ void test_19 (void) { int i, j; /* Compare two uninitialized locals. */ - __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" "" { xfail *-*-* } } */ - /* { dg-warning "TRUE" "" { target *-*-* } .-1 } */ - // TODO(xfail) + __analyzer_eval (i == j); /* { dg-warning "UNKNOWN" } */ } void test_20 (int i, int j) diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-5.c b/gcc/testsuite/gcc.dg/analyzer/data-model-5.c index 46881c9..e20a9f8 100644 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-5.c +++ b/gcc/testsuite/gcc.dg/analyzer/data-model-5.c @@ -71,7 +71,7 @@ base_obj *alloc_obj (type_obj *ob_type, size_t sz) base_obj *new_string_obj (const char *str) { - __analyzer_dump (); + //__analyzer_dump (); size_t len = strlen (str); #if 1 string_obj *str_obj @@ -83,7 +83,7 @@ base_obj *new_string_obj (const char *str) str_obj->str_base.ob_type = &str_type; str_obj->str_base.ob_refcnt = 1; #endif - str_obj->str_len = len; + str_obj->str_len = len; /* { dg-warning "use of NULL 'str_obj'" } */ memcpy (str_obj->str_buf, str, len); str_obj->str_buf[len] = '\0'; return (base_obj *)str_obj; @@ -93,7 +93,7 @@ void unref (base_obj *obj) { if (--obj->ob_refcnt == 0) { - __analyzer_dump(); + //__analyzer_dump(); obj->ob_type->tp_dealloc (obj); } } @@ -125,4 +125,6 @@ but at: we have: sv0: {type: ‘struct base_obj *’, &r18} in "created EN: 321" (before pruning) + +Maybe put an assertion in the "validate" method? */ -- 1.8.5.3