CBMC
instrument_spec_assigns.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Instrument assigns clauses in code contracts.
4 
5 Author: Remi Delmas
6 
7 Date: January 2022
8 
9 \*******************************************************************/
10 
13 
15 
16 #include <util/arith_tools.h>
17 #include <util/c_types.h>
18 #include <util/expr_util.h>
19 #include <util/format_expr.h>
22 #include <util/simplify_expr.h>
23 
24 #include <langapi/language_util.h>
25 
26 #include "cfg_info.h"
27 #include "utils.h"
28 
30 static const char LOG_HEADER[] = "assigns clause checking: ";
31 
33 static const char PROPAGATE_STATIC_LOCAL_PRAGMA[] =
34  "contracts:propagate-static-local";
35 
37 {
38  const auto &pragmas = source_location.get_pragmas();
39  return pragmas.find(PROPAGATE_STATIC_LOCAL_PRAGMA) != pragmas.end();
40 }
41 
43 {
45 }
46 
49  "contracts:disable:assigns-check";
50 
52 {
53  location.add_pragma("disable:pointer-check");
54  location.add_pragma("disable:pointer-primitive-check");
55  location.add_pragma("disable:pointer-overflow-check");
56  location.add_pragma("disable:signed-overflow-check");
57  location.add_pragma("disable:unsigned-overflow-check");
58  location.add_pragma("disable:conversion-check");
59 }
60 
64  const goto_programt::const_targett &target)
65 {
66  const auto &pragmas = target->source_location().get_pragmas();
67  return pragmas.find(CONTRACT_PRAGMA_DISABLE_ASSIGNS_CHECK) != pragmas.end();
68 }
69 
71 {
73 }
74 
77 {
79  return instr;
80 }
81 
83 {
86  return prog;
87 }
88 
90  const exprt &expr,
91  goto_programt &dest)
92 {
93  if(auto target = expr_try_dynamic_cast<conditional_target_group_exprt>(expr))
94  track_spec_target_group(*target, dest);
95  else
96  track_plain_spec_target(expr, dest);
97 }
98 
100  const symbol_exprt &symbol_expr,
101  goto_programt &dest)
102 {
103  create_snapshot(create_car_from_stack_alloc(symbol_expr), dest);
104 }
105 
107  const symbol_exprt &symbol_expr) const
108 {
109  return from_stack_alloc.find(symbol_expr) != from_stack_alloc.end();
110 }
111 
113  const symbol_exprt &symbol_expr,
114  goto_programt &dest)
115 {
116  // ensure it is tracked
118  stack_allocated_is_tracked(symbol_expr),
119  "symbol is not tracked :" + from_expr(ns, "", symbol_expr));
120 
121  const auto &car = from_stack_alloc.find(symbol_expr)->second;
122 
123  source_locationt source_location(symbol_expr.source_location());
124  add_pragma_disable_pointer_checks(source_location);
125  add_pragma_disable_assigns_check(source_location);
126 
128  car.valid_var(), false_exprt{}, source_location));
129 }
130 
132  const exprt &expr,
133  goto_programt &dest)
134 {
135  // insert in tracking set
136  const auto &car = create_car_from_heap_alloc(expr);
137 
138  // generate target validity check for this target.
139  target_validity_assertion(car, true, dest);
140 
141  // generate snapshot instructions for this target.
142  create_snapshot(car, dest);
143 }
144 
146  const exprt &lhs,
147  goto_programt &dest) const
148 {
149  // create temporary car but do not track
150  const auto car = create_car_expr(true_exprt{}, lhs);
151  create_snapshot(car, dest);
152  inclusion_check_assertion(car, false, true, dest);
153 }
154 
156 {
157  const auto &found = functions.function_map.find(function_id);
158  INVARIANT(
159  found != functions.function_map.end(),
160  "the instrumented function must exist in the model");
161  const goto_programt &body = found->second.body;
162 
163  propagated_static_localst propagated;
164  covered_locationst covered_locations;
165  covered_locations[function_id].anywhere();
167  function_id,
168  body.instructions.begin(),
169  body.instructions.end(),
170  covered_locations,
171  propagated);
172 
173  std::unordered_set<symbol_exprt, irep_hash> symbols;
174  collect_static_symbols(covered_locations, symbols);
175 
176  for(const auto &expr : propagated)
178 
179  for(const auto &sym : symbols)
181 }
182 
186  goto_programt &dest)
187 {
188  propagated_static_localst propagated;
189  covered_locationst covered_locations;
190  traverse_instructions(function_id, it, end, covered_locations, propagated);
191 
192  std::unordered_set<symbol_exprt, irep_hash> symbols;
193  collect_static_symbols(covered_locations, symbols);
194 
195  for(const auto &sym : symbols)
197 
198  for(const auto &expr : propagated)
200 }
201 
203  const irep_idt ambient_function_id,
206  covered_locationst &covered_locations,
207  propagated_static_localst &propagated) const
208 {
209  for(; it != end; it++)
210  {
211  const auto &loc = it->source_location();
212  const auto &loc_fun = loc.get_function();
213  if(!loc_fun.empty())
214  {
215  auto &itv = covered_locations[loc_fun];
216  if(loc_fun == ambient_function_id)
217  {
218  itv.update(loc);
219  }
220  else
221  {
222  // we are on an instruction coming from some other function that the
223  // ambient function so we assume that the whole function was inlined
224  itv.anywhere();
225  }
226  }
227  else
228  {
229  log.debug() << "Ignoring instruction without function attribute"
230  << messaget::eom;
231  // ignore instructions with a source_location that
232  // have no function attribute
233  }
234 
235  // Collect assignments marked as "propagate static local"
236  // (these are generated by havoc_assigns_clause_targett)
238  {
239  INVARIANT(
240  it->is_assign() && can_cast_expr<symbol_exprt>(it->assign_lhs()) &&
241  can_cast_expr<side_effect_expr_nondett>(it->assign_rhs()),
242  "Expected an assignment of the form `symbol_exprt := "
243  "side_effect_expr_nondett`");
244  // must be a nondet assignment to a symbol
245  propagated.insert(to_symbol_expr(it->assign_lhs()));
246  }
247 
248  // recurse into bodies of called functions if available
249  if(it->is_function_call())
250  {
251  const auto &fun_expr = it->call_function();
252 
254  fun_expr.id() == ID_symbol,
255  "Local static search requires function pointer removal");
256  const irep_idt &fun_id = to_symbol_expr(fun_expr).get_identifier();
257 
258  const auto &found = functions.function_map.find(fun_id);
259  INVARIANT(
260  found != functions.function_map.end(),
261  "Function " + id2string(fun_id) + "not in function map");
262 
263  // do not recurse if the function was already seen before
264  if(covered_locations.find(fun_id) == covered_locations.end())
265  {
266  // consider all locations of this function covered
267  covered_locations[fun_id].anywhere();
268  const goto_programt &body = found->second.body;
269  if(!body.empty())
270  {
272  fun_id,
273  body.instructions.begin(),
274  body.instructions.end(),
275  covered_locations,
276  propagated);
277  }
278  }
279  }
280  }
281 }
282 
284  covered_locationst &covered_locations,
285  std::unordered_set<symbol_exprt, irep_hash> &dest)
286 {
287  for(const auto &sym_pair : st)
288  {
289  const auto &sym = sym_pair.second;
290  if(sym.is_static_lifetime)
291  {
292  const auto &loc = sym.location;
293  if(!loc.get_function().empty())
294  {
295  const auto &itv = covered_locations.find(loc.get_function());
296  if(itv != covered_locations.end() && itv->second.contains(sym.location))
297  dest.insert(sym.symbol_expr());
298  }
299  }
300  }
301 }
302 
305  const exprt &expr,
306 
307  goto_programt &dest)
308 {
309  // create temporary car but do not track
310  const auto car = create_car_expr(true_exprt{}, expr);
311 
312  // generate snapshot instructions for this target.
313  create_snapshot(car, dest);
314 
315  // check inclusion, allowing null and not allowing stack allocated locals
316  inclusion_check_assertion(car, true, false, dest);
317 
318  // invalidate aliases of the freed object
320 }
321 
323  goto_programt &body,
324  goto_programt::targett instruction_it,
325  const goto_programt::targett &instruction_end,
326  const std::function<bool(const goto_programt::targett &)> &pred)
327 {
328  while(instruction_it != instruction_end)
329  {
330  // Skip instructions marked as disabled for assigns clause checking
331  if(
332  has_disable_assigns_check_pragma(instruction_it) ||
333  (pred && !pred(instruction_it)))
334  {
335  instruction_it++;
336  continue;
337  }
338 
339  // Do not instrument this instruction again in the future,
340  // since we are going to instrument it now below.
341  add_pragma_disable_assigns_check(*instruction_it);
342 
343  if(instruction_it->is_decl() && must_track_decl(instruction_it))
344  {
345  // grab the declared symbol
346  const auto &decl_symbol = instruction_it->decl_symbol();
347  // move past the call and then insert the CAR
348  instruction_it++;
349  goto_programt payload;
350  track_stack_allocated(decl_symbol, payload);
351  insert_before_swap_and_advance(body, instruction_it, payload);
352  // since CAR was inserted *after* the DECL instruction,
353  // move the instruction pointer backward,
354  // because the enclosing while loop step takes
355  // care of the increment
356  instruction_it--;
357  }
358  else if(instruction_it->is_assign() && must_check_assign(instruction_it))
359  {
360  instrument_assign_statement(instruction_it, body);
361  }
362  else if(instruction_it->is_function_call())
363  {
364  instrument_call_statement(instruction_it, body);
365  }
366  else if(instruction_it->is_dead() && must_track_dead(instruction_it))
367  {
368  const auto &symbol = instruction_it->dead_symbol();
369  if(stack_allocated_is_tracked(symbol))
370  {
371  goto_programt payload;
372  invalidate_stack_allocated(symbol, payload);
373  insert_before_swap_and_advance(body, instruction_it, payload);
374  }
375  else
376  {
377  // Some variables declared outside of the loop
378  // can go `DEAD` (possible conditionally) when return
379  // statements exist inside the loop body.
380  // Since they are not DECL'd inside the loop, these locations
381  // are not automatically tracked in the stack_allocated map,
382  // so to be writable these variables must be listed in the assigns
383  // clause.
384  log.warning() << "Found a `DEAD` variable " << symbol.get_identifier()
385  << " without corresponding `DECL`, at: "
386  << instruction_it->source_location() << messaget::eom;
387  }
388  }
389  else if(
390  instruction_it->is_other() &&
391  instruction_it->get_other().get_statement() == ID_havoc_object)
392  {
393  auto havoc_argument = instruction_it->get_other().operands().front();
394  auto havoc_object = pointer_object(havoc_argument);
395  havoc_object.add_source_location() = instruction_it->source_location();
396  goto_programt payload;
397  check_inclusion_assignment(havoc_object, payload);
398  insert_before_swap_and_advance(body, instruction_it, payload);
399  }
400 
401  // Move to the next instruction
402  instruction_it++;
403  }
404 }
405 
407  const conditional_target_group_exprt &group,
408  goto_programt &dest)
409 {
410  // clean up side effects from the guard expression if needed
411  cleanert cleaner(st, log.get_message_handler());
412  exprt condition(group.condition());
413  if(has_subexpr(condition, ID_side_effect))
414  cleaner.clean(condition, dest, mode);
415 
416  // create conditional address ranges by distributing the condition
417  for(const auto &target : group.targets())
418  {
419  // insert in tracking set
420  const auto &car = create_car_from_spec_assigns(condition, target);
421 
422  // generate target validity check for this target.
423  target_validity_assertion(car, true, dest);
424 
425  // generate snapshot instructions for this target.
426  create_snapshot(car, dest);
427  }
428 }
429 
431  const exprt &expr,
432  goto_programt &dest)
433 {
434  // insert in tracking set
435  const auto &car = create_car_from_spec_assigns(true_exprt{}, expr);
436 
437  // generate target validity check for this target.
438  target_validity_assertion(car, true, dest);
439 
440  // generate snapshot instructions for this target.
441  create_snapshot(car, dest);
442 }
443 
445  const std::string &suffix,
446  const typet &type,
447  const source_locationt &location) const
448 {
449  return new_tmp_symbol(type, location, mode, st, suffix);
450 }
451 
453  const exprt &condition,
454  const exprt &target) const
455 {
456  const source_locationt &source_location = target.source_location();
457  const auto &valid_var =
458  create_fresh_symbol("__car_valid", bool_typet(), source_location)
459  .symbol_expr();
460 
461  const auto &lower_bound_var =
462  create_fresh_symbol("__car_lb", pointer_type(char_type()), source_location)
463  .symbol_expr();
464 
465  const auto &upper_bound_var =
466  create_fresh_symbol("__car_ub", pointer_type(char_type()), source_location)
467  .symbol_expr();
468 
469  if(target.id() == ID_pointer_object)
470  {
471  const auto &arg = to_pointer_object_expr(target).pointer();
472  return {
473  condition,
474  target,
475  minus_exprt(
477  pointer_offset(arg)),
479  valid_var,
480  lower_bound_var,
481  upper_bound_var,
483  }
485  {
486  const auto &funcall = to_side_effect_expr_function_call(target);
487  if(can_cast_expr<symbol_exprt>(funcall.function()))
488  {
489  const auto &ident = to_symbol_expr(funcall.function()).get_identifier();
490  if(ident == CPROVER_PREFIX "object_from")
491  {
492  const auto &ptr = funcall.arguments().at(0);
493  return {
494  condition,
495  target,
496  // lb = ptr
498  // size = object_size(ptr) - pointer_offset(ptr)
500  minus_exprt{
502  object_size(ptr), signed_size_type()),
503  pointer_offset(ptr)},
504  size_type()),
505  valid_var,
506  lower_bound_var,
507  upper_bound_var,
509  }
510  else if(ident == CPROVER_PREFIX "object_upto")
511  {
512  const auto &ptr = funcall.arguments().at(0);
513  const auto &size = funcall.arguments().at(1);
514  return {
515  condition,
516  target,
517  // lb = ptr
519  // size = size
521  valid_var,
522  lower_bound_var,
523  upper_bound_var,
525  }
526  else if(ident == CPROVER_PREFIX "object_whole")
527  {
528  const auto &ptr = funcall.arguments().at(0);
529  return {
530  condition,
531  target,
532  // lb = ptr - pointer_offset(ptr)
533  minus_exprt(
535  pointer_offset(ptr)),
536  // size = object_size(ptr)
538  valid_var,
539  lower_bound_var,
540  upper_bound_var,
542  }
543  else if(ident == CPROVER_PREFIX "assignable")
544  {
545  const auto &ptr = funcall.arguments().at(0);
546  const auto &size = funcall.arguments().at(1);
547  const auto &is_ptr_to_ptr = funcall.arguments().at(2);
548  return {
549  condition,
550  target,
551  // lb = ptr
553  // size = size
555  valid_var,
556  lower_bound_var,
557  upper_bound_var,
558  is_ptr_to_ptr.is_true() ? car_havoc_methodt::NONDET_ASSIGN
560  }
561  else
562  {
564  log.error() << "call to " << ident
565  << " in assigns clauses not supported in this version";
566  }
567  }
568  }
569  else if(is_assignable(target))
570  {
571  const auto &size = size_of_expr(target.type(), ns);
572 
573  INVARIANT(
574  size.has_value(),
575  "no definite size for lvalue target:\n" + target.pretty());
576 
577  return {
578  condition,
579  target,
580  // lb = &target
583  // size = sizeof(target)
585  valid_var,
586  lower_bound_var,
587  upper_bound_var,
589  }
590 
591  UNREACHABLE;
592 }
593 
595  const car_exprt &car,
596  goto_programt &dest) const
597 {
598  source_locationt source_location(car.source_location());
599  add_pragma_disable_pointer_checks(source_location);
600  add_pragma_disable_assigns_check(source_location);
601 
602  dest.add(goto_programt::make_decl(car.valid_var(), source_location));
603 
605  car.valid_var(),
607  and_exprt{car.condition(),
609  ns),
610  source_location));
611 
612  dest.add(goto_programt::make_decl(car.lower_bound_var(), source_location));
613 
615  car.lower_bound_var(), car.target_start_address(), source_location));
616 
617  dest.add(goto_programt::make_decl(car.upper_bound_var(), source_location));
618 
620  car.upper_bound_var(),
623  source_location));
624 }
625 
627  const car_exprt &car,
628  bool allow_null_target) const
629 {
630  // If requested, we check that when guard condition is true,
631  // the target's `start_address` pointer satisfies w_ok with the expected size
632  // (or is NULL if we allow it explicitly).
633  // This assertion will be falsified whenever `start_address` is invalid or
634  // not of the right size (or is NULL if we do not allow it explicitly).
635  auto result =
638 
639  if(allow_null_target)
641 
642  return simplify_expr(result, ns);
643 }
644 
646  const car_exprt &car,
647  bool allow_null_target,
648  goto_programt &dest) const
649 {
650  // since assigns clauses are declared outside of their function body
651  // their source location might not have a function attribute
652  source_locationt source_location(car.source_location());
653  if(source_location.get_function().empty())
654  source_location.set_function(function_id);
655 
656  source_location.set_property_class("assigns");
657 
658  add_pragma_disable_pointer_checks(source_location);
659  add_pragma_disable_assigns_check(source_location);
660 
661  std::string comment = "Check that ";
662  comment += from_expr(ns, "", car.target());
663  comment += " is valid";
664  if(!car.condition().is_true())
665  {
666  comment += " when ";
667  comment += from_expr(ns, "", car.condition());
668  }
669 
670  source_location.set_comment(comment);
671 
673  target_validity_expr(car, allow_null_target), source_location));
674 }
675 
677  const car_exprt &car,
678  bool allow_null_lhs,
679  bool include_stack_allocated,
680  goto_programt &dest) const
681 {
682  source_locationt source_location(car.source_location());
683 
684  // since assigns clauses are declared outside of their function body
685  // their source location might not have a function attribute
686  if(source_location.get_function().empty())
687  source_location.set_function(function_id);
688 
689  add_pragma_disable_pointer_checks(source_location);
690  add_pragma_disable_assigns_check(source_location);
691 
692  source_location.set_property_class("assigns");
693 
694  const auto &orig_comment = source_location.get_comment();
695  std::string comment = "Check that ";
697  {
698  if(!car.condition().is_true())
699  comment += from_expr(ns, "", car.condition()) + ": ";
700  comment += from_expr(ns, "", car.target());
701  }
702  else
703  comment += id2string(orig_comment);
704 
705  comment += " is assignable";
706  source_location.set_comment(comment);
707 
709  inclusion_check_full(car, allow_null_lhs, include_stack_allocated),
710  source_location));
711 }
712 
714  const car_exprt &car,
715  const car_exprt &candidate_car) const
716 {
717  // remark: both lb and ub are derived from the same object so checking
718  // same_object(upper_bound_address_var, lhs.upper_bound_address_var)
719  // is redundant
720  return simplify_expr(
721  and_exprt{
722  {candidate_car.valid_var(),
723  same_object(candidate_car.lower_bound_var(), car.lower_bound_var()),
724  less_than_or_equal_exprt{pointer_offset(candidate_car.lower_bound_var()),
725  pointer_offset(car.lower_bound_var())},
727  pointer_offset(car.upper_bound_var()),
728  pointer_offset(candidate_car.upper_bound_var())}}},
729  ns);
730 }
731 
733  const car_exprt &car,
734  bool allow_null_lhs,
735  bool include_stack_allocated) const
736 {
737  bool no_targets = from_spec_assigns.empty() && from_heap_alloc.empty() &&
738  (!include_stack_allocated ||
739  (from_static_local.empty() && from_stack_alloc.empty()));
740 
741  // inclusion check expression
742  if(no_targets)
743  {
744  // if null lhs are allowed then we should have a null lhs when
745  // we reach this program point, otherwise we should never reach
746  // this program point
747  if(allow_null_lhs)
748  return null_pointer(car.target_start_address());
749  else
750  return false_exprt{};
751  }
752 
753  // Build a disjunction over all tracked locations
754  exprt::operandst disjuncts;
755  log.debug() << LOG_HEADER << " inclusion check: \n"
756  << from_expr_using_mode(ns, mode, car.target()) << " in {"
757  << messaget::eom;
758 
759  for(const auto &pair : from_spec_assigns)
760  {
761  disjuncts.push_back(inclusion_check_single(car, pair.second));
762  log.debug() << "\t(spec) "
763  << from_expr_using_mode(ns, mode, pair.second.target())
764  << messaget::eom;
765  }
766 
767  for(const auto &heap_car : from_heap_alloc)
768  {
769  disjuncts.push_back(inclusion_check_single(car, heap_car));
770  log.debug() << "\t(heap) "
771  << from_expr_using_mode(ns, mode, heap_car.target())
772  << messaget::eom;
773  }
774 
775  if(include_stack_allocated)
776  {
777  for(const auto &pair : from_stack_alloc)
778  {
779  disjuncts.push_back(inclusion_check_single(car, pair.second));
780  log.debug() << "\t(stack) "
781  << from_expr_using_mode(ns, mode, pair.second.target())
782  << messaget::eom;
783  }
784 
785  // static locals are stack allocated and can never be DEAD
786  for(const auto &pair : from_static_local)
787  {
788  disjuncts.push_back(inclusion_check_single(car, pair.second));
789  log.debug() << "\t(static) "
790  << from_expr_using_mode(ns, mode, pair.second.target())
791  << messaget::eom;
792  }
793  }
794  log.debug() << "}" << messaget::eom;
795 
796  if(allow_null_lhs)
797  return or_exprt{
799  and_exprt{car.valid_var(), disjunction(disjuncts)}};
800  else
801  return and_exprt{car.valid_var(), disjunction(disjuncts)};
802 }
803 
805  const exprt &condition,
806  const exprt &target)
807 {
808  conditional_target_exprt key{condition, target};
809  const auto &found = from_spec_assigns.find(key);
810  if(found != from_spec_assigns.end())
811  {
812  log.warning() << "Ignored duplicate expression '"
813  << from_expr(ns, target.id(), target)
814  << "' in assigns clause spec at "
815  << target.source_location().as_string() << messaget::eom;
816  return found->second;
817  }
818  else
819  {
820  log.debug() << LOG_HEADER << "creating CAR for assigns clause target "
821  << format(condition) << ": " << format(target) << messaget::eom;
822  from_spec_assigns.insert({key, create_car_expr(condition, target)});
823  return from_spec_assigns.find(key)->second;
824  }
825 }
826 
828  const symbol_exprt &target)
829 {
830  const auto &found = from_stack_alloc.find(target);
831  if(found != from_stack_alloc.end())
832  {
833  log.warning() << "Ignored duplicate stack-allocated target '"
834  << from_expr(ns, target.id(), target) << "' at "
835  << target.source_location().as_string() << messaget::eom;
836  return found->second;
837  }
838  else
839  {
840  log.debug() << LOG_HEADER << "creating CAR for stack-allocated target "
841  << format(target) << messaget::eom;
842  from_stack_alloc.insert({target, create_car_expr(true_exprt{}, target)});
843  return from_stack_alloc.find(target)->second;
844  }
845 }
846 
847 const car_exprt &
849 {
850  log.debug() << LOG_HEADER << "creating CAR for heap-allocated target "
851  << format(target) << messaget::eom;
852  from_heap_alloc.emplace_back(create_car_expr(true_exprt{}, target));
853  return from_heap_alloc.back();
854 }
855 
857  const symbol_exprt &target)
858 {
859  const auto &found = from_static_local.find(target);
860  if(found != from_static_local.end())
861  {
862  log.warning() << "Ignored duplicate static local var target '"
863  << from_expr(ns, target.id(), target) << "' at "
864  << target.source_location().as_string() << messaget::eom;
865  return found->second;
866  }
867  else
868  {
869  log.debug() << LOG_HEADER << "creating CAR for static local target "
870  << format(target) << messaget::eom;
871  from_static_local.insert({target, create_car_expr(true_exprt{}, target)});
872  return from_static_local.find(target)->second;
873  }
874 }
875 
877  const car_exprt &tracked_car,
878  const car_exprt &freed_car,
879  goto_programt &result) const
880 {
881  source_locationt source_location(freed_car.source_location());
882  add_pragma_disable_pointer_checks(source_location);
883  add_pragma_disable_assigns_check(source_location);
884 
886  tracked_car.valid_var(),
887  and_exprt{tracked_car.valid_var(),
888  not_exprt{same_object(
889  tracked_car.lower_bound_var(), freed_car.lower_bound_var())}},
890  source_location));
891 }
892 
894  const car_exprt &freed_car,
895  goto_programt &dest) const
896 {
897  for(const auto &pair : from_spec_assigns)
898  invalidate_car(pair.second, freed_car, dest);
899 
900  for(const auto &car : from_heap_alloc)
901  invalidate_car(car, freed_car, dest);
902 }
903 
906  const goto_programt::const_targett &target)
907 {
908  log.debug().source_location = target->source_location();
909 
910  if(can_cast_expr<symbol_exprt>(target->assign_lhs()))
911  {
912  const auto &symbol_expr = to_symbol_expr(target->assign_lhs());
913 
914  if(cfg_info.is_local(symbol_expr.get_identifier()))
915  {
916  log.debug() << LOG_HEADER
917  << "skipping checking on assignment to local symbol "
918  << format(symbol_expr) << messaget::eom;
919  return false;
920  }
921  else
922  {
923  log.debug() << LOG_HEADER << "checking assignment to non-local symbol "
924  << format(symbol_expr) << messaget::eom;
925  return true;
926  }
927 
928  log.debug() << LOG_HEADER << "checking assignment to symbol "
929  << format(symbol_expr) << messaget::eom;
930  return true;
931  }
932  else
933  {
934  // This is not a mere symbol.
935  // Since non-dirty locals are not tracked explicitly in the write set,
936  // we need to skip the check if we can verify that the expression describes
937  // an access to a non-dirty local symbol or an input parameter,
938  // otherwise the check will fail.
939  // In addition, the expression shall not contain address_of or dereference
940  // operators, regardless of the base symbol/object on which they apply.
941  // If the expression contains an address_of operation, the assignment gets
942  // checked. If the base object is a local or a parameter, it will also be
943  // flagged as dirty and will be tracked explicitly, and the check will pass.
944  // If the expression contains a dereference operation, the assignment gets
945  // checked. If the dereferenced address was computed from a local object,
946  // from a function parameter or returned by a local malloc,
947  // then the object will be tracked explicitly and the check will pass.
948  // In all other cases (address of a non-local object, or dereference of
949  // a non-locally computed address) the location must be given explicitly
950  // in the assigns clause to be tracked and we must check the assignment.
951  if(cfg_info.is_local_composite_access(target->assign_lhs()))
952  {
953  log.debug()
954  << LOG_HEADER
955  << "skipping check on assignment to local composite member expression "
956  << format(target->assign_lhs()) << messaget::eom;
957  return false;
958  }
959  log.debug() << LOG_HEADER << "checking assignment to expression "
960  << format(target->assign_lhs()) << messaget::eom;
961  return true;
962  }
963 }
964 
967  const irep_idt &ident) const
968 {
970 }
971 
974  const goto_programt::const_targett &target) const
975 {
976  log.debug().source_location = target->source_location();
977  if(must_track_decl_or_dead(target->decl_symbol().get_identifier()))
978  {
979  log.debug() << LOG_HEADER << "explicitly tracking "
980  << format(target->decl_symbol()) << " as assignable"
981  << messaget::eom;
982  return true;
983  }
984  else
985  {
986  log.debug() << LOG_HEADER << "implicitly tracking "
987  << format(target->decl_symbol())
988  << " as assignable (non-dirty local)" << messaget::eom;
989  return false;
990  }
991 }
992 
996  const goto_programt::const_targett &target) const
997 {
998  return must_track_decl_or_dead(target->dead_symbol().get_identifier());
999 }
1000 
1002  goto_programt::targett &instruction_it,
1003  goto_programt &program) const
1004 {
1005  auto lhs = instruction_it->assign_lhs();
1006  lhs.add_source_location() = instruction_it->source_location();
1007  goto_programt payload;
1008  check_inclusion_assignment(lhs, payload);
1009  insert_before_swap_and_advance(program, instruction_it, payload);
1010 }
1011 
1013  goto_programt::targett &instruction_it,
1014  goto_programt &body)
1015 {
1017  instruction_it->is_function_call(),
1018  "The first argument of instrument_call_statement should always be "
1019  "a function call");
1020 
1021  const auto &callee_name =
1022  to_symbol_expr(instruction_it->call_function()).get_identifier();
1023 
1024  if(callee_name == "malloc")
1025  {
1026  const auto &function_call = to_code_function_call(instruction_it->code());
1027  if(function_call.lhs().is_not_nil())
1028  {
1029  // grab the returned pointer from malloc
1030  auto object = pointer_object(function_call.lhs());
1031  object.add_source_location() = function_call.source_location();
1032  // move past the call and then insert the CAR
1033  instruction_it++;
1034  goto_programt payload;
1035  track_heap_allocated(object, payload);
1036  insert_before_swap_and_advance(body, instruction_it, payload);
1037  // since CAR was inserted *after* the malloc call,
1038  // move the instruction pointer backward,
1039  // because the caller increments it in a `for` loop
1040  instruction_it--;
1041  }
1042  }
1043  else if(callee_name == "free")
1044  {
1045  const auto &ptr = instruction_it->call_arguments().front();
1046  auto object = pointer_object(ptr);
1047  object.add_source_location() = instruction_it->source_location();
1048  goto_programt payload;
1050  insert_before_swap_and_advance(body, instruction_it, payload);
1051  }
1052 }
Forall_goto_program_instructions
#define Forall_goto_program_instructions(it, program)
Definition: goto_program.h:1234
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
pointer_offset_size.h
can_cast_expr< symbol_exprt >
bool can_cast_expr< symbol_exprt >(const exprt &base)
Definition: std_expr.h:206
source_locationt::get_function
const irep_idt & get_function() const
Definition: source_location.h:55
source_locationt::get_comment
const irep_idt & get_comment() const
Definition: source_location.h:70
format
static format_containert< T > format(const T &o)
Definition: format.h:37
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
is_assignable
bool is_assignable(const exprt &expr)
Returns true iff the argument is one of the following:
Definition: expr_util.cpp:22
instrument_spec_assignst::from_spec_assigns
cond_target_exprt_to_car_mapt from_spec_assigns
Map from conditional target expressions of assigns clauses to corresponding conditional address range...
Definition: instrument_spec_assigns.h:612
to_code_function_call
const code_function_callt & to_code_function_call(const goto_instruction_codet &code)
Definition: goto_instruction_code.h:385
insert_before_swap_and_advance
void insert_before_swap_and_advance(goto_programt &destination, goto_programt::targett &target, goto_programt &payload)
Insert a goto program before a target instruction iterator and advance the iterator.
Definition: utils.cpp:138
to_side_effect_expr_function_call
side_effect_expr_function_callt & to_side_effect_expr_function_call(exprt &expr)
Definition: std_code.h:1739
has_subexpr
bool has_subexpr(const exprt &expr, const std::function< bool(const exprt &)> &pred)
returns true if the expression has a subexpression that satisfies pred
Definition: expr_util.cpp:139
pointer_object
exprt pointer_object(const exprt &p)
Definition: pointer_predicates.cpp:23
source_locationt::as_string
std::string as_string() const
Definition: source_location.h:25
can_cast_expr< side_effect_expr_function_callt >
bool can_cast_expr< side_effect_expr_function_callt >(const exprt &base)
Definition: std_code.h:1730
source_locationt::set_comment
void set_comment(const irep_idt &comment)
Definition: source_location.h:135
instrument_spec_assignst::create_car_from_spec_assigns
const car_exprt & create_car_from_spec_assigns(const exprt &condition, const exprt &target)
Definition: instrument_spec_assigns.cpp:804
conditional_target_exprt
Class that represents a single conditional target.
Definition: instrument_spec_assigns.h:37
arith_tools.h
source_locationt::set_function
void set_function(const irep_idt &function)
Definition: source_location.h:120
instrument_spec_assignst::traverse_instructions
void traverse_instructions(const irep_idt ambient_function_id, goto_programt::const_targett it, const goto_programt::const_targett end, covered_locationst &covered_locations, propagated_static_localst &propagated) const
Traverses the given list of instructions, updating the given coverage map, recursing into function ca...
Definition: instrument_spec_assigns.cpp:202
null_pointer
exprt null_pointer(const exprt &pointer)
Definition: pointer_predicates.cpp:100
goto_programt::instructiont::source_location_nonconst
source_locationt & source_location_nonconst()
Definition: goto_program.h:345
typet
The type of an expression, extends irept.
Definition: type.h:28
source_locationt::get_pragmas
const irept::named_subt & get_pragmas() const
Definition: source_location.h:189
irept::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
instrument_spec_assignst::check_inclusion_heap_allocated_and_invalidate_aliases
void check_inclusion_heap_allocated_and_invalidate_aliases(const exprt &expr, goto_programt &dest)
Generates inclusion check instructions for an argument passed to free.
Definition: instrument_spec_assigns.cpp:304
instrument_spec_assignst::create_snapshot
void create_snapshot(const car_exprt &car, goto_programt &dest) const
Returns snapshot instructions for a car_exprt.
Definition: instrument_spec_assigns.cpp:594
car_exprt::condition
const exprt & condition() const
Condition expression. When this condition holds the target is allowed.
Definition: instrument_spec_assigns.h:107
CONTRACT_PRAGMA_DISABLE_ASSIGNS_CHECK
const char CONTRACT_PRAGMA_DISABLE_ASSIGNS_CHECK[]
A local pragma used to keep track and skip already instrumented instructions.
Definition: instrument_spec_assigns.cpp:48
instrument_spec_assignst::from_stack_alloc
symbol_exprt_to_car_mapt from_stack_alloc
Map from DECL symbols to corresponding conditional address ranges.
Definition: instrument_spec_assigns.h:621
pointer_predicates.h
instrument_spec_assignst::check_inclusion_assignment
void check_inclusion_assignment(const exprt &lhs, goto_programt &dest) const
Generates inclusion check instructions for an assignment, havoc or havoc_object instruction.
Definition: instrument_spec_assigns.cpp:145
cfg_info.h
has_disable_assigns_check_pragma
bool has_disable_assigns_check_pragma(const goto_programt::const_targett &target)
Returns true iff the target instruction is tagged with a 'CONTRACT_PRAGMA_DISABLE_ASSIGNS_CHECK' prag...
Definition: instrument_spec_assigns.cpp:63
and_exprt
Boolean AND.
Definition: std_expr.h:2070
instrument_spec_assignst::invalidate_car
void invalidate_car(const car_exprt &tracked_car, const car_exprt &freed_car, goto_programt &result) const
Adds an assignment in dest to invalidate the tracked car if was valid before and was pointing to the ...
Definition: instrument_spec_assigns.cpp:876
source_locationt::add_pragma
void add_pragma(const irep_idt &pragma)
Definition: source_location.h:184
goto_programt::add
targett add(instructiont &&instruction)
Adds a given instruction at the end.
Definition: goto_program.h:709
instrument_spec_assignst::invalidate_heap_and_spec_aliases
void invalidate_heap_and_spec_aliases(const car_exprt &freed_car, goto_programt &dest) const
Generates instructions to invalidate all targets aliased with a car that was passed to free,...
Definition: instrument_spec_assigns.cpp:893
plus_exprt
The plus expression Associativity is not specified.
Definition: std_expr.h:946
goto_programt::empty
bool empty() const
Is the program empty?
Definition: goto_program.h:790
exprt
Base class for all expressions.
Definition: expr.h:55
instrument_spec_assignst::from_static_local
symbol_exprt_to_car_mapt from_static_local
Map to from detected or propagated static local symbols to corresponding conditional address ranges.
Definition: instrument_spec_assigns.h:636
instrument_spec_assignst::inclusion_check_assertion
void inclusion_check_assertion(const car_exprt &lhs, bool allow_null_lhs, bool include_stack_allocated, goto_programt &dest) const
Returns an inclusion check assertion of lhs over all tracked cars.
Definition: instrument_spec_assigns.cpp:676
bool_typet
The Boolean type.
Definition: std_types.h:35
messaget::eom
static eomt eom
Definition: message.h:297
instrument_spec_assignst::target_validity_expr
exprt target_validity_expr(const car_exprt &car, bool allow_null_target) const
Returns the target validity expression for a car_exprt.
Definition: instrument_spec_assigns.cpp:626
exprt::is_true
bool is_true() const
Return whether the expression is a constant representing true.
Definition: expr.cpp:34
PROPAGATE_STATIC_LOCAL_PRAGMA
static const char PROPAGATE_STATIC_LOCAL_PRAGMA[]
Pragma used to mark assignments to static locals that need to be propagated.
Definition: instrument_spec_assigns.cpp:33
car_exprt::target_size
const exprt & target_size() const
Size of the target in bytes.
Definition: instrument_spec_assigns.h:125
goto_functionst::function_map
function_mapt function_map
Definition: goto_functions.h:29
car_exprt::lower_bound_var
const symbol_exprt & lower_bound_var() const
Identifier of the lower address bound snapshot variable.
Definition: instrument_spec_assigns.h:137
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
goto_programt::make_decl
static instructiont make_decl(const symbol_exprt &symbol, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:955
car_havoc_methodt::HAVOC_OBJECT
@ HAVOC_OBJECT
is_assigns_clause_replacement_tracking_comment
bool is_assigns_clause_replacement_tracking_comment(const irep_idt &comment)
Returns true if the given comment matches the type of comments created by make_assigns_clause_replace...
Definition: utils.cpp:240
goto_programt::make_assignment
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
Definition: goto_program.h:1056
instrument_spec_assignst::target_validity_assertion
void target_validity_assertion(const car_exprt &car, bool allow_null_target, goto_programt &dest) const
Generates the target validity assertion for the given car and adds it to dest.
Definition: instrument_spec_assigns.cpp:645
cleanert::clean
void clean(exprt &guard, goto_programt &dest, const irep_idt &mode)
Definition: utils.h:157
instrument_spec_assignst::log
messaget log
Logger.
Definition: instrument_spec_assigns.h:492
cleanert
Allows to clean expressions of side effects.
Definition: utils.h:147
add_pragma_disable_pointer_checks
void add_pragma_disable_pointer_checks(source_locationt &location)
Adds a pragma on a source location disable all pointer checks.
Definition: instrument_spec_assigns.cpp:51
instrument_spec_assignst::function_id
const irep_idt & function_id
Name of the instrumented function.
Definition: instrument_spec_assigns.h:477
car_exprt::upper_bound_var
const symbol_exprt & upper_bound_var() const
Identifier of the upper address bound snapshot variable.
Definition: instrument_spec_assigns.h:143
car_exprt::valid_var
const symbol_exprt & valid_var() const
Identifier of the validity snapshot variable.
Definition: instrument_spec_assigns.h:131
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
to_pointer_object_expr
const pointer_object_exprt & to_pointer_object_expr(const exprt &expr)
Cast an exprt to a pointer_object_exprt.
Definition: pointer_expr.h:986
disjunction
exprt disjunction(const exprt::operandst &op)
1) generates a disjunction for two or more operands 2) for one operand, returns the operand 3) return...
Definition: std_expr.cpp:50
instrument_spec_assignst::ns
const namespacet ns
Program namespace.
Definition: instrument_spec_assigns.h:489
utils.h
goto_programt::make_assertion
static instructiont make_assertion(const exprt &g, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:924
messaget::error
mstreamt & error() const
Definition: message.h:399
or_exprt
Boolean OR.
Definition: std_expr.h:2178
can_cast_expr< side_effect_expr_nondett >
bool can_cast_expr< side_effect_expr_nondett >(const exprt &base)
Definition: std_code.h:1540
instrument_spec_assignst::create_car_expr
car_exprt create_car_expr(const exprt &condition, const exprt &target) const
Creates a conditional address range expression from a cleaned-up condition and target expression.
Definition: instrument_spec_assigns.cpp:452
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
car_havoc_methodt::NONDET_ASSIGN
@ NONDET_ASSIGN
instrument_spec_assignst::must_track_dead
bool must_track_dead(const goto_programt::const_targett &target) const
Returns true iff a DEAD x must be processed to update the write set.
Definition: instrument_spec_assigns.cpp:995
messaget::mstreamt::source_location
source_locationt source_location
Definition: message.h:247
language_util.h
instrument_spec_assignst::inclusion_check_single
exprt inclusion_check_single(const car_exprt &lhs, const car_exprt &candidate_car) const
Returns inclusion check expression for a single candidate location.
Definition: instrument_spec_assigns.cpp:713
instrument_spec_assignst::st
symbol_tablet & st
Program symbol table.
Definition: instrument_spec_assigns.h:486
instrument_spec_assignst::create_car_from_static_local
const car_exprt & create_car_from_static_local(const symbol_exprt &target)
Definition: instrument_spec_assigns.cpp:856
has_propagate_static_local_pragma
bool has_propagate_static_local_pragma(const source_locationt &source_location)
Definition: instrument_spec_assigns.cpp:36
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
add_pragma_disable_assigns_check
void add_pragma_disable_assigns_check(source_locationt &location)
Adds a pragma on a source_locationt to disable inclusion checking.
Definition: instrument_spec_assigns.cpp:70
symbolt::symbol_expr
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
signed_size_type
signedbv_typet signed_size_type()
Definition: c_types.cpp:84
simplify_expr
exprt simplify_expr(exprt src, const namespacet &ns)
Definition: simplify_expr.cpp:2931
cfg_infot::is_local_composite_access
bool is_local_composite_access(const exprt &expr) const
Returns true iff expr is an access to a locally declared symbol and does not contain dereference or a...
Definition: cfg_info.h:50
instrument_spec_assignst::inclusion_check_full
exprt inclusion_check_full(const car_exprt &lhs, bool allow_null_lhs, bool include_stack_allocated) const
Returns an inclusion check expression of lhs over all tracked cars.
Definition: instrument_spec_assigns.cpp:732
add_propagate_static_local_pragma
void add_propagate_static_local_pragma(source_locationt &source_location)
Sets a pragma to mark assignments to static local variables that need to be propagated upwards in the...
Definition: instrument_spec_assigns.cpp:42
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
instrument_spec_assignst::mode
const irep_idt & mode
Language mode.
Definition: instrument_spec_assigns.h:495
instrument_spec_assignst::from_heap_alloc
car_expr_listt from_heap_alloc
Definition: instrument_spec_assigns.h:630
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
object_size
exprt object_size(const exprt &pointer)
Definition: pointer_predicates.cpp:33
instrument_spec_assignst::must_track_decl
bool must_track_decl(const goto_programt::const_targett &target) const
Returns true iff a DECL x must be explicitly added to the write set.
Definition: instrument_spec_assigns.cpp:973
irept::id
const irep_idt & id() const
Definition: irep.h:396
LOG_HEADER
static const char LOG_HEADER[]
header for log messages
Definition: instrument_spec_assigns.cpp:30
exprt::operandst
std::vector< exprt > operandst
Definition: expr.h:58
dstringt::empty
bool empty() const
Definition: dstring.h:88
false_exprt
The Boolean constant false.
Definition: std_expr.h:3016
instrument_spec_assignst::functions
const goto_functionst & functions
Other functions of the model.
Definition: instrument_spec_assigns.h:480
instrument_spec_assignst::must_check_assign
bool must_check_assign(const goto_programt::const_targett &target)
Returns true iff an ASSIGN lhs := rhs instruction must be instrumented.
Definition: instrument_spec_assigns.cpp:905
instrument_spec_assignst::instrument_assign_statement
void instrument_assign_statement(goto_programt::targett &instruction_it, goto_programt &body) const
Inserts an assertion in body immediately before the assignment at instruction_it, to ensure that the ...
Definition: instrument_spec_assigns.cpp:1001
conditional_target_group_exprt
A class for an expression that represents a conditional target or a list of targets sharing a common ...
Definition: c_expr.h:231
pointer_offset
exprt pointer_offset(const exprt &pointer)
Definition: pointer_predicates.cpp:38
minus_exprt
Binary minus.
Definition: std_expr.h:1005
conditional_target_group_exprt::condition
const exprt & condition() const
Definition: c_expr.h:266
conditional_target_group_exprt::targets
const exprt::operandst & targets() const
Definition: c_expr.h:276
char_type
bitvector_typet char_type()
Definition: c_types.cpp:124
source_locationt
Definition: source_location.h:18
simplify_expr.h
goto_programt::instructions
instructionst instructions
The list of instructions in the goto program.
Definition: goto_program.h:592
instrument_spec_assignst::track_static_locals_between
void track_static_locals_between(goto_programt::const_targett it, const goto_programt::const_targett end, goto_programt &dest)
Searches the goto instructions reachable between the given it and end target instructions to identify...
Definition: instrument_spec_assigns.cpp:183
expr_util.h
Deprecated expression utility functions.
cfg_infot::is_not_local_or_dirty_local
virtual bool is_not_local_or_dirty_local(const irep_idt &ident) const =0
Returns true iff the given ident is either non-locally declared or is locally-declared but dirty.
messaget::get_message_handler
message_handlert & get_message_handler()
Definition: message.h:184
format_expr.h
instrument_spec_assignst::track_static_locals
void track_static_locals(goto_programt &dest)
Searches the goto instructions reachable from the start to the end of the instrumented function's ins...
Definition: instrument_spec_assigns.cpp:155
instrument_spec_assignst::invalidate_stack_allocated
void invalidate_stack_allocated(const symbol_exprt &symbol_expr, goto_programt &dest)
Generate instructions to invalidate a stack-allocated object that goes DEAD in dest.
Definition: instrument_spec_assigns.cpp:112
instrument_spec_assignst::track_plain_spec_target
void track_plain_spec_target(const exprt &expr, goto_programt &dest)
Track and generate snaphsot instructions and target validity checking assertions for a conditional ta...
Definition: instrument_spec_assigns.cpp:430
car_havoc_methodt::HAVOC_SLICE
@ HAVOC_SLICE
instrument_spec_assignst::instrument_call_statement
void instrument_call_statement(goto_programt::targett &instruction_it, goto_programt &body)
Inserts an assertion in body immediately before the function call at instruction_it,...
Definition: instrument_spec_assigns.cpp:1012
car_exprt::target
const exprt & target() const
The target expression.
Definition: instrument_spec_assigns.h:113
instrument_spec_assignst::create_fresh_symbol
const symbolt create_fresh_symbol(const std::string &suffix, const typet &type, const source_locationt &location) const
Creates a fresh symbolt with given suffix, scoped to function_id.
Definition: instrument_spec_assigns.cpp:444
instrument_spec_assignst::must_track_decl_or_dead
bool must_track_decl_or_dead(const irep_idt &ident) const
Returns true iff a function-local symbol must be tracked.
Definition: instrument_spec_assigns.cpp:966
symbolt
Symbol table entry.
Definition: symbol.h:27
w_ok_exprt
A predicate that indicates that an address range is ok to write.
Definition: pointer_expr.h:792
instrument_spec_assigns.h
PRECONDITION_WITH_DIAGNOSTICS
#define PRECONDITION_WITH_DIAGNOSTICS(CONDITION,...)
Definition: invariant.h:464
instrument_spec_assignst::covered_locationst
std::unordered_map< irep_idt, location_intervalt > covered_locationst
Map type from function identifiers to covered locations.
Definition: instrument_spec_assigns.h:408
instrument_spec_assignst::instrument_instructions
void instrument_instructions(goto_programt &body, goto_programt::targett instruction_it, const goto_programt::targett &instruction_end, const std::function< bool(const goto_programt::targett &)> &pred={})
Instruments a sequence of instructions with inclusion checks.
Definition: instrument_spec_assigns.cpp:322
instrument_spec_assignst::collect_static_symbols
void collect_static_symbols(covered_locationst &covered_locations, std::unordered_set< symbol_exprt, irep_hash > &dest)
Collects static symbols from the symbol table that have a source location included in one of the cove...
Definition: instrument_spec_assigns.cpp:283
CPROVER_PREFIX
#define CPROVER_PREFIX
Definition: cprover_prefix.h:14
same_object
exprt same_object(const exprt &p1, const exprt &p2)
Definition: pointer_predicates.cpp:28
exprt::add_to_operands
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
Definition: expr.h:162
instrument_spec_assignst::create_car_from_heap_alloc
const car_exprt & create_car_from_heap_alloc(const exprt &target)
Definition: instrument_spec_assigns.cpp:848
car_exprt::target_start_address
const exprt & target_start_address() const
Start address of the target.
Definition: instrument_spec_assigns.h:119
goto_programt
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:72
instrument_spec_assignst::track_heap_allocated
void track_heap_allocated(const exprt &expr, goto_programt &dest)
Track a whole heap-alloc object and generate snaphsot instructions in dest.
Definition: instrument_spec_assigns.cpp:131
size_of_expr
optionalt< exprt > size_of_expr(const typet &type, const namespacet &ns)
Definition: pointer_offset_size.cpp:280
goto_programt::const_targett
instructionst::const_iterator const_targett
Definition: goto_program.h:587
pointer_object_exprt::pointer
exprt & pointer()
Definition: pointer_expr.h:955
instrument_spec_assignst::track_spec_target
void track_spec_target(const exprt &expr, goto_programt &dest)
Track an assigns clause target and generate snaphsot instructions and well-definedness assertions in ...
Definition: instrument_spec_assigns.cpp:89
new_tmp_symbol
const symbolt & new_tmp_symbol(const typet &type, const source_locationt &location, const irep_idt &mode, symbol_table_baset &symtab, std::string suffix, bool is_auxiliary)
Adds a fresh and uniquely named symbol to the symbol table.
Definition: utils.cpp:148
instrument_spec_assignst::cfg_info
cfg_infot & cfg_info
CFG information for simplification.
Definition: instrument_spec_assigns.h:483
car_exprt
Class that represents a normalized conditional address range, with:
Definition: instrument_spec_assigns.h:76
less_than_or_equal_exprt
Binary less than or equal operator expression.
Definition: std_expr.h:814
messaget::debug
mstreamt & debug() const
Definition: message.h:429
address_of_exprt
Operator to return the address of an object.
Definition: pointer_expr.h:370
size_type
unsignedbv_typet size_type()
Definition: c_types.cpp:68
instrument_spec_assignst::track_spec_target_group
void track_spec_target_group(const conditional_target_group_exprt &group, goto_programt &dest)
Track and generate snaphsot instructions and target validity checking assertions for a conditional ta...
Definition: instrument_spec_assigns.cpp:406
true_exprt
The Boolean constant true.
Definition: std_expr.h:3007
instrument_spec_assignst::propagated_static_localst
std::unordered_set< symbol_exprt, irep_hash > propagated_static_localst
Definition: instrument_spec_assigns.h:409
messaget::warning
mstreamt & warning() const
Definition: message.h:404
comment
static std::string comment(const rw_set_baset::entryt &entry, bool write)
Definition: race_check.cpp:109
goto_programt::instructiont
This class represents an instruction in the GOTO intermediate representation.
Definition: goto_program.h:180
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:211
instrument_spec_assignst::stack_allocated_is_tracked
bool stack_allocated_is_tracked(const symbol_exprt &symbol_expr) const
Returns true if the expression is tracked.
Definition: instrument_spec_assigns.cpp:106
c_types.h
from_expr
std::string from_expr(const namespacet &ns, const irep_idt &identifier, const exprt &expr)
Definition: language_util.cpp:38
instrument_spec_assignst::track_stack_allocated
void track_stack_allocated(const symbol_exprt &symbol_expr, goto_programt &dest)
Track a stack-allocated object and generate snaphsot instructions in dest.
Definition: instrument_spec_assigns.cpp:99
goto_programt::targett
instructionst::iterator targett
Definition: goto_program.h:586
from_expr_using_mode
std::string from_expr_using_mode(const namespacet &ns, const irep_idt &mode, const exprt &expr)
Formats an expression using the given namespace, using the given mode to retrieve the language printe...
Definition: language_util.cpp:21
cfg_infot::is_local
virtual bool is_local(const irep_idt &ident) const =0
Returns true iff ident is locally declared.
validation_modet::INVARIANT
@ INVARIANT
instrument_spec_assignst::create_car_from_stack_alloc
const car_exprt & create_car_from_stack_alloc(const symbol_exprt &target)
Definition: instrument_spec_assigns.cpp:827
source_locationt::set_property_class
void set_property_class(const irep_idt &property_class)
Definition: source_location.h:130
not_exprt
Boolean negation.
Definition: std_expr.h:2277