Skip to content

Commit 8fb6da2

Browse files
committed
Templatize and virtualize value-set analysis
This templates value-set-analysis, so that it can be subclassed providing a value-set extension, and virtualizes value-set so it can similarly be extended.
1 parent 386a3bc commit 8fb6da2

8 files changed

+112
-55
lines changed

src/pointer-analysis/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ SRC = add_failed_symbols.cpp \
1111
value_set_analysis_fivr.cpp \
1212
value_set_analysis_fivrns.cpp \
1313
value_set_dereference.cpp \
14-
value_set_domain.cpp \
1514
value_set_domain_fi.cpp \
1615
value_set_domain_fivr.cpp \
1716
value_set_domain_fivrns.cpp \

src/pointer-analysis/show_value_sets.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ Author: Daniel Kroening, [email protected]
1212
#ifndef CPROVER_POINTER_ANALYSIS_SHOW_VALUE_SETS_H
1313
#define CPROVER_POINTER_ANALYSIS_SHOW_VALUE_SETS_H
1414

15+
#include <pointer-analysis/value_set_analysis.h>
1516
#include <util/ui_message.h>
1617

1718
class goto_modelt;
18-
class value_set_analysist;
1919

2020
void show_value_sets(
2121
ui_message_handlert::uit,

src/pointer-analysis/value_set.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,12 @@ void value_sett::assign(
12051205
object_mapt values_rhs;
12061206
get_value_set(rhs, values_rhs, ns, is_simplified);
12071207

1208+
// Permit custom subclass to alter the read values prior to write:
1209+
adjust_assign_rhs_values(rhs, ns, values_rhs);
1210+
1211+
// Permit custom subclass to perform global side-effects prior to write:
1212+
apply_assign_side_effects(lhs, rhs, ns);
1213+
12081214
assign_rec(lhs, values_rhs, "", ns, add_to_sets);
12091215
}
12101216
}
@@ -1484,7 +1490,7 @@ void value_sett::do_end_function(
14841490
assign(lhs, rhs, ns, false, false);
14851491
}
14861492

