Skip to content

Commit 3824dbd

Browse files
author
thk123
committed
Changed the pointer abstract object to store an expression
Before there was a problem where if we stored an abstract object that get modified, as this would cause a copy, the pointer would point at the old value. To resolve, just store an expression representing what it is pointing to. This can then be re-evaluated by the enviroment to find its current possible values.
1 parent 0ed9592 commit 3824dbd

7 files changed

+80
-43
lines changed

src/analyses/variable-sensitivity/abstract_enviroment.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ abstract_object_pointert abstract_environmentt::eval(
9393
std::dynamic_pointer_cast<pointer_abstract_objectt>(
9494
eval(dereference.pointer(), ns));
9595

96-
return pointer_abstract_object->read_dereference(*this);
96+
return pointer_abstract_object->read_dereference(*this, ns);
9797
}
9898
},
9999
{
@@ -139,6 +139,7 @@ Function: abstract_environmentt::assign
139139
Inputs:
140140
expr - the expression to assign to
141141
value - the value to assign to the expression
142+
ns - the namespace
142143
143144
Outputs: ?
144145
@@ -147,7 +148,7 @@ Function: abstract_environmentt::assign
147148
\*******************************************************************/
148149

149150
bool abstract_environmentt::assign(
150-
const exprt &expr, const abstract_object_pointert value)
151+
const exprt &expr, const abstract_object_pointert value, const namespacet &ns)
151152
{
152153
assert(value);
153154

@@ -188,7 +189,7 @@ bool abstract_environmentt::assign(
188189
{
189190
symbol_object=map[symbol_expr];
190191
}
191-
final_value=write(symbol_object, value, stactions, false);
192+
final_value=write(symbol_object, value, stactions, ns, false);
192193
}
193194
else
194195
{
@@ -218,6 +219,7 @@ Function: abstract_object_pointert abstract_environmentt::write
218219
rhs - the value we are trying to write to the left hand side
219220
remaining_stack - what is left of the stack before the rhs can replace or be
220221
merged with the rhs
222+
ns - the namespace
221223
merge_write - Are re replacing the left hand side with the right hand side
222224
(e.g. we know for a fact that we are overwriting this object)
223225
or could the write in fact not take place and therefore we
@@ -231,10 +233,12 @@ Function: abstract_object_pointert abstract_environmentt::write
231233
abstract_pointer and abstract_array until the stack is empty
232234
233235
\*******************************************************************/
236+
234237
abstract_object_pointert abstract_environmentt::write(
235238
abstract_object_pointert lhs,
236239
abstract_object_pointert rhs,
237240
std::stack<exprt> remaining_stack,
241+
const namespacet &ns,
238242
bool merge_write)
239243
{
240244
assert(!remaining_stack.empty());
@@ -307,7 +311,7 @@ abstract_object_pointert abstract_environmentt::write(
307311

308312
sharing_ptrt<pointer_abstract_objectt> modified_pointer=
309313
pointer_abstract_object->write_dereference(
310-
*this, stack, rhs_object, merge_write);
314+
*this, ns, stack, rhs_object, merge_write);
311315

312316
return modified_pointer;
313317
}

src/analyses/variable-sensitivity/abstract_enviroment.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,18 @@ class abstract_environmentt
2222
// These three are really the heart of the method
2323
virtual abstract_object_pointert eval(
2424
const exprt &expr, const namespacet &ns) const;
25-
virtual bool assign(const exprt &expr, const abstract_object_pointert value);
25+
virtual bool assign(
26+
const exprt &expr,
27+
const abstract_object_pointert value,
28+
const namespacet &ns);
2629
virtual bool assume(const exprt &expr, const namespacet &ns);
2730

28-
virtual abstract_object_pointert write(abstract_object_pointert lhs,
29-
abstract_object_pointert rhs,
30-
std::stack<exprt> remaining_stack,
31-
bool merge_write);
31+
virtual abstract_object_pointert write(
32+
abstract_object_pointert lhs,
33+
abstract_object_pointert rhs,
34+
std::stack<exprt> remaining_stack,
35+
const namespacet &ns,
36+
bool merge_write);
3237

3338
virtual abstract_object_pointert abstract_object_factory(
3439
const typet type, bool top=true, bool bottom=false) const;

src/analyses/variable-sensitivity/constant_pointer_abstract_object.cpp

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <analyses/variable-sensitivity/abstract_enviroment.h>
1111
#include <util/std_types.h>
1212
#include <util/std_expr.h>
13+
#include <analyses/ai.h>
1314
#include "constant_pointer_abstract_object.h"
1415

1516
/*******************************************************************\
@@ -30,7 +31,7 @@ constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
3031
pointer_abstract_objectt(t)
3132
{
3233
assert(t.id()==ID_pointer);
33-
value=enviroment.abstract_object_factory(t.subtype(), true, false);
34+
value=nil_exprt();
3435
}
3536

3637
/*******************************************************************\
@@ -54,7 +55,7 @@ constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
5455
pointer_abstract_objectt(t, tp, bttm)
5556
{
5657
assert(t.id()==ID_pointer);
57-
value=enviroment.abstract_object_factory(t.subtype(), top, bottom);
58+
value=nil_exprt();
5859
}
5960

6061
/*******************************************************************\
@@ -100,8 +101,8 @@ constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
100101
// can create a pointer
101102
if(e.id()==ID_address_of)
102103
{
103-
address_of_exprt address_expr(to_address_of_expr(e));
104-
value=enviroment.eval(address_expr.object(), ns);
104+
//address_of_exprt address_expr(to_address_of_expr(e));
105+
value=e;
105106
top=false;
106107
}
107108
else
@@ -111,19 +112,19 @@ constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
111112
constant_exprt constant_expr(to_constant_expr(e));
112113
if(constant_expr.get_value()==ID_NULL)
113114
{
114-
value=nullptr;
115+
value=e;
115116
top=false;
116117
}
117118
else
118119
{
119120
// TODO(tkiley): These should probably be logged.
120121
// unknown type
121-
value=enviroment.abstract_object_factory(type.subtype(), true, false);
122+
value=nil_exprt();
122123
}
123124
}
124125
else
125126
{
126-
value=enviroment.abstract_object_factory(type.subtype(), true, false);
127+
value=nil_exprt();
127128
}
128129
}
129130
}
@@ -163,7 +164,7 @@ bool constant_pointer_abstract_objectt::merge_state(
163164
else
164165
{
165166
top=true;
166-
value=nullptr;
167+
value=nil_exprt();
167168
assert(!bottom);
168169
return !op1->top;
169170
}
@@ -195,16 +196,9 @@ exprt constant_pointer_abstract_objectt::to_constant() const
195196
}
196197
else
197198
{
198-
if(value==nullptr)
199-
{
200-
return null_pointer_exprt(to_pointer_type(type));
201-
}
202-
else
203-
{
204-
const exprt &value_expr=value->to_constant();
205-
address_of_exprt address_expr(value_expr);
206-
return address_expr;
207-
}
199+
// TODO(tkiley): I think we would like to eval this before using it
200+
// in the to_constant.
201+
return value;
208202
}
209203
}
210204

@@ -233,14 +227,25 @@ void constant_pointer_abstract_objectt::output(
233227
}
234228
else
235229
{
236-
if(value==nullptr)
230+
if(value.id()==ID_constant && value.get(ID_value)==ID_NULL)
237231
{
238232
out << "NULL";
239233
}
240234
else
241235
{
242236
out << "ptr ->(";
243-
value->output(out, ai, ns);
237+
if(value.id()==ID_address_of)
238+
{
239+
const address_of_exprt &address_expr(to_address_of_expr(value));
240+
if(address_expr.object().id()==ID_symbol)
241+
{
242+
const symbol_exprt &symbol_pointed_to(
243+
to_symbol_expr(address_expr.object()));
244+
245+
out << symbol_pointed_to.get_identifier();
246+
}
247+
}
248+
244249
out << ")";
245250
}
246251
}
@@ -252,6 +257,7 @@ Function: constant_pointer_abstract_objectt::read_dereference
252257
253258
Inputs:
254259
env - the environment
260+
ns - the namespace
255261
256262
Outputs: An abstract object representing the value this pointer is pointing
257263
to
@@ -263,18 +269,30 @@ Function: constant_pointer_abstract_objectt::read_dereference
263269
\*******************************************************************/
264270

265271
abstract_object_pointert constant_pointer_abstract_objectt::read_dereference(
266-
const abstract_environmentt &env) const
272+
const abstract_environmentt &env, const namespacet &ns) const
267273
{
268-
if(top || bottom || value==nullptr)
274+
if(top || bottom || value.id()==ID_nil)
269275
{
270276
// Return top if dereferencing a null pointer or we are top
271-
bool is_value_top = top || value==nullptr;
277+
bool is_value_top = top || value.id()==ID_nil;
272278
return env.abstract_object_factory(
273279
type.subtype(), is_value_top, !is_value_top);
274280
}
275281
else
276282
{
277-
return value;
283+
if(value.id()==ID_address_of)
284+
{
285+
return env.eval(value.op0(), ns);
286+
}
287+
else if(value.id()==ID_constant)
288+
{
289+
// Reading a null pointer, return top
290+
return env.abstract_object_factory(type.subtype(), true, false);
291+
}
292+
else
293+
{
294+
return env.abstract_object_factory(type.subtype(), true, false);
295+
}
278296
}
279297
}
280298

@@ -284,6 +302,7 @@ Function: constant_pointer_abstract_objectt::write_dereference
284302
285303
Inputs:
286304
environment - the environment
305+
ns - the namespace
287306
stack - the remaining stack
288307
new_value - the value to write to the dereferenced pointer
289308
merging_write - is it a merging write (i.e. we aren't certain
@@ -305,14 +324,15 @@ Function: constant_pointer_abstract_objectt::write_dereference
305324
sharing_ptrt<pointer_abstract_objectt>
306325
constant_pointer_abstract_objectt::write_dereference(
307326
abstract_environmentt &environment,
327+
const namespacet &ns,
308328
const std::stack<exprt> stack,
309329
const abstract_object_pointert new_value,
310330
bool merging_write)
311331
{
312332
if(top || bottom)
313333
{
314334
return pointer_abstract_objectt::write_dereference(
315-
environment, stack, new_value, merging_write);
335+
environment, ns, stack, new_value, merging_write);
316336
}
317337
else
318338
{
@@ -324,19 +344,21 @@ sharing_ptrt<pointer_abstract_objectt>
324344

325345
if(merging_write)
326346
{
347+
abstract_object_pointert pointed_value=environment.eval(value, ns);
327348
bool modifications;
328-
copy->value=value->merge(new_value, modifications);
349+
pointed_value->merge(new_value, modifications);
329350
}
330351
else
331352
{
332-
copy->value=new_value;
353+
environment.assign(value, new_value, ns);
333354
}
334355
return copy;
335356
}
336357
else
337358
{
359+
abstract_object_pointert pointed_value=environment.eval(value, ns);
338360
return std::dynamic_pointer_cast<constant_pointer_abstract_objectt>(
339-
environment.write(value, new_value, stack, merging_write));
361+
environment.write(pointed_value, new_value, stack, ns, merging_write));
340362
}
341363
}
342364
}

