@@ -32,7 +32,6 @@ constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
32
32
pointer_abstract_objectt(t)
33
33
{
34
34
assert (t.id ()==ID_pointer);
35
- value=nil_exprt ();
36
35
}
37
36
38
37
/* ******************************************************************\
@@ -56,7 +55,6 @@ constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
56
55
pointer_abstract_objectt(t, tp, bttm)
57
56
{
58
57
assert (t.id ()==ID_pointer);
59
- value=nil_exprt ();
60
58
}
61
59
62
60
/* ******************************************************************\
@@ -74,7 +72,7 @@ Function: constant_pointer_abstract_objectt::constant_pointer_abstract_objectt
74
72
75
73
constant_pointer_abstract_objectt::constant_pointer_abstract_objectt (
76
74
const constant_pointer_abstract_objectt &old):
77
- pointer_abstract_objectt(old), value (old.value )
75
+ pointer_abstract_objectt(old), value_stack (old.value_stack )
78
76
{}
79
77
80
78
/* ******************************************************************\
@@ -94,26 +92,11 @@ constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
94
92
const exprt &e,
95
93
const abstract_environmentt &environment,
96
94
const namespacet &ns):
97
- pointer_abstract_objectt(e, environment, ns)
95
+ pointer_abstract_objectt(e, environment, ns),
96
+ value_stack(e, environment, ns)
98
97
{
99
98
assert (e.type ().id ()==ID_pointer);
100
- value=nil_exprt ();
101
-
102
- if (e.id ()==ID_address_of)
103
- {
104
- value=e;
105
- top=false ;
106
- }
107
- else if (e.id ()==ID_constant)
108
- {
109
- constant_exprt constant_expr (to_constant_expr (e));
110
- if (constant_expr.get_value ()==ID_NULL)
111
- {
112
- value=e;
113
- top=false ;
114
- }
115
- }
116
- // Else unknown expression type - possibly we should handle more
99
+ top=value_stack.is_top_value ();
117
100
}
118
101
119
102
/* ******************************************************************\
@@ -174,8 +157,10 @@ abstract_object_pointert
174
157
}
175
158
else
176
159
{
177
- // Can we actually merge these value
178
- if (value==other->value )
160
+ bool matching_pointer=
161
+ value_stack.to_expression ()==other->value_stack .to_expression ();
162
+
163
+ if (matching_pointer)
179
164
{
180
165
return shared_from_this ();
181
166
}
@@ -213,7 +198,7 @@ exprt constant_pointer_abstract_objectt::to_constant() const
213
198
{
214
199
// TODO(tkiley): I think we would like to eval this before using it
215
200
// in the to_constant.
216
- return value ;
201
+ return value_stack. to_expression () ;
217
202
}
218
203
}
219
204
@@ -236,33 +221,27 @@ Function: constant_pointer_abstract_objectt::output
236
221
void constant_pointer_abstract_objectt::output (
237
222
std::ostream &out, const ai_baset &ai, const namespacet &ns) const
238
223
{
239
- if (is_top () || is_bottom ())
224
+ if (is_top () || is_bottom () || value_stack. is_top_value () )
240
225
{
241
226
pointer_abstract_objectt::output (out, ai, ns);
242
227
}
243
228
else
244
229
{
245
- if (value.id ()==ID_constant && value.get (ID_value)==ID_NULL)
246
- {
247
- out << " NULL" ;
248
- }
249
- else
230
+ out << " ptr ->(" ;
231
+ const exprt &value=value_stack.to_expression ();
232
+ if (value.id ()==ID_address_of)
250
233
{
251
- out << " ptr ->( " ;
252
- if (value. id ()==ID_address_of )
234
+ const address_of_exprt & address_expr ( to_address_of_expr (value)) ;
235
+ if (address_expr. object (). id ()==ID_symbol )
253
236
{
254
- const address_of_exprt &address_expr (to_address_of_expr (value));
255
- if (address_expr.object ().id ()==ID_symbol)
256
- {
257
- const symbol_exprt &symbol_pointed_to (
258
- to_symbol_expr (address_expr.object ()));
259
-
260
- out << symbol_pointed_to.get_identifier ();
261
- }
262
- }
237
+ const symbol_exprt &symbol_pointed_to (
238
+ to_symbol_expr (address_expr.object ()));
263
239
264
- out << " )" ;
240
+ out << symbol_pointed_to.get_identifier ();
241
+ }
265
242
}
243
+
244
+ out << " )" ;
266
245
}
267
246
}
268
247
@@ -286,28 +265,16 @@ Function: constant_pointer_abstract_objectt::read_dereference
286
265
abstract_object_pointert constant_pointer_abstract_objectt::read_dereference (
287
266
const abstract_environmentt &env, const namespacet &ns) const
288
267
{
289
- if (is_top () || is_bottom () || value. id ()==ID_nil )
268
+ if (is_top () || is_bottom () || value_stack. is_top_value () )
290
269
{
291
270
// Return top if dereferencing a null pointer or we are top
292
- bool is_value_top = is_top () || value. id ()==ID_nil ;
271
+ bool is_value_top = is_top () || value_stack. is_top_value () ;
293
272
return env.abstract_object_factory (
294
273
type ().subtype (), ns, is_value_top, !is_value_top);
295
274
}
296
275
else
297
276
{
298
- if (value.id ()==ID_address_of)
299
- {
300
- return env.eval (value.op0 (), ns);
301
- }
302
- else if (value.id ()==ID_constant)
303
- {
304
- // Reading a null pointer, return top
305
- return env.abstract_object_factory (type ().subtype (), ns, true , false );
306
- }
307
- else
308
- {
309
- return env.abstract_object_factory (type ().subtype (), ns, true , false );
310
- }
277
+ return env.eval (value_stack.to_expression ().op0 (), ns);
311
278
}
312
279
}
313
280
@@ -344,22 +311,13 @@ sharing_ptrt<pointer_abstract_objectt>
344
311
const abstract_object_pointert new_value,
345
312
bool merging_write) const
346
313
{
347
- if (is_top () || is_bottom ())
314
+ if (is_top () || is_bottom () || value_stack. is_top_value () )
348
315
{
349
316
return pointer_abstract_objectt::write_dereference (
350
317
environment, ns, stack, new_value, merging_write);
351
318
}
352
319
else
353
320
{
354
- // If not an address, we don't know what we are pointing to
355
- if (value.id ()!=ID_address_of)
356
- {
357
- return pointer_abstract_objectt::write_dereference (
358
- environment, ns, stack, new_value, merging_write);
359
- }
360
-
361
- const address_of_exprt &address_expr=to_address_of_expr (value);
362
-
363
321
sharing_ptrt<constant_pointer_abstract_objectt> copy=
364
322
sharing_ptrt<constant_pointer_abstract_objectt>(
365
323
new constant_pointer_abstract_objectt (*this ));
@@ -369,26 +327,30 @@ sharing_ptrt<pointer_abstract_objectt>
369
327
// We should not be changing the type of an abstract object
370
328
assert (new_value->type ()==type ().subtype ());
371
329
372
-
330
+ // Get an expression that we can assign to
331
+ exprt value=value_stack.to_expression ().op0 ();
373
332
if (merging_write)
374
333
{
375
334
abstract_object_pointert pointed_value=
376
- environment.eval (address_expr. object () , ns);
335
+ environment.eval (value , ns);
377
336
bool modifications;
378
337
abstract_object_pointert merged_value=
379
338
abstract_objectt::merge (pointed_value, new_value, modifications);
380
- environment.assign (address_expr. object () , merged_value, ns);
339
+ environment.assign (value , merged_value, ns);
381
340
}
382
341
else
383
342
{
384
- environment.assign (address_expr. object () , new_value, ns);
343
+ environment.assign (value , new_value, ns);
385
344
}
386
345
}
387
346
else
388
347
{
348
+ exprt value=value_stack.to_expression ().op0 ();
389
349
abstract_object_pointert pointed_value=
390
- environment.eval (address_expr.object (), ns);
391
- environment.write (pointed_value, new_value, stack, ns, merging_write);
350
+ environment.eval (value, ns);
351
+ abstract_object_pointert modified_value=
352
+ environment.write (pointed_value, new_value, stack, ns, merging_write);
353
+ environment.assign (value, modified_value, ns);
392
354
393
355
// but the pointer itself does not change!
394
356
}
0 commit comments