1487-
void value_sett::apply_code(
1493+
void value_sett::apply_code_rec(
14881494
const codet &code,
14891495
const namespacet &ns)
14901496
{
@@ -1493,7 +1499,7 @@ void value_sett::apply_code(
14931499
if(statement==ID_block)
14941500
{
14951501
forall_operands(it, code)
1496-
apply_code(to_code(*it), ns);
1502+
apply_code_rec(to_code(*it), ns);
14971503
}
14981504
else if(statement==ID_function_call)
14991505
{

src/pointer-analysis/value_set.h

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,10 @@ class value_sett
248248

249249
void apply_code(
250250
const codet &code,
251-
const namespacet &ns);
251+
const namespacet &ns)
252+
{
253+
apply_code_rec(code, ns);
254+
}
252255

253256
void assign(
254257
const exprt &lhs,
@@ -277,13 +280,6 @@ class value_sett
277280
const namespacet &ns) const;
278281

279282
protected:
280-
void get_value_set_rec(
281-
const exprt &expr,
282-
object_mapt &dest,
283-
const std::string &suffix,
284-
const typet &original_type,
285-
const namespacet &ns) const;
286-
287283
void get_value_set(
288284
const exprt &expr,
289285
object_mapt &dest,
@@ -307,13 +303,6 @@ class value_sett
307303
const exprt &src,
308304
exprt &dest) const;
309305

310-
void assign_rec(
311-
const exprt &lhs,
312-
const object_mapt &values_rhs,
313-
const std::string &suffix,
314-
const namespacet &ns,
315-
bool add_to_sets);
316-
317306
void do_free(
318307
const exprt &op,
319308
const namespacet &ns);
@@ -322,6 +311,53 @@ class value_sett
322311
const exprt &src,
323312
const irep_idt &component_name,
324313
const namespacet &ns);
314+
315+
// Subclass customisation points:
316+
317+
protected:
318+
/// Subclass customisation point for recursion over RHS expression:
319+
virtual void get_value_set_rec(
320+
const exprt &expr,
321+
object_mapt &dest,
322+
const std::string &suffix,
323+
const typet &original_type,
324+
const namespacet &ns) const;
325+
326+
/// Subclass customisation point for recursion over LHS expression:
327+
virtual void assign_rec(
328+
const exprt &lhs,
329+
const object_mapt &values_rhs,
330+
const std::string &suffix,
331+
const namespacet &ns,
332+
bool add_to_sets);
333+
334+
/// Subclass customisation point for applying code to this domain:
335+
virtual void apply_code_rec(
336+
const codet &code,
337+
const namespacet &ns);
338+
339+
private:
340+
/// Subclass customisation point to filter or otherwise alter the value-set
341+
/// returned from get_value_set before it is passed into assign. For example,
342+
/// this is used in one subclass to tag and thus differentiate values that
343+
/// originated in a particular place, vs. those that have been copied.
344+
virtual void adjust_assign_rhs_values(
345+
const exprt &rhs,
346+
const namespacet &ns,
347+
object_mapt &rhs_values) const
348+
{
349+
}
350+
351+
/// Subclass customisation point to apply global side-effects to this domain,
352+
/// after RHS values are read but before they are written. For example, this
353+
/// is used in a recency-analysis plugin to demote existing most-recent
354+
/// objects to general case ones.
355+
virtual void apply_assign_side_effects(
356+
const exprt &lhs,
357+
const exprt &rhs,
358+
const namespacet &ns)
359+
{
360+
}
325361
};
326362

327363
#endif // CPROVER_POINTER_ANALYSIS_VALUE_SET_H

src/pointer-analysis/value_set_analysis.cpp

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,11 @@ Author: Daniel Kroening, [email protected]
1818

1919
#include <langapi/language_util.h>
2020

21-
void value_set_analysist::initialize(
22-
const goto_programt &goto_program)
23-
{
24-
baset::initialize(goto_program);
25-
}
26-
27-
void value_set_analysist::initialize(
28-
const goto_functionst &goto_functions)
29-
{
30-
baset::initialize(goto_functions);
31-
}
32-
33-
void value_set_analysist::convert(
21+
void value_sets_to_xml(
22+
std::function<const value_sett &(goto_programt::const_targett)> get_value_set,
3423
const goto_programt &goto_program,
3524
const irep_idt &identifier,
36-
xmlt &dest) const
25+
xmlt &dest)
3726
{
3827
source_locationt previous_location;
3928

@@ -48,7 +37,7 @@ void value_set_analysist::convert(
4837
continue;
4938

5039
// find value set
51-
const value_sett &value_set=(*this)[i_it].value_set;
40+
const value_sett &value_set=get_value_set(i_it);
5241

5342
xmlt &i=dest.new_element("instruction");
5443
i.new_element()=::xml(location);
@@ -81,6 +70,7 @@ void value_set_analysist::convert(
8170
}
8271
}
8372
}
73+
8474
void convert(
8575
const goto_functionst &goto_functions,
8676
const value_set_analysist &value_set_analysis,

src/pointer-analysis/value_set_analysis.h

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,37 @@ Author: Daniel Kroening, [email protected]
2020

2121
class xmlt;
2222

23-
class value_set_analysist:
23+
void value_sets_to_xml(
24+
std::function<const value_sett &(goto_programt::const_targett)> get_value_set,
25+
const goto_programt &goto_program,
26+
const irep_idt &identifier,
27+
xmlt &dest);
28+
29+
template<class VSDT>
30+
class value_set_analysis_templatet:
2431
public value_setst,
25-
public static_analysist<value_set_domaint>
32+
public static_analysist<VSDT>
2633
{
2734
public:
28-
explicit value_set_analysist(const namespacet &_ns):
29-
static_analysist<value_set_domaint>(_ns)
35+
typedef VSDT domaint;
36+
typedef static_analysist<domaint> baset;
37+
typedef typename baset::locationt locationt;
38+
39+
explicit value_set_analysis_templatet(const namespacet &ns):baset(ns)
3040
{
3141
}
3242

33-
typedef static_analysist<value_set_domaint> baset;
34-
35-
// overloading
36-
virtual void initialize(const goto_programt &goto_program);
37-
virtual void initialize(const goto_functionst &goto_functions);
38-
3943
void convert(
4044
const goto_programt &goto_program,
4145
const irep_idt &identifier,
42-
xmlt &dest) const;
46+
xmlt &dest) const
47+
{
48+
value_sets_to_xml(
49+
[this](locationt l) { return (*this)[l].value_set; },
50+
goto_program,
51+
identifier,
52+
dest);
53+
}
4354

4455
public:
4556
// interface value_sets
@@ -48,10 +59,14 @@ class value_set_analysist:
4859
const exprt &expr,
4960
value_setst::valuest &dest)
5061
{
51-
(*this)[l].value_set.get_value_set(expr, dest, ns);
62+
(*this)[l].value_set.get_value_set(expr, dest, baset::ns);
5263
}
5364
};
5465

