CBMC
string_instrumentation.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: String Abstraction
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "string_instrumentation.h"
13 
14 #include <util/arith_tools.h>
15 #include <util/c_types.h>
16 #include <util/config.h>
17 #include <util/pointer_expr.h>
18 #include <util/std_code.h>
19 #include <util/string_constant.h>
20 
23 
24 #include "format_strings.h"
25 
26 #include <algorithm>
27 
28 exprt is_zero_string(const exprt &what, bool write)
29 {
30  unary_exprt result{"is_zero_string", what, c_bool_type()};
31  result.copy_to_operands(what);
32  result.set("lhs", write);
33  return notequal_exprt{result, from_integer(0, c_bool_type())};
34 }
35 
36 exprt zero_string_length(const exprt &what, bool write)
37 {
38  exprt result("zero_string_length", size_type());
39  result.copy_to_operands(what);
40  result.set("lhs", write);
41  return result;
42 }
43 
44 exprt buffer_size(const exprt &what)
45 {
46  exprt result("buffer_size", size_type());
47  result.copy_to_operands(what);
48  return result;
49 }
50 
52 {
53 public:
55  : symbol_table(_symbol_table), ns(_symbol_table)
56  {
57  }
58 
59  void operator()(goto_programt &dest);
60  void operator()(goto_functionst &dest);
61 
62 protected:
65 
68 
69  // strings
70  void do_sprintf(
71  goto_programt &dest,
73  const exprt &lhs,
74  const exprt::operandst &arguments);
75  void do_snprintf(
76  goto_programt &dest,
78  const exprt &lhs,
79  const exprt::operandst &arguments);
80  void do_strcat(
81  goto_programt &dest,
83  const exprt &lhs,
84  const exprt::operandst &arguments);
85  void do_strncmp(
86  goto_programt &dest,
88  const exprt &lhs,
89  const exprt::operandst &arguments);
90  void do_strchr(
91  goto_programt &dest,
93  const exprt &lhs,
94  const exprt::operandst &arguments);
95  void do_strrchr(
96  goto_programt &dest,
98  const exprt &lhs,
99  const exprt::operandst &arguments);
100  void do_strstr(
101  goto_programt &dest,
102  goto_programt::targett target,
103  const exprt &lhs,
104  const exprt::operandst &arguments);
105  void do_strtok(
106  goto_programt &dest,
107  goto_programt::targett target,
108  const exprt &lhs,
109  const exprt::operandst &arguments);
110  void do_strerror(
111  goto_programt &dest,
113  const exprt &lhs,
114  const exprt::operandst &arguments);
115  void do_fscanf(
116  goto_programt &dest,
117  goto_programt::targett target,
118  const exprt &lhs,
119  const exprt::operandst &arguments);
120 
122  goto_programt &dest,
124  const code_function_callt::argumentst &arguments,
125  std::size_t format_string_inx,
126  std::size_t argument_start_inx,
127  const std::string &function_name);
128 
130  goto_programt &dest,
132  const code_function_callt::argumentst &arguments,
133  std::size_t format_string_inx,
134  std::size_t argument_start_inx,
135  const std::string &function_name);
136 
137  bool is_string_type(const typet &t) const
138  {
139  return (t.id() == ID_pointer || t.id() == ID_array) &&
140  (to_type_with_subtype(t).subtype().id() == ID_signedbv ||
141  to_type_with_subtype(t).subtype().id() == ID_unsignedbv) &&
144  }
145 
146  void invalidate_buffer(
147  goto_programt &dest,
149  const exprt &buffer,
150  const typet &buf_type,
151  const mp_integer &limit);
152 };
153 
155  symbol_table_baset &symbol_table,
156  goto_programt &dest)
157 {
160 }
161 
163  symbol_table_baset &symbol_table,
164  goto_functionst &dest)
165 {
168 }
169 
171 {
172  string_instrumentation(goto_model.symbol_table, goto_model.goto_functions);
173 }
174 
176 {
177  for(goto_functionst::function_mapt::iterator it = dest.function_map.begin();
178  it != dest.function_map.end();
179  it++)
180  {
181  (*this)(it->second.body);
182  }
183 }
184 
186 {
188  instrument(dest, it);
189 }
190 
192  goto_programt &dest,
194 {
195  if(it->is_function_call())
196  do_function_call(dest, it);
197 }
198 
200  goto_programt &dest,
201  goto_programt::targett target)
202 {
203  const exprt &lhs = as_const(*target).call_lhs();
204  const exprt &function = as_const(*target).call_function();
205  const auto &arguments = as_const(*target).call_arguments();
206 
207  if(function.id() == ID_symbol)
208  {
209  const irep_idt &identifier = to_symbol_expr(function).get_identifier();
210 
211  if(identifier == "strcoll")
212  {
213  }
214  else if(identifier == "strncmp")
215  do_strncmp(dest, target, lhs, arguments);
216  else if(identifier == "strxfrm")
217  {
218  }
219  else if(identifier == "strchr")
220  do_strchr(dest, target, lhs, arguments);
221  else if(identifier == "strcspn")
222  {
223  }
224  else if(identifier == "strpbrk")
225  {
226  }
227  else if(identifier == "strrchr")
228  do_strrchr(dest, target, lhs, arguments);
229  else if(identifier == "strspn")
230  {
231  }
232  else if(identifier == "strerror")
233  do_strerror(dest, target, lhs, arguments);
234  else if(identifier == "strstr")
235  do_strstr(dest, target, lhs, arguments);
236  else if(identifier == "strtok")
237  do_strtok(dest, target, lhs, arguments);
238  else if(identifier == "sprintf")
239  do_sprintf(dest, target, lhs, arguments);
240  else if(identifier == "snprintf")
241  do_snprintf(dest, target, lhs, arguments);
242  else if(identifier == "fscanf" || identifier == "__isoc99_fscanf")
243  do_fscanf(dest, target, lhs, arguments);
244 
245  remove_skip(dest);
246  }
247 }
248 
250  goto_programt &dest,
251  goto_programt::targett target,
252  const exprt &lhs,
253  const exprt::operandst &arguments)
254 {
255  if(arguments.size() < 2)
256  {
258  "sprintf expected to have two or more arguments",
259  target->source_location());
260  }
261 
262  goto_programt tmp;
263 
264  // in the abstract model, we have to report a
265  // (possibly false) positive here
266  source_locationt annotated_location = target->source_location();
267  annotated_location.set_property_class("string");
268  annotated_location.set_comment("sprintf buffer overflow");
269  tmp.add(goto_programt::make_assertion(false_exprt(), annotated_location));
270 
271  do_format_string_read(tmp, target, arguments, 1, 2, "sprintf");
272 
273  if(lhs.is_not_nil())
274  {
275  exprt rhs = side_effect_expr_nondett(lhs.type(), target->source_location());
276 
277  tmp.add(
278  goto_programt::make_assignment(lhs, rhs, target->source_location()));
279  }
280 
281  target->turn_into_skip();
282  dest.insert_before_swap(target, tmp);
283 }
284 
286  goto_programt &dest,
287  goto_programt::targett target,
288  const exprt &lhs,
289  const exprt::operandst &arguments)
290 {
291  if(arguments.size() < 3)
292  {
294  "snprintf expected to have three or more arguments",
295  target->source_location());
296  }
297 
298  goto_programt tmp;
299 
300  exprt bufsize = buffer_size(arguments[0]);
301 
302  source_locationt annotated_location = target->source_location();
303  annotated_location.set_property_class("string");
304  annotated_location.set_comment("snprintf buffer overflow");
306  binary_relation_exprt(bufsize, ID_ge, arguments[1]), annotated_location));
307 
308  do_format_string_read(tmp, target, arguments, 2, 3, "snprintf");
309 
310  if(lhs.is_not_nil())
311  {
312  exprt rhs = side_effect_expr_nondett(lhs.type(), target->source_location());
313 
314  tmp.add(
315  goto_programt::make_assignment(lhs, rhs, target->source_location()));
316  }
317 
318  target->turn_into_skip();
319  dest.insert_before_swap(target, tmp);
320 }
321 
323  goto_programt &dest,
324  goto_programt::targett target,
325  const exprt &lhs,
326  const exprt::operandst &arguments)
327 {
328  if(arguments.size() < 2)
329  {
331  "fscanf expected to have two or more arguments",
332  target->source_location());
333  }
334 
335  goto_programt tmp;
336 
337  do_format_string_write(tmp, target, arguments, 1, 2, "fscanf");
338 
339  if(lhs.is_not_nil())
340  {
341  exprt rhs = side_effect_expr_nondett(lhs.type(), target->source_location());
342 
343  tmp.add(
344  goto_programt::make_assignment(lhs, rhs, target->source_location()));
345  }
346 
347  target->turn_into_skip();
348  dest.insert_before_swap(target, tmp);
349 }
350 
352  goto_programt &dest,
354  const code_function_callt::argumentst &arguments,
355  std::size_t format_string_inx,
356  std::size_t argument_start_inx,
357  const std::string &function_name)
358 {
359  const exprt &format_arg = arguments[format_string_inx];
360 
361  if(
362  format_arg.id() == ID_address_of &&
363  to_address_of_expr(format_arg).object().id() == ID_index &&
364  to_index_expr(to_address_of_expr(format_arg).object()).array().id() ==
365  ID_string_constant)
366  {
369  to_index_expr(to_address_of_expr(format_arg).object()).array())
370  .value()));
371 
372  std::size_t args = 0;
373 
374  for(const auto &token : token_list)
375  {
376  if(token.type == format_tokent::token_typet::STRING)
377  {
378  const exprt &arg = arguments[argument_start_inx + args];
379 
380  if(arg.id() != ID_string_constant) // we don't need to check constants
381  {
382  exprt temp(arg);
383 
384  if(arg.type().id() != ID_pointer)
385  {
386  index_exprt index(temp, from_integer(0, c_index_type()));
387  temp = address_of_exprt(index);
388  }
389 
390  source_locationt annotated_location = target->source_location();
391  annotated_location.set_property_class("string");
392  std::string comment("zero-termination of string argument of ");
393  comment += function_name;
394  annotated_location.set_comment(comment);
396  is_zero_string(temp), annotated_location));
397  }
398  }
399 
400  if(
401  token.type != format_tokent::token_typet::TEXT &&
403  args++;
404 
405  if(
406  find(
407  token.flags.begin(),
408  token.flags.end(),
409  format_tokent::flag_typet::ASTERISK) != token.flags.end())
410  args++; // just eat the additional argument
411  }
412  }
413  else // non-const format string
414  {
415  source_locationt annotated_location = target->source_location();
416  annotated_location.set_property_class("string");
417  annotated_location.set_comment(
418  "zero-termination of format string of " + function_name);
420  is_zero_string(arguments[1]), annotated_location));
421 
422  for(std::size_t i = 2; i < arguments.size(); i++)
423  {
424  const exprt &arg = arguments[i];
425 
426  if(arguments[i].id() != ID_string_constant && is_string_type(arg.type()))
427  {
428  exprt temp(arg);
429 
430  if(arg.type().id() != ID_pointer)
431  {
432  index_exprt index(temp, from_integer(0, c_index_type()));
433  temp = address_of_exprt(index);
434  }
435 
436  source_locationt annotated_location = target->source_location();
437  annotated_location.set_property_class("string");
438  annotated_location.set_comment(
439  "zero-termination of string argument of " + function_name);
441  is_zero_string(temp), annotated_location));
442  }
443  }
444  }
445 }
446 
448  goto_programt &dest,
450  const code_function_callt::argumentst &arguments,
451  std::size_t format_string_inx,
452  std::size_t argument_start_inx,
453  const std::string &function_name)
454 {
455  const exprt &format_arg = arguments[format_string_inx];
456 
457  if(
458  format_arg.id() == ID_address_of &&
459  to_address_of_expr(format_arg).object().id() == ID_index &&
460  to_index_expr(to_address_of_expr(format_arg).object()).array().id() ==
461  ID_string_constant) // constant format
462  {
465  to_index_expr(to_address_of_expr(format_arg).object()).array())
466  .value()));
467 
468  std::size_t args = 0;
469 
470  for(const auto &token : token_list)
471  {
472  if(
473  find(
474  token.flags.begin(),
475  token.flags.end(),
476  format_tokent::flag_typet::ASTERISK) != token.flags.end())
477  continue; // asterisk means `ignore this'
478 
479  switch(token.type)
480  {
482  {
483  const exprt &argument = arguments[argument_start_inx + args];
484  const typet &arg_type = argument.type();
485 
486  exprt condition;
487 
488  if(token.field_width != 0)
489  {
490  exprt fwidth = from_integer(token.field_width, unsigned_int_type());
492  const plus_exprt fw_1(fwidth, one); // +1 for 0-char
493 
494  exprt fw_lt_bs;
495 
496  if(arg_type.id() == ID_pointer)
497  fw_lt_bs =
498  binary_relation_exprt(fw_1, ID_le, buffer_size(argument));
499  else
500  {
501  const index_exprt index(
502  argument, from_integer(0, unsigned_int_type()));
503  address_of_exprt aof(index);
504  fw_lt_bs = binary_relation_exprt(fw_1, ID_le, buffer_size(aof));
505  }
506 
507  condition = fw_lt_bs;
508  }
509  else
510  {
511  // this is a possible overflow.
512  condition = false_exprt();
513  }
514 
515  source_locationt annotated_location = target->source_location();
516  annotated_location.set_property_class("string");
517  std::string comment("format string buffer overflow in ");
518  comment += function_name;
519  annotated_location.set_comment(comment);
520  dest.add(goto_programt::make_assertion(condition, annotated_location));
521 
522  // now kill the contents
523  invalidate_buffer(dest, target, argument, arg_type, token.field_width);
524 
525  args++;
526  break;
527  }
530  {
531  // nothing
532  break;
533  }
538  {
539  const exprt &argument = arguments[argument_start_inx + args];
540  const dereference_exprt lhs{argument};
541 
542  side_effect_expr_nondett rhs(lhs.type(), target->source_location());
543 
544  dest.add(
545  goto_programt::make_assignment(lhs, rhs, target->source_location()));
546 
547  args++;
548  break;
549  }
550  }
551  }
552  }
553  else // non-const format string
554  {
555  for(std::size_t i = argument_start_inx; i < arguments.size(); i++)
556  {
557  const typet &arg_type = arguments[i].type();
558 
559  // Note: is_string_type() is a `good guess' here. Actually
560  // any of the pointers could point into an array. But it
561  // would suck if we had to invalidate all variables.
562  // Luckily this case isn't needed too often.
563  if(is_string_type(arg_type))
564  {
565  // as we don't know any field width for the %s that
566  // should be here during runtime, we just report a
567  // possibly false positive
568  source_locationt annotated_location = target->source_location();
569  annotated_location.set_property_class("string");
570  std::string comment("format string buffer overflow in ");
571  comment += function_name;
572  annotated_location.set_comment(comment);
573  dest.add(
574  goto_programt::make_assertion(false_exprt(), annotated_location));
575 
576  invalidate_buffer(dest, target, arguments[i], arg_type, 0);
577  }
578  else
579  {
580  dereference_exprt lhs{arguments[i]};
581 
582  side_effect_expr_nondett rhs(lhs.type(), target->source_location());
583 
584  dest.add(
585  goto_programt::make_assignment(lhs, rhs, target->source_location()));
586  }
587  }
588  }
589 }
590 
592  goto_programt &,
594  const exprt &,
595  const exprt::operandst &)
596 {
597 }
598 
600  goto_programt &dest,
601  goto_programt::targett target,
602  const exprt &lhs,
603  const exprt::operandst &arguments)
604 {
605  if(arguments.size() != 2)
606  {
608  "strchr expected to have two arguments", target->source_location());
609  }
610 
611  source_locationt annotated_location = target->source_location();
612  annotated_location.set_property_class("string");
613  annotated_location.set_comment(
614  "zero-termination of string argument of strchr");
616  is_zero_string(arguments[0]), annotated_location);
617 
618  target->turn_into_skip();
619  dest.insert_before_swap(target, assertion);
620 }
621 
623  goto_programt &dest,
624  goto_programt::targett target,
625  const exprt &lhs,
626  const exprt::operandst &arguments)
627 {
628  if(arguments.size() != 2)
629  {
631  "strrchr expected to have two arguments", target->source_location());
632  }
633 
634  source_locationt annotated_location = target->source_location();
635  annotated_location.set_property_class("string");
636  annotated_location.set_comment(
637  "zero-termination of string argument of strrchr");
639  is_zero_string(arguments[0]), annotated_location);
640 
641  target->turn_into_skip();
642  dest.insert_before_swap(target, assertion);
643 }
644 
646  goto_programt &dest,
647  goto_programt::targett target,
648  const exprt &lhs,
649  const exprt::operandst &arguments)
650 {
651  if(arguments.size() != 2)
652  {
654  "strstr expected to have two arguments", target->source_location());
655  }
656 
657  goto_programt tmp;
658 
659  source_locationt annotated_location = target->source_location();
660  annotated_location.set_property_class("string");
661  annotated_location.set_comment(
662  "zero-termination of 1st string argument of strstr");
664  is_zero_string(arguments[0]), annotated_location));
665 
666  annotated_location.set_property_class("string");
667  annotated_location.set_comment(
668  "zero-termination of 2nd string argument of strstr");
670  is_zero_string(arguments[1]), annotated_location));
671 
672  target->turn_into_skip();
673  dest.insert_before_swap(target, tmp);
674 }
675 
677  goto_programt &dest,
678  goto_programt::targett target,
679  const exprt &lhs,
680  const exprt::operandst &arguments)
681 {
682  if(arguments.size() != 2)
683  {
685  "strtok expected to have two arguments", target->source_location());
686  }
687 
688  goto_programt tmp;
689 
690  source_locationt annotated_location = target->source_location();
691  annotated_location.set_property_class("string");
692  annotated_location.set_comment(
693  "zero-termination of 1st string argument of strtok");
695  is_zero_string(arguments[0]), annotated_location));
696 
697  annotated_location.set_property_class("string");
698  annotated_location.set_comment(
699  "zero-termination of 2nd string argument of strtok");
701  is_zero_string(arguments[1]), annotated_location));
702 
703  target->turn_into_skip();
704  dest.insert_before_swap(target, tmp);
705 }
706 
708  goto_programt &dest,
710  const exprt &lhs,
711  const exprt::operandst &arguments)
712 {
713  if(lhs.is_nil())
714  {
715  it->turn_into_skip();
716  return;
717  }
718 
719  irep_idt identifier_buf = "__strerror_buffer";
720  irep_idt identifier_size = "__strerror_buffer_size";
721 
722  if(symbol_table.symbols.find(identifier_buf) == symbol_table.symbols.end())
723  {
724  symbolt new_symbol_size{identifier_size, size_type(), ID_C};
725  new_symbol_size.base_name = identifier_size;
726  new_symbol_size.pretty_name = new_symbol_size.base_name;
727  new_symbol_size.is_state_var = true;
728  new_symbol_size.is_lvalue = true;
729  new_symbol_size.is_static_lifetime = true;
730 
731  array_typet type(char_type(), new_symbol_size.symbol_expr());
732  symbolt new_symbol_buf{identifier_buf, type, ID_C};
733  new_symbol_buf.is_state_var = true;
734  new_symbol_buf.is_lvalue = true;
735  new_symbol_buf.is_static_lifetime = true;
736  new_symbol_buf.base_name = identifier_buf;
737  new_symbol_buf.pretty_name = new_symbol_buf.base_name;
738 
739  symbol_table.insert(std::move(new_symbol_buf));
740  symbol_table.insert(std::move(new_symbol_size));
741  }
742 
743  const symbolt &symbol_size = ns.lookup(identifier_size);
744  const symbolt &symbol_buf = ns.lookup(identifier_buf);
745 
746  goto_programt tmp;
747 
748  {
749  exprt nondet_size =
750  side_effect_expr_nondett(size_type(), it->source_location());
752  code_assignt(symbol_size.symbol_expr(), nondet_size),
753  it->source_location()));
754 
757  symbol_size.symbol_expr(),
758  ID_notequal,
759  from_integer(0, symbol_size.type)),
760  it->source_location()));
761  }
762 
763  // return a pointer to some magic buffer
764  index_exprt index(
765  symbol_buf.symbol_expr(), from_integer(0, c_index_type()), char_type());
766 
767  address_of_exprt ptr(index);
768 
769  // make that zero-terminated
771  unary_exprt{"is_zero_string", ptr, c_bool_type()},
773  it->source_location()));
774 
775  // assign address
776  {
777  exprt rhs = typecast_exprt::conditional_cast(ptr, lhs.type());
779  code_assignt(lhs, rhs), it->source_location()));
780  }
781 
782  it->turn_into_skip();
783  dest.insert_before_swap(it, tmp);
784 }
785 
787  goto_programt &dest,
789  const exprt &buffer,
790  const typet &buf_type,
791  const mp_integer &limit)
792 {
793  irep_idt cntr_id = "string_instrumentation::$counter";
794 
795  if(symbol_table.symbols.find(cntr_id) == symbol_table.symbols.end())
796  {
797  symbolt new_symbol{cntr_id, size_type(), ID_C};
798  new_symbol.base_name = "$counter";
799  new_symbol.pretty_name = new_symbol.base_name;
800  new_symbol.is_state_var = true;
801  new_symbol.is_lvalue = true;
802  new_symbol.is_static_lifetime = true;
803 
804  symbol_table.insert(std::move(new_symbol));
805  }
806 
807  const symbolt &cntr_sym = ns.lookup(cntr_id);
808 
809  // create a loop that runs over the buffer
810  // and invalidates every element
811 
813  cntr_sym.symbol_expr(),
814  from_integer(0, cntr_sym.type),
815  target->source_location()));
816 
817  exprt bufp;
818 
819  if(buf_type.id() == ID_pointer)
820  bufp = buffer;
821  else
822  {
823  index_exprt index(
824  buffer,
826  to_type_with_subtype(buf_type).subtype());
827  bufp = address_of_exprt(index);
828  }
829 
830  exprt condition;
831 
832  if(limit == 0)
833  condition =
834  binary_relation_exprt(cntr_sym.symbol_expr(), ID_ge, buffer_size(bufp));
835  else
836  condition = binary_relation_exprt(
837  cntr_sym.symbol_expr(), ID_gt, from_integer(limit, unsigned_int_type()));
838 
839  goto_programt::targett check = dest.add(
841 
842  const plus_exprt b_plus_i(bufp, cntr_sym.symbol_expr());
843  const dereference_exprt deref(
844  b_plus_i, to_type_with_subtype(buf_type).subtype());
845 
846  const side_effect_expr_nondett nondet(
847  to_type_with_subtype(buf_type).subtype(), target->source_location());
848 
849  // invalidate
850  dest.add(
851  goto_programt::make_assignment(deref, nondet, target->source_location()));
852 
853  const plus_exprt plus(
854  cntr_sym.symbol_expr(), from_integer(1, unsigned_int_type()));
855 
857  cntr_sym.symbol_expr(), plus, target->source_location()));
858 
859  dest.add(
861 
863  dest.add(goto_programt::make_skip(target->source_location()));
864 
865  check->complete_goto(exit);
866 }
configt config
Definition: config.cpp:25
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:99
const T & as_const(T &value)
Return a reference to the same object but ensures the type is const.
Definition: as_const.h:14
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
unsignedbv_typet unsigned_int_type()
Definition: c_types.cpp:36
bitvector_typet char_type()
Definition: c_types.cpp:106
typet c_bool_type()
Definition: c_types.cpp:100
bitvector_typet c_index_type()
Definition: c_types.cpp:16
Operator to return the address of an object.
Definition: pointer_expr.h:540
Arrays with given size.
Definition: std_types.h:807
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition: std_expr.h:762
std::size_t get_width() const
Definition: std_types.h:925
A goto_instruction_codet representing an assignment in the program.
exprt::operandst argumentst
struct configt::ansi_ct ansi_c
Operator to dereference a pointer.
Definition: pointer_expr.h:834
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
Base class for all expressions.
Definition: expr.h:56
std::vector< exprt > operandst
Definition: expr.h:58
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
Definition: expr.h:163
const source_locationt & source_location() const
Definition: expr.h:231
typet & type()
Return the type of the expression.
Definition: expr.h:84
The Boolean constant false.
Definition: std_expr.h:3082
A collection of goto functions.
function_mapt function_map
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:31
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:34
This class represents an instruction in the GOTO intermediate representation.
Definition: goto_program.h:181
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:73
static instructiont make_assumption(const exprt &g, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:945
void insert_before_swap(targett target)
Insertion that preserves jumps to "target".
Definition: goto_program.h:643
instructionst::iterator targett
Definition: goto_program.h:614
instructionst::const_iterator const_targett
Definition: goto_program.h:615
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
static instructiont make_skip(const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:891
targett add(instructiont &&instruction)
Adds a given instruction at the end.
Definition: goto_program.h:739
static instructiont make_goto(targett _target, const source_locationt &l=source_locationt::nil())
static instructiont make_assertion(const exprt &g, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:933
static instructiont make_incomplete_goto(const exprt &_cond, const source_locationt &l=source_locationt::nil())
Array index operator.
Definition: std_expr.h:1470
Thrown when we can't handle something in an input source file.
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:412
bool is_not_nil() const
Definition: irep.h:372
const irep_idt & id() const
Definition: irep.h:388
bool is_nil() const
Definition: irep.h:368
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:148
Disequality.
Definition: std_expr.h:1425
The plus expression Associativity is not specified.
Definition: std_expr.h:1002
A side_effect_exprt that returns a non-deterministically chosen value.
Definition: std_code.h:1520
void set_comment(const irep_idt &comment)
void set_property_class(const irep_idt &property_class)
void do_strtok(goto_programt &dest, goto_programt::targett target, const exprt &lhs, const exprt::operandst &arguments)
void do_function_call(goto_programt &dest, goto_programt::targett target)
bool is_string_type(const typet &t) const
void operator()(goto_programt &dest)
void do_snprintf(goto_programt &dest, goto_programt::targett target, const exprt &lhs, const exprt::operandst &arguments)
string_instrumentationt(symbol_table_baset &_symbol_table)
void do_format_string_read(goto_programt &dest, goto_programt::const_targett target, const code_function_callt::argumentst &arguments, std::size_t format_string_inx, std::size_t argument_start_inx, const std::string &function_name)
symbol_table_baset & symbol_table
void do_strncmp(goto_programt &dest, goto_programt::targett it, const exprt &lhs, const exprt::operandst &arguments)
void do_sprintf(goto_programt &dest, goto_programt::targett target, const exprt &lhs, const exprt::operandst &arguments)
void do_strstr(goto_programt &dest, goto_programt::targett target, const exprt &lhs, const exprt::operandst &arguments)
void do_strerror(goto_programt &dest, goto_programt::targett it, const exprt &lhs, const exprt::operandst &arguments)
void do_format_string_write(goto_programt &dest, goto_programt::const_targett target, const code_function_callt::argumentst &arguments, std::size_t format_string_inx, std::size_t argument_start_inx, const std::string &function_name)
void do_fscanf(goto_programt &dest, goto_programt::targett target, const exprt &lhs, const exprt::operandst &arguments)
void instrument(goto_programt &dest, goto_programt::targett it)
void do_strcat(goto_programt &dest, goto_programt::targett it, const exprt &lhs, const exprt::operandst &arguments)
void do_strrchr(goto_programt &dest, goto_programt::targett target, const exprt &lhs, const exprt::operandst &arguments)
void invalidate_buffer(goto_programt &dest, goto_programt::const_targett target, const exprt &buffer, const typet &buf_type, const mp_integer &limit)
void do_strchr(goto_programt &dest, goto_programt::targett target, const exprt &lhs, const exprt::operandst &arguments)
const irep_idt & get_identifier() const
Definition: std_expr.h:160
The symbol table base class interface.
const symbolst & symbols
Read-only field, used to look up symbols given their names.
virtual std::pair< symbolt &, bool > insert(symbolt symbol)=0
Move or copy a new symbol to the symbol table.
Symbol table entry.
Definition: symbol.h:28
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
typet type
Type of symbol.
Definition: symbol.h:31
The Boolean constant true.
Definition: std_expr.h:3073
const typet & subtype() const
Definition: type.h:187
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2081
The type of an expression, extends irept.
Definition: type.h:29
const source_locationt & source_location() const
Definition: type.h:72
Generic base class for unary expressions.
Definition: std_expr.h:361
format_token_listt parse_format_string(const std::string &arg_string)
Format String Parser.
std::list< format_tokent > format_token_listt
Symbol Table + CFG.
#define Forall_goto_program_instructions(it, program)
const std::string & id2string(const irep_idt &d)
Definition: irep.h:44
API to expression classes for Pointers.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
Definition: pointer_expr.h:577
static std::string comment(const rw_set_baset::entryt &entry, bool write)
Definition: race_check.cpp:108
void remove_skip(goto_programt &goto_program, goto_programt::targett begin, goto_programt::targett end)
remove unnecessary skip statements
Definition: remove_skip.cpp:87
Program Transformation.
BigInt mp_integer
Definition: smt_terms.h:17
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:272
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1538
void exit(int status)
Definition: stdlib.c:102
const string_constantt & to_string_constant(const exprt &expr)
void string_instrumentation(symbol_table_baset &symbol_table, goto_programt &dest)
exprt buffer_size(const exprt &what)
exprt is_zero_string(const exprt &what, bool write)
exprt zero_string_length(const exprt &what, bool write)
String Abstraction.
std::size_t char_width
Definition: config.h:140
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition: type.h:208
ssize_t write(int fildes, const void *buf, size_t nbyte)
Definition: unistd.c:195
#define size_type
Definition: unistd.c:347