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