66+
typedef
67+
value_set_analysis_templatet<value_set_domain_templatet<value_sett>>
68+
value_set_analysist;
69+
5570
void convert(
5671
const goto_functionst &goto_functions,
5772
const value_set_analysist &value_set_analysis,

src/pointer-analysis/value_set_domain.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ Author: Daniel Kroening, [email protected]
1717

1818
#include "value_set.h"
1919

20-
class value_set_domaint:public domain_baset
20+
template<class VST>
21+
class value_set_domain_templatet:public domain_baset
2122
{
2223
public:
23-
value_sett value_set;
24+
VST value_set;
2425

2526
// overloading
2627

27-
bool merge(const value_set_domaint &other, locationt to)
28+
bool merge(const value_set_domain_templatet<VST> &other, locationt to)
2829
{
2930
return value_set.make_union(other.value_set);
3031
}
@@ -58,4 +59,8 @@ class value_set_domaint:public domain_baset
5859
}
5960
};
6061

62+
typedef value_set_domain_templatet<value_sett> value_set_domaint;
63+
64+
#include "value_set_domain_transform.inc"
65+
6166
#endif // CPROVER_POINTER_ANALYSIS_VALUE_SET_DOMAIN_H

src/pointer-analysis/value_set_domain.cpp renamed to src/pointer-analysis/value_set_domain_transform.inc

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ Author: Daniel Kroening, [email protected]
99
/// \file
1010
/// Value Set
1111

12-
#include "value_set_domain.h"
12+
// The body of value_set_domaint<VST>::transform, included from
13+
// value_set_domain.h but retained in this out-of-line file to ease
14+
// git merges:
1315

14-
#include <util/std_code.h>
15-
16-
void value_set_domaint::transform(
16+
template<class VST>
17+
void value_set_domain_templatet<VST>::transform(
1718
const namespacet &ns,
1819
locationt from_l,
1920
locationt to_l)
@@ -25,9 +26,13 @@ void value_set_domaint::transform(
2526
break;
2627

2728
case END_FUNCTION:
28-
value_set.do_end_function(static_analysis_baset::get_return_lhs(to_l), ns);
29+
{
30+
value_set.do_end_function(
31+
static_analysis_baset::get_return_lhs(to_l), ns);
2932
break;
33+
}
3034

35+
// Note intentional fall-through here:
3136
case RETURN:
3237
case OTHER:
3338
case ASSIGN:
@@ -44,7 +49,8 @@ void value_set_domaint::transform(
4449
const code_function_callt &code=
4550
to_code_function_call(from_l->code);
4651

47-
value_set.do_function_call(to_l->function, code.arguments(), ns);
52+
value_set.do_function_call(
53+
to_l->function, code.arguments(), ns);
4854
}
4955
break;
5056

0 commit comments

Comments
 (0)