-
Notifications
You must be signed in to change notification settings - Fork 273
SSS: value-set-analysis adaptation #612
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
c308d18
83fd948
1a314e3
913fbd9
ff34029
87f1bce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,10 +10,10 @@ Author: Daniel Kroening, [email protected] | |
#define CPROVER_POINTER_ANALYSIS_SHOW_VALUE_SETS_H | ||
|
||
#include <util/ui_message.h> | ||
#include "value_set_analysis.h" | ||
|
||
class goto_functionst; | ||
class goto_programt; | ||
class value_set_analysist; | ||
|
||
void show_value_sets( | ||
ui_message_handlert::uit ui, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1062,6 +1062,32 @@ void value_sett::get_reference_set( | |
dest.push_back(to_expr(it)); | ||
} | ||
|
||
static void strip_casts( | ||
exprt &e, | ||
const namespacet &ns, | ||
const typet &target_type_raw) | ||
{ | ||
const auto &target_type=ns.follow(target_type_raw); | ||
while(true) | ||
{ | ||
if(e.id()==ID_typecast) | ||
e=e.op0(); | ||
else if(e.id()==ID_member) | ||
{ | ||
auto &mem=to_member_expr(e); | ||
const auto &struct_type=to_struct_type(ns.follow(e.op0().type())); | ||
if(mem.get_component_name()==struct_type.components()[0].get_name()) | ||
e=e.op0(); | ||
else | ||
return; | ||
} | ||
else | ||
return; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe add a blank line after the return |
||
if(ns.follow(e.type())==target_type) | ||
return; | ||
} | ||
} | ||
|
||
/*******************************************************************\ | ||
|
||
Function: value_sett::get_reference_set_rec | ||
|
@@ -1208,7 +1234,13 @@ void value_sett::get_reference_set_rec( | |
{ | ||
// adjust type? | ||
if(ns.follow(struct_op.type())!=final_object_type) | ||
{ | ||
// Avoid an infinite loop of casting by stripping typecasts | ||
// and address-of-first-members first. | ||
strip_casts(member_expr.op0(), ns, struct_op.type()); | ||
if(ns.follow(member_expr.op0().type())!=ns.follow(struct_op.type())) | ||
member_expr.op0().make_typecast(struct_op.type()); | ||
} | ||
|
||
insert(dest, member_expr, o); | ||
} | ||
|
@@ -1492,7 +1524,6 @@ void value_sett::assign_rec( | |
if(lhs.id()==ID_symbol) | ||
{ | ||
const irep_idt &identifier=to_symbol_expr(lhs).get_identifier(); | ||
|
||
entryt &e=get_entry(entryt(identifier, suffix), lhs.type(), ns); | ||
|
||
if(add_to_sets) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,114 +8,13 @@ Author: Daniel Kroening, [email protected] | |
|
||
#include <util/prefix.h> | ||
#include <util/cprover_prefix.h> | ||
#include <util/xml_expr.h> | ||
#include <util/xml.h> | ||
|
||
#include <langapi/language_util.h> | ||
|
||
#include "value_set_analysis.h" | ||
|
||
/*******************************************************************\ | ||
|
||
Function: value_set_analysist::initialize | ||
|
||
Inputs: | ||
|
||
Outputs: | ||
|
||
Purpose: | ||
|
||
\*******************************************************************/ | ||
|
||
void value_set_analysist::initialize( | ||
const goto_programt &goto_program) | ||
{ | ||
baset::initialize(goto_program); | ||
} | ||
|
||
/*******************************************************************\ | ||
|
||
Function: value_set_analysist::initialize | ||
|
||
Inputs: | ||
|
||
Outputs: | ||
|
||
Purpose: | ||
|
||
\*******************************************************************/ | ||
|
||
void value_set_analysist::initialize( | ||
const goto_functionst &goto_functions) | ||
{ | ||
baset::initialize(goto_functions); | ||
} | ||
|
||
/*******************************************************************\ | ||
|
||
Function: value_set_analysist::convert | ||
|
||
Inputs: | ||
|
||
Outputs: | ||
|
||
Purpose: | ||
|
||
\*******************************************************************/ | ||
|
||
void value_set_analysist::convert( | ||
const goto_programt &goto_program, | ||
const irep_idt &identifier, | ||
xmlt &dest) const | ||
{ | ||
source_locationt previous_location; | ||
|
||
forall_goto_program_instructions(i_it, goto_program) | ||
{ | ||
const source_locationt &location=i_it->source_location; | ||
|
||
if(location==previous_location) | ||
continue; | ||
|
||
if(location.is_nil() || location.get_file()==irep_idt()) | ||
continue; | ||
|
||
// find value set | ||
const value_sett &value_set=(*this)[i_it].value_set; | ||
|
||
xmlt &i=dest.new_element("instruction"); | ||
i.new_element()=::xml(location); | ||
|
||
for(value_sett::valuest::const_iterator | ||
v_it=value_set.values.begin(); | ||
v_it!=value_set.values.end(); | ||
v_it++) | ||
{ | ||
xmlt &var=i.new_element("variable"); | ||
var.new_element("identifier").data= | ||
id2string(v_it->first); | ||
|
||
#if 0 | ||
const value_sett::expr_sett &expr_set= | ||
v_it->second.expr_set(); | ||
|
||
for(value_sett::expr_sett::const_iterator | ||
e_it=expr_set.begin(); | ||
e_it!=expr_set.end(); | ||
e_it++) | ||
{ | ||
std::string value_str= | ||
from_expr(ns, identifier, *e_it); | ||
|
||
var.new_element("value").data= | ||
xmlt::escape(value_str); | ||
} | ||
#endif | ||
} | ||
} | ||
} | ||
/*******************************************************************\ | ||
|
||
Function: convert | ||
|
||
Inputs: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,32 +11,90 @@ Author: Daniel Kroening, [email protected] | |
|
||
#define USE_DEPRECATED_STATIC_ANALYSIS_H | ||
#include <analyses/static_analysis.h> | ||
#include <util/xml_expr.h> | ||
#include <util/xml.h> | ||
|
||
#include "value_set_domain.h" | ||
#include "value_sets.h" | ||
#include "value_set.h" | ||
|
||
class xmlt; | ||
|
||
class value_set_analysist: | ||
template<class Value_Sett> | ||
class value_set_analysis_baset: | ||
public value_setst, | ||
public static_analysist<value_set_domaint> | ||
public static_analysist<value_set_domaint<Value_Sett> > | ||
{ | ||
public: | ||
explicit value_set_analysist(const namespacet &_ns): | ||
static_analysist<value_set_domaint>(_ns) | ||
typedef value_set_domaint<Value_Sett> domaint; | ||
typedef static_analysist<domaint> baset; | ||
typedef typename baset::locationt locationt; | ||
|
||
explicit value_set_analysis_baset(const namespacet &_ns):baset(_ns) | ||
{ | ||
} | ||
|
||
typedef static_analysist<value_set_domaint> baset; | ||
|
||
// overloading | ||
virtual void initialize(const goto_programt &goto_program); | ||
virtual void initialize(const goto_functionst &goto_functions); | ||
void initialize(const goto_programt &goto_program) | ||
{ | ||
baset::initialize(goto_program); | ||
} | ||
void initialize(const goto_functionst &goto_functions) | ||
{ | ||
baset::initialize(goto_functions); | ||
} | ||
|
||
void convert( | ||
const goto_programt &goto_program, | ||
const irep_idt &identifier, | ||
xmlt &dest) const; | ||
xmlt &dest) const | ||
{ | ||
source_locationt previous_location; | ||
|
||
forall_goto_program_instructions(i_it, goto_program) | ||
{ | ||
const source_locationt &location=i_it->source_location; | ||
|
||
if(location==previous_location) | ||
continue; | ||
|
||
if(location.is_nil() || location.get_file()==irep_idt()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. get_file().empty() |
||
continue; | ||
|
||
// find value set | ||
const value_sett &value_set=(*this)[i_it].value_set; | ||
|
||
xmlt &i=dest.new_element("instruction"); | ||
i.new_element()=::xml(location); | ||
|
||
for(value_sett::valuest::const_iterator | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for each |
||
v_it=value_set.values.begin(); | ||
v_it!=value_set.values.end(); | ||
v_it++) | ||
{ | ||
xmlt &var=i.new_element("variable"); | ||
var.new_element("identifier").data= | ||
id2string(v_it->first); | ||
|
||
#if 0 | ||
const value_sett::expr_sett &expr_set= | ||
v_it->second.expr_set(); | ||
|
||
for(value_sett::expr_sett::const_iterator | ||
e_it=expr_set.begin(); | ||
e_it!=expr_set.end(); | ||
e_it++) | ||
{ | ||
std::string value_str= | ||
from_expr(ns, identifier, *e_it); | ||
|
||
var.new_element("value").data= | ||
xmlt::escape(value_str); | ||
} | ||
#endif | ||
} | ||
} | ||
} | ||
|
||
public: | ||
// interface value_sets | ||
|
@@ -45,10 +103,12 @@ class value_set_analysist: | |
const exprt &expr, | ||
value_setst::valuest &dest) | ||
{ | ||
(*this)[l].value_set.get_value_set(expr, dest, ns); | ||
(*this)[l].value_set.get_value_set(expr, dest, baset::ns); | ||
} | ||
}; | ||
|
||
typedef value_set_analysis_baset<value_sett> value_set_analysist; | ||
|
||
void convert( | ||
const goto_functionst &goto_functions, | ||
const value_set_analysist &value_set_analysis, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function comment block missing