src/analyses/variable-sensitivity/constant_pointer_abstract_object.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,17 @@ class constant_pointer_abstract_objectt:public pointer_abstract_objectt
4343
void output(std::ostream &out, const ai_baset &ai, const namespacet &ns);
4444

4545
abstract_object_pointert read_dereference(
46-
const abstract_environmentt &env) const;
46+
const abstract_environmentt &env, const namespacet &ns) const;
4747

4848
sharing_ptrt<pointer_abstract_objectt> write_dereference(
4949
abstract_environmentt &environment,
50+
const namespacet &ns,
5051
const std::stack<exprt> stack,
5152
const abstract_object_pointert value,
5253
bool merging_write);
5354

5455
private:
55-
abstract_object_pointert value;
56+
exprt value;
5657

5758

5859
};

src/analyses/variable-sensitivity/pointer_abstract_object.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ Function: pointer_abstract_objectt::read_dereference
9898
9999
Inputs:
100100
env - the environment
101+
ns - the namespace
101102
102103
Outputs: An abstract object representing the value being pointed to
103104
@@ -107,7 +108,7 @@ Function: pointer_abstract_objectt::read_dereference
107108
\*******************************************************************/
108109

109110
abstract_object_pointert pointer_abstract_objectt::read_dereference(
110-
const abstract_environmentt &env) const
111+
const abstract_environmentt &env, const namespacet &ns) const
111112
{
112113
pointer_typet pointer_type(to_pointer_type(type));
113114
const typet &pointed_to_type=pointer_type.subtype();
@@ -121,6 +122,7 @@ Function: pointer_abstract_objectt::write_dereference
121122
122123
Inputs:
123124
environment - the abstract environment
125+
ns - the namespace
124126
stack - the remaining stack of expressions on the LHS to evaluate
125127
value - the value we are trying to assign to what the pointer is
126128
pointing to
@@ -141,6 +143,7 @@ Function: pointer_abstract_objectt::write_dereference
141143
sharing_ptrt<pointer_abstract_objectt>
142144
pointer_abstract_objectt::write_dereference(
143145
abstract_environmentt &environment,
146+
const namespacet &ns,
144147
const std::stack<exprt> stack,
145148
const abstract_object_pointert value,
146149
bool merging_write)

src/analyses/variable-sensitivity/pointer_abstract_object.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ class pointer_abstract_objectt:public abstract_objectt
3030

3131
// pointer interface
3232
virtual abstract_object_pointert read_dereference(
33-
const abstract_environmentt &env) const;
33+
const abstract_environmentt &env, const namespacet &ns) const;
3434

3535
virtual sharing_ptrt<pointer_abstract_objectt> write_dereference(
3636
abstract_environmentt &environment,
37+
const namespacet &ns,
3738
const std::stack<exprt> stack,
3839
const abstract_object_pointert value,
3940
bool merging_write);

src/analyses/variable-sensitivity/variable_sensitivity_domain.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ void variable_sensitivity_domaint::transform(
5454
abstract_object_pointert top_object=
5555
abstract_state.abstract_object_factory(
5656
to_code_dead(instruction.code).symbol().type(), true);
57-
abstract_state.assign(to_code_dead(instruction.code).symbol(), top_object);
57+
abstract_state.assign(
58+
to_code_dead(instruction.code).symbol(), top_object, ns);
5859
}
5960
break;
6061

@@ -64,7 +65,7 @@ void variable_sensitivity_domaint::transform(
6465

6566
// TODO : check return values
6667
abstract_object_pointert r = abstract_state.eval(inst.rhs(), ns);
67-
abstract_state.assign(inst.lhs(), r);
68+
abstract_state.assign(inst.lhs(), r, ns);
6869
}
6970
break;
7071

0 commit comments

Comments
 (0)