CBMC
Loading...
Searching...
No Matches
dfcc_library.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Dynamic frame condition checking
4
5Author: Remi Delmas, delmarsd@amazon.com
6
7\*******************************************************************/
8
9#include "dfcc_library.h"
10
11#include <util/arith_tools.h>
12#include <util/c_types.h>
13#include <util/config.h>
14#include <util/cprover_prefix.h>
15#include <util/format_type.h>
16#include <util/message.h>
17#include <util/pointer_expr.h>
19#include <util/std_code.h>
20#include <util/std_expr.h>
21
25
26#include <ansi-c/c_expr.h>
33
34#include "dfcc_utils.h"
35
37template <typename K, typename V>
38std::map<V, K> swap_map(std::map<K, V> const &map)
39{
40 std::map<V, K> result;
41 for(auto const &pair : map)
42 result.insert({pair.second, pair.first});
43 return result;
44}
45
46// NOLINTNEXTLINE(build/deprecated)
47#define CONTRACTS_PREFIX CPROVER_PREFIX "contracts_"
48
50const std::map<dfcc_typet, irep_idt> create_dfcc_type_to_name()
51{
52 return std::map<dfcc_typet, irep_idt>{
57 {dfcc_typet::PTR_PRED_CTX_PTR, CONTRACTS_PREFIX "ptr_pred_ctx_ptr_t"},
61 {dfcc_typet::WRITE_SET_PTR, CONTRACTS_PREFIX "write_set_ptr_t"}};
62}
63
64const std::map<dfcc_funt, irep_idt> create_dfcc_fun_to_name()
65{
66 return {
73 CONTRACTS_PREFIX "obj_set_create_indexed_by_object_id"},
75 CONTRACTS_PREFIX "obj_set_create_append"},
82 CONTRACTS_PREFIX "obj_set_contains_exact"},
86 CONTRACTS_PREFIX "write_set_insert_assignable"},
88 CONTRACTS_PREFIX "write_set_insert_object_whole"},
90 CONTRACTS_PREFIX "write_set_insert_object_from"},
92 CONTRACTS_PREFIX "write_set_insert_object_upto"},
94 CONTRACTS_PREFIX "write_set_add_freeable"},
96 CONTRACTS_PREFIX "write_set_add_allocated"},
97 {dfcc_funt::WRITE_SET_ADD_DECL, CONTRACTS_PREFIX "write_set_add_decl"},
99 CONTRACTS_PREFIX "write_set_record_dead"},
101 CONTRACTS_PREFIX "write_set_record_deallocated"},
103 CONTRACTS_PREFIX "write_set_check_allocated_deallocated_is_empty"},
105 CONTRACTS_PREFIX "write_set_check_assignment"},
107 CONTRACTS_PREFIX "write_set_check_array_set"},
109 CONTRACTS_PREFIX "write_set_check_array_copy"},
111 CONTRACTS_PREFIX "write_set_check_array_replace"},
113 CONTRACTS_PREFIX "write_set_check_havoc_object"},
115 CONTRACTS_PREFIX "write_set_check_deallocate"},
117 CONTRACTS_PREFIX "write_set_check_assigns_clause_inclusion"},
119 CONTRACTS_PREFIX "write_set_check_frees_clause_inclusion"},
121 CONTRACTS_PREFIX "write_set_deallocate_freeable"},
123 CONTRACTS_PREFIX "write_set_havoc_get_assignable_target"},
125 CONTRACTS_PREFIX "write_set_havoc_object_whole"},
127 CONTRACTS_PREFIX "write_set_havoc_slice"},
128 {dfcc_funt::LINK_PTR_PRED_CTX, CONTRACTS_PREFIX "link_ptr_pred_ctx"},
130 {dfcc_funt::LINK_DEALLOCATED, CONTRACTS_PREFIX "link_deallocated"},
131 {dfcc_funt::PTR_PRED_CTX_INIT, CONTRACTS_PREFIX "ptr_pred_ctx_init"},
132 {dfcc_funt::PTR_PRED_CTX_RESET, CONTRACTS_PREFIX "ptr_pred_ctx_reset"},
136 CONTRACTS_PREFIX "pointer_in_range_dfcc"},
140 CONTRACTS_PREFIX "check_replace_ensures_was_freed_preconditions"},
141 {dfcc_funt::OBEYS_CONTRACT, CONTRACTS_PREFIX "obeys_contract"}};
142}
143
153
154const std::map<irep_idt, dfcc_funt> create_havoc_hook()
155{
156 return {
157 {CPROVER_PREFIX "assignable",
162}
163
164const std::set<irep_idt> create_assignable_builtin_names()
165{
166 return {
167 CPROVER_PREFIX "assignable",
168 CPROVER_PREFIX "assignable_set_insert_assignable",
169 CPROVER_PREFIX "object_whole",
170 CPROVER_PREFIX "assignable_set_insert_object_whole",
171 CPROVER_PREFIX "object_from",
172 CPROVER_PREFIX "assignable_set_insert_object_from",
173 CPROVER_PREFIX "object_upto",
174 CPROVER_PREFIX "assignable_set_insert_object_upto",
175 CPROVER_PREFIX "freeable",
176 CPROVER_PREFIX "assignable_set_add_freeable"};
177}
178
181 goto_modelt &goto_model,
182 message_handlert &message_handler)
183 : goto_model(goto_model),
184 message_handler(message_handler),
185 log(message_handler),
186 dfcc_type_to_name(create_dfcc_type_to_name()),
187 dfcc_name_to_type(swap_map<dfcc_typet, irep_idt>(dfcc_type_to_name)),
188 dfcc_fun_to_name(create_dfcc_fun_to_name()),
189 dfcc_name_to_fun(swap_map<dfcc_funt, irep_idt>(dfcc_fun_to_name)),
190 dfcc_hook(create_dfcc_hook()),
191 havoc_hook(create_havoc_hook()),
192 assignable_builtin_names(create_assignable_builtin_names())
193{
194 // Add the instrumented map symbol to the symbol table.
196}
197
199bool dfcc_libraryt::is_front_end_builtin(const irep_idt &function_id) const
200{
201 return dfcc_hook.find(function_id) != dfcc_hook.end();
202}
203
206{
208 return dfcc_hook.find(function_id)->second;
209}
210
211// Returns the havoc function to use for a given front-end function
212std::optional<dfcc_funt>
214{
215 auto found = havoc_hook.find(function_id);
216 if(found != havoc_hook.end())
217 return {found->second};
218 else
219 return {};
220}
221
223{
224 sl.add_pragma("disable:pointer-check");
225 sl.add_pragma("disable:pointer-primitive-check");
226 sl.add_pragma("disable:pointer-overflow-check");
227 sl.add_pragma("disable:signed-overflow-check");
228 sl.add_pragma("disable:unsigned-overflow-check");
229 sl.add_pragma("disable:conversion-check");
230 sl.add_pragma("disable:undefined-shift-check");
231}
232
234{
235 for(const auto &pair : dfcc_fun_to_name)
236 {
237 auto &function = goto_model.goto_functions.function_map[pair.second];
238 for(auto &inst : function.body.instructions)
239 {
240 add_checked_pragmas(inst.source_location_nonconst());
241 }
242 }
243}
244
246{
247 std::set<irep_idt> missing;
248
249 // add `malloc` since it is needed used by the `is_fresh` function
250 missing.insert("malloc");
251
252 // add `free` and `__CPROVER_deallocate` since they are used by the
253 // `write_set_deallocate_freeable`
254 missing.insert("free");
255
256 // used by `write_set_release`
257 missing.insert(CPROVER_PREFIX "deallocate");
258
259 // Make sure all front end functions are loaded
260 missing.insert(CPROVER_PREFIX "assignable");
261 missing.insert(CPROVER_PREFIX "object_from");
262 missing.insert(CPROVER_PREFIX "object_upto");
263 missing.insert(CPROVER_PREFIX "object_whole");
264 missing.insert(CPROVER_PREFIX "freeable");
265
266 // go over all library functions
267 for(const auto &pair : dfcc_fun_to_name)
268 {
269 // check for an actual body in the goto functions map instead of relying
270 // on the symbol's value: a symbol may carry the `compiled` marker value
271 // even when its body was dropped, e.g. by `--drop-unused-functions`
273 missing.insert(pair.second);
274 }
275 return missing;
276}
277
278bool dfcc_libraryt::loaded = false;
279
282static bool code_types_match(const typet &lhs, const typet &rhs)
283{
284 if(lhs == rhs)
285 return true;
289 {
290 for(auto &parameter : code_type->parameters())
291 {
292 parameter.set_identifier(irep_idt{});
293 parameter.set_base_name(irep_idt{});
294 }
295 }
296 return lhs_code == rhs_code;
297}
298
299void dfcc_libraryt::load(std::set<irep_idt> &to_instrument)
300{
302 !loaded, "the cprover_contracts library can only be loaded once");
303 loaded = true;
304
305 log.status() << "Adding the cprover_contracts library (" << config.ansi_c.arch
306 << ")" << messaget::eom;
307
308 // these will need to get instrumented as well
309 to_instrument.insert("malloc");
310 to_instrument.insert("free");
311 to_instrument.insert(CPROVER_PREFIX "deallocate");
312
313 std::set<irep_idt> to_load;
314
315 // add the whole library
316 to_load.insert(CPROVER_PREFIX "contracts_library");
317
318 // add front end functions
319 to_load.insert(CPROVER_PREFIX "assignable");
320 to_load.insert(CPROVER_PREFIX "object_from");
321 to_load.insert(CPROVER_PREFIX "object_upto");
322 to_load.insert(CPROVER_PREFIX "object_whole");
323 to_load.insert(CPROVER_PREFIX "freeable");
324
325 // add stdlib dependences
326 to_load.insert("malloc");
327 to_load.insert("free");
328 to_load.insert(CPROVER_PREFIX "deallocate");
329
333
334 // compute missing library functions before modifying the symbol table
335 std::set<irep_idt> missing = get_missing_funs();
336
337 // Copy all loaded symbols to the main symbol table. Functions that already
338 // exist in the model but have no body in the goto functions map are
339 // completed using the library implementation: the model may declare, say,
340 // `free` (via stdlib.h) without its body ever being linked in when all
341 // calls to it are unreachable from the entry point, or a body may have
342 // been removed by `--drop-unused-functions`, which leaves the symbol value
343 // set to the `compiled` marker. The DFCC library requires the
344 // implementations of the functions loaded above in either case. Symbols
345 // whose value holds a not-yet-converted body are left alone.
346 for(const auto &symbol_pair : tmp_symbol_table.symbols)
347 {
350 if(
351 !insert_result.second && symbol_pair.second.type.id() == ID_code &&
352 symbol_pair.second.value.is_not_nil() && existing.type.id() == ID_code &&
353 (existing.value.is_nil() || existing.is_compiled()) &&
355 goto_model, symbol_pair.first))
356 {
357 if(!code_types_match(existing.type, symbol_pair.second.type))
358 {
359 log.warning() << "dfcc_libraryt::load: replacing declaration of '"
360 << symbol_pair.first << "' of type '"
361 << format(existing.type)
362 << "' with the CPROVER library implementation of type '"
363 << format(symbol_pair.second.type) << "'"
364 << messaget::eom;
365 }
366 existing.type = symbol_pair.second.type;
367 existing.value = symbol_pair.second.value;
368 }
369 }
370
371 // compile all missing library functions to GOTO
372 for(const auto &id : missing)
373 {
377 }
378
379 // check that all symbols have a goto_implementation
380 // and populate symbol maps
382 for(const auto &pair : dfcc_fun_to_name)
383 {
384 const auto &found =
386
387 INVARIANT(
389 found->second.body_available(),
390 "The body of DFCC library function " + id2string(pair.second) +
391 " could not be found");
392
393 dfcc_fun_symbol[pair.first] = ns.lookup(pair.second);
394 }
395
396 // populate symbol maps for easy access to symbols during translation
397 for(const auto &pair : dfcc_type_to_name)
398 {
399 dfcc_type[pair.first] = ns.lookup(pair.second).type;
400 }
401
402 // fix malloc and free calls
404
405 // inline the functions that need to be inlined for perf reasons
407
408 // hide all instructions in counter example traces
409 for(auto it : dfcc_fun_symbol)
410 goto_model.goto_functions.function_map.at(it.second.name).make_hidden();
411}
412
413std::optional<dfcc_funt> dfcc_libraryt::get_dfcc_fun(const irep_idt &id) const
414{
415 auto found = dfcc_name_to_fun.find(id);
416 if(found != dfcc_name_to_fun.end())
417 return {found->second};
418 else
419 return {};
420}
421
423{
424 return get_dfcc_fun(id).has_value();
425}
426
431
451
452bool dfcc_libraryt::inlined = false;
453
455{
456 INVARIANT(!inlined, "inline_functions can only be called once");
457 inlined = true;
458 for(const auto &function_id : to_inline)
459 {
462 }
463}
464
474
475bool dfcc_libraryt::specialized = false;
476
478{
479 INVARIANT(
481 "dfcc_libraryt::specialize_functions can only be called once");
482
483 specialized = true;
484 std::list<std::string> loop_names;
485
486 for(const auto &entry : to_unwind)
487 {
488 const auto &function = entry.first;
489 const auto &loop_id = entry.second;
490 std::stringstream stream;
491 stream << id2string(dfcc_fun_to_name.at(function)) << "." << loop_id << ":"
493 const auto &str = stream.str();
494 loop_names.push_back(str);
495 }
496 unwindsett unwindset;
497 unwindset.parse_unwindset(loop_names, goto_model, message_handler);
501}
502
507
510
512{
513 INVARIANT(
515 "dfcc_libraryt::fix_malloc_free_calls can only be called once");
516 malloc_free_fixed = true;
517 for(const auto fun : fix_malloc_free_set)
518 {
521
523 {
524 if(ins->is_function_call())
525 {
526 const auto &function = ins->call_function();
527
528 if(function.id() == ID_symbol)
529 {
530 const irep_idt &fun_name = to_symbol_expr(function).identifier();
531
532 if(fun_name == (CONTRACTS_PREFIX "malloc"))
533 to_symbol_expr(ins->call_function()).identifier("malloc");
534 else if(fun_name == (CONTRACTS_PREFIX "free"))
535 to_symbol_expr(ins->call_function()).identifier("free");
536 }
537 }
538 }
539 }
540}
541
543{
544 // not using assume-false in order not to hinder coverage
545 std::string options = "assert-false";
546 c_object_factory_parameterst object_factory_params;
548 options, object_factory_params, goto_model.symbol_table, message_handler);
549 for(const auto &it : dfcc_hook)
550 {
551 const auto &function_id = it.first;
552 if(goto_model.symbol_table.has_symbol(function_id))
553 {
554 auto &goto_function =
555 goto_model.goto_functions.function_map.at(function_id);
556
557 generate_function_bodies->generate_function_body(
558 goto_function, goto_model.symbol_table, function_id);
559 }
560 }
561}
562
564{
565 const irep_idt map_name = "__dfcc_instrumented_functions";
566
569
570 auto map_type =
572
575 map_type,
576 "",
577 "__dfcc_instrumented_functions",
579 ID_C,
580 "<built-in-library>",
581 array_of_exprt(from_integer(0, map_type.element_type()), map_type),
582 true);
583}
584
586 const std::set<irep_idt> &instrumented_functions,
587 const source_locationt &source_location,
588 goto_programt &dest)
589{
592
593 std::map<std::string, irep_idt> sorted_instrumented_functions;
594 for(const auto &function_id : instrumented_functions)
595 sorted_instrumented_functions.insert({id2string(function_id), function_id});
596
597 for(const auto &[_, function_id] : sorted_instrumented_functions)
598 {
600 dfcc_utilst::get_function_symbol(goto_model.symbol_table, function_id)
601 .symbol_expr()));
604 index_expr, from_integer(1, unsigned_char_type()), source_location));
605 }
606 goto_model.goto_functions.update();
607}
608
611 const exprt &max_assigns_clause_size,
613 const exprt &assume_requires_ctx,
614 const exprt &assert_requires_ctx,
615 const exprt &assume_ensures_ctx,
616 const exprt &assert_ensures_ctx,
617 const exprt &allow_allocate,
618 const exprt &allow_deallocate,
619 const source_locationt &source_location)
620{
621 auto function_symbol =
624 auto &arguments = call.arguments();
625 // check that address_of_write_set.type() is dfcc_typet::WRITE_SET_PTR
626 arguments.emplace_back(address_of_write_set);
627 PRECONDITION(max_assigns_clause_size.type() == size_type());
628 arguments.emplace_back(max_assigns_clause_size);
630 arguments.emplace_back(max_frees_clause_size);
631 arguments.push_back(assume_requires_ctx);
632 arguments.push_back(assert_requires_ctx);
633 arguments.push_back(assume_ensures_ctx);
634 arguments.push_back(assert_ensures_ctx);
635 arguments.push_back(allow_allocate);
636 arguments.push_back(allow_deallocate);
637 call.add_source_location() = source_location;
638 return call;
639}
640
643 const exprt &max_assigns_clause_size,
644 const source_locationt &source_location)
645{
648 max_assigns_clause_size,
650 false_exprt(),
651 false_exprt(),
652 false_exprt(),
653 false_exprt(),
654 false_exprt(),
655 false_exprt(),
656 source_location);
657}
658
660 const exprt &write_set_ptr,
661 const source_locationt &source_location)
662{
665 {write_set_ptr});
666 call.add_source_location() = source_location;
667 return call;
668}
669
671 const exprt &write_set_ptr,
672 const exprt &ptr,
673 const source_locationt &source_location)
674{
677 {write_set_ptr, ptr});
678 call.add_source_location() = source_location;
679 return call;
680}
681
683 const exprt &write_set_ptr,
684 const exprt &ptr,
685 const source_locationt &source_location)
686{
689 {write_set_ptr, ptr});
690 call.add_source_location() = source_location;
691 return call;
692}
693
695 const exprt &write_set_ptr,
696 const exprt &ptr,
697 const source_locationt &source_location)
698{
701 {write_set_ptr, ptr});
702 call.add_source_location() = source_location;
703 return call;
704}
705
707 const exprt &write_set_ptr,
708 const exprt &ptr,
709 const source_locationt &source_location)
710{
713 {write_set_ptr, ptr});
714 call.add_source_location() = source_location;
715 return call;
716}
717
720 const exprt &check_var,
721 const exprt &write_set_ptr,
722 const source_locationt &source_location)
723{
725 check_var,
727 .symbol_expr(),
728 {write_set_ptr});
729 call.add_source_location() = source_location;
730 return call;
731}
732
734 const exprt &check_var,
735 const exprt &write_set_ptr,
736 const exprt &ptr,
737 const exprt &size,
738 const source_locationt &source_location)
739{
741 check_var,
743 {write_set_ptr, ptr, size});
744 call.add_source_location() = source_location;
745 return call;
746}
747
749 const exprt &check_var,
750 const exprt &write_set_ptr,
751 const exprt &dest,
752 const source_locationt &source_location)
753{
755 check_var,
757 {write_set_ptr, dest});
758 call.add_source_location() = source_location;
759 return call;
760}
761
763 const exprt &check_var,
764 const exprt &write_set_ptr,
765 const exprt &dest,
766 const source_locationt &source_location)
767{
769 check_var,
771 {write_set_ptr, dest});
772 call.add_source_location() = source_location;
773 return call;
774}
775
777 const exprt &check_var,
778 const exprt &write_set_ptr,
779 const exprt &dest,
780 const exprt &src,
781 const source_locationt &source_location)
782{
784 check_var,
786 {write_set_ptr, dest, src});
787 call.add_source_location() = source_location;
788 return call;
789}
790
792 const exprt &check_var,
793 const exprt &write_set_ptr,
794 const exprt &ptr,
795 const source_locationt &source_location)
796{
798 check_var,
800 {write_set_ptr, ptr});
801 call.add_source_location() = source_location;
802 return call;
803}
804
806 const exprt &check_var,
807 const exprt &write_set_ptr,
808 const exprt &ptr,
809 const source_locationt &source_location)
810{
812 check_var,
814 {write_set_ptr, ptr});
815 call.add_source_location() = source_location;
816 return call;
817}
818
834
850
852 const exprt &write_set_ptr,
854 const source_locationt &source_location)
855{
859 call.add_source_location() = source_location;
860 return call;
861}
862
864 const exprt &write_set_ptr,
865 const exprt &ptr_pred_ctx_ptr,
866 const source_locationt &source_location)
867{
871 call.add_source_location() = source_location;
872 return call;
873}
874
878 const source_locationt &source_location)
879{
883 call.add_source_location() = source_location;
884 return call;
885}
886
890 const source_locationt &source_location)
891{
895 call.add_source_location() = source_location;
896 return call;
897}
898
901 const exprt &ptr,
902 const exprt &write_set_ptr,
903 const source_locationt &source_location)
904{
907 .symbol_expr(),
908 {ptr, write_set_ptr});
909 call.add_source_location() = source_location;
910 return call;
911}
912
915 const exprt &obj_set_ptr,
916 const source_locationt &source_location)
917{
920 .symbol_expr(),
921 {obj_set_ptr});
922 call.add_source_location() = source_location;
923 return call;
924}
925
927 const exprt &obj_set_ptr,
928 const source_locationt &source_location)
929{
932 call.add_source_location() = source_location;
933 return call;
934}
935
937 const exprt &ptr_pred_ctx_ptr,
938 const source_locationt &source_location)
939{
943 call.add_source_location() = source_location;
944 return call;
945}
946
948 const exprt &ptr_pred_ctx_ptr,
949 const source_locationt &source_location)
950{
954 call.add_source_location() = source_location;
955 return call;
956}
void cprover_c_library_factory_force_load(const std::set< irep_idt > &functions, symbol_table_baset &symbol_table, message_handlert &message_handler)
Load the requested function symbols from the cprover library and add them to the symbol table regardl...
configt config
Definition config.cpp:25
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
API to expression classes that are internal to the C frontend.
unsignedbv_typet unsigned_char_type()
Definition c_types.cpp:127
Operator to return the address of an object.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:566
Array constructor from single element.
Definition std_expr.h:1512
Arrays with given size.
Definition std_types.h:806
goto_instruction_codet representation of a function call statement.
Base type of functions.
Definition std_types.h:582
struct configt::ansi_ct ansi_c
const code_function_callt write_set_record_dead_call(const exprt &write_set_ptr, const exprt &ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_record_dead.
const std::map< irep_idt, dfcc_funt > havoc_hook
Maps front-end functions to library functions giving their havoc semantics.
const code_function_callt write_set_check_allocated_deallocated_is_empty_call(const exprt &check_var, const exprt &write_set_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_check_allocated_deallocated_is_empty.
const code_function_callt obj_set_create_indexed_by_object_id_call(const exprt &obj_set_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_obj_set_create_indexed_by_object_id.
static bool inlined
True iff the library functions are inlined.
const std::map< irep_idt, dfcc_funt > dfcc_hook
Maps built-in function names to enums to use for instrumentation.
const code_function_callt write_set_check_assignment_call(const exprt &check_var, const exprt &write_set_ptr, const exprt &ptr, const exprt &size, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_check_assignment.
static bool loaded
True iff the contracts library symbols are loaded.
dfcc_libraryt(goto_modelt &goto_model, message_handlert &lmessage_handler)
Class constructor.
void fix_malloc_free_calls()
Fixes function calls to malloc and free in library functions.
static bool malloc_free_fixed
True iff the library functions uses of malloc and free are fixed.
bool is_front_end_builtin(const irep_idt &function_id) const
Returns true iff the given function_id is one of __CPROVER_assignable, __CPROVER_object_whole,...
const code_function_callt link_allocated_call(const exprt &write_set_postconditions_ptr, const exprt &write_set_to_link_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_link_allocated.
const code_function_callt write_set_record_deallocated_call(const exprt &write_set_ptr, const exprt &ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_record_deallocated.
const code_function_callt write_set_add_decl_call(const exprt &write_set_ptr, const exprt &ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_add_decl.
void inline_functions()
Inlines library functions that need to be inlined before use.
const code_function_callt write_set_check_array_copy_call(const exprt &check_var, const exprt &write_set_ptr, const exprt &dest, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_check_array_copy.
const code_function_callt link_ptr_pred_ctx_call(const exprt &write_set_ptr, const exprt &ptr_pred_ctx_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_link_ptr_pred_ctx.
const code_function_callt write_set_add_allocated_call(const exprt &write_set_ptr, const exprt &ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_add_allocated.
std::optional< dfcc_funt > get_dfcc_fun(const irep_idt &id) const
Returns the dfcc_funt that corresponds to the given id if any.
void add_instrumented_functions_map_init_instructions(const std::set< irep_idt > &instrumented_functions, const source_locationt &source_location, goto_programt &dest)
Generates instructions to initialize the instrumented function map symbol from the given set of instr...
const std::map< dfcc_typet, irep_idt > dfcc_type_to_name
Enum to type name mapping.
const symbolt & get_instrumented_functions_map_symbol()
Returns the "__dfcc_instrumented_functions" symbol or creates it if it does not exist already.
const std::map< dfcc_funt, irep_idt > dfcc_fun_to_name
enum to function name mapping
const std::map< irep_idt, dfcc_funt > dfcc_name_to_fun
const code_function_callt write_set_check_array_set_call(const exprt &check_var, const exprt &write_set_ptr, const exprt &dest, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_check_array_set.
const code_function_callt write_set_check_array_replace_call(const exprt &check_var, const exprt &write_set_ptr, const exprt &dest, const exprt &src, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_check_array_replace.
const code_function_callt write_set_release_call(const exprt &write_set_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_release.
const code_function_callt ptr_pred_ctx_init_call(const exprt &ptr_pred_ctx_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_ptr_pred_ctx_init.
void inhibit_front_end_builtins()
Adds an ASSERT(false) body to all front-end functions __CPROVER_object_whole __CPROVER_object_upto __...
const code_function_callt obj_set_release_call(const exprt &obj_set_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_obj_set_release.
const irep_idt & get_dfcc_fun_name(dfcc_funt fun) const
Returns the name of the given dfcc_funt.
dfcc_funt get_hook(const irep_idt &function_id) const
Returns the library instrumentation hook for the given front-end function.
const code_function_callt ptr_pred_ctx_reset_call(const exprt &ptr_pred_ctx_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_ptr_pred_ctx_init.
bool is_dfcc_library_symbol(const irep_idt &id) const
True iff the given id is one of the library symbols.
const code_function_callt write_set_check_deallocate_call(const exprt &check_var, const exprt &write_set_ptr, const exprt &ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_check_deallocate.
const code_function_callt link_deallocated_call(const exprt &write_set_postconditions_ptr, const exprt &write_set_to_link_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_link_deallocated.
goto_modelt & goto_model
const code_function_callt write_set_check_assigns_clause_inclusion_call(const exprt &check_var, const exprt &reference_write_set_ptr, const exprt &candidate_write_set_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_check_assigns_clause_inclusion.
message_handlert & message_handler
std::map< dfcc_typet, typet > dfcc_type
Maps enum values to the actual types (dynamically loaded)
std::set< irep_idt > get_missing_funs()
Collects the names of all library functions currently missing from the goto_model into missing.
const code_function_callt write_set_create_call(const exprt &write_set_ptr, const exprt &contract_assigns_size, const exprt &contract_frees_size, const exprt &assume_requires_ctx, const exprt &assert_requires_ctx, const exprt &assume_ensures_ctx, const exprt &assert_ensures_ctx, const exprt &allow_allocate, const exprt &allow_deallocate, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_create.
const code_function_callt write_set_check_frees_clause_inclusion_call(const exprt &check_var, const exprt &reference_write_set_ptr, const exprt &candidate_write_set_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_check_frees_clause_inclusion.
const code_function_callt write_set_check_havoc_object_call(const exprt &check_var, const exprt &write_set_ptr, const exprt &ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_check_havoc_object.
void disable_checks()
Adds "checked" pragmas to instructions of all library functions instructions.
const code_function_callt check_replace_ensures_was_freed_preconditions_call(const exprt &ptr, const exprt &write_set_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_check_replace_ensures_was_freed_preconditions.
const code_function_callt write_set_deallocate_freeable_call(const exprt &write_set_ptr, const exprt &target_write_set_ptr, const source_locationt &source_location)
Builds call to __CPROVER_contracts_write_set_deallocate_freeable.
void specialize(const std::size_t contract_assigns_size_hint)
Specializes the library by unwinding loops in library functions to the given assigns clause size.
std::map< dfcc_funt, symbolt > dfcc_fun_symbol
Maps enum values to the actual function symbols (dynamically loaded)
std::optional< dfcc_funt > get_havoc_hook(const irep_idt &function_id) const
Returns the library instrumentation hook for the given built-in.
void load(std::set< irep_idt > &to_instrument)
After calling this function, all library types and functions are present in the the goto_model.
static bool specialized
True iff the library functions are specialized to a particular contract.
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:57
typet & type()
Return the type of the expression.
Definition expr.h:85
The Boolean constant false.
Definition std_expr.h:3135
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
A generic container class for the GOTO intermediate representation of one function.
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
Array index operator.
Definition std_expr.h:1431
An expression denoting infinity.
Definition std_expr.h:3160
mstreamt & warning() const
Definition message.h:406
static eomt eom
Definition message.h:289
mstreamt & status() const
Definition message.h:416
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
The symbol table.
virtual std::pair< symbolt &, bool > insert(symbolt symbol) override
Author: Diffblue Ltd.
Symbol table entry.
Definition symbol.h:28
void set_compiled()
Set the symbol's value to "compiled"; to be used once the code-typed value has been converted to a go...
Definition symbol.h:120
The type of an expression, extends irept.
Definition type.h:29
void parse_unwindset(const std::list< std::string > &unwindset, abstract_goto_modelt &goto_model, message_handlert &message_handler)
#define CPROVER_PREFIX
#define CONTRACTS_PREFIX
const std::map< irep_idt, dfcc_funt > create_havoc_hook()
static const std::set< dfcc_funt > to_inline
set of functions that need to be inlined
const std::map< dfcc_funt, irep_idt > create_dfcc_fun_to_name()
const std::set< irep_idt > create_assignable_builtin_names()
static void add_checked_pragmas(source_locationt &sl)
const std::map< dfcc_typet, irep_idt > create_dfcc_type_to_name()
Creates the enum to type name mapping.
std::map< V, K > swap_map(std::map< K, V > const &map)
Swaps keys and values in a map.
static const std::set< dfcc_funt > fix_malloc_free_set
Set of functions that contain calls to assignable_malloc or assignable_free.
static const std::map< dfcc_funt, int > to_unwind
set of functions that need to be unwound to assigns clause size with corresponding loop identifiers.
static bool code_types_match(const typet &lhs, const typet &rhs)
Returns true iff the two code types are equal when ignoring parameter identifiers and base names.
const std::map< irep_idt, dfcc_funt > create_dfcc_hook()
Dynamic frame condition checking library loading.
dfcc_funt
One enum value per function defined by the cprover_dfcc.c library file.
@ WRITE_SET_INSERT_OBJECT_UPTO
@ CAR_SET_CONTAINS
@ WRITE_SET_CHECK_ASSIGNMENT
@ WRITE_SET_INSERT_ASSIGNABLE
@ WRITE_SET_CHECK_FREES_CLAUSE_INCLUSION
@ POINTER_IN_RANGE_DFCC
@ OBJ_SET_CREATE_APPEND
@ WRITE_SET_RELEASE
@ WRITE_SET_INSERT_OBJECT_WHOLE
@ WRITE_SET_DEALLOCATE_FREEABLE
@ WRITE_SET_CHECK_ARRAY_REPLACE
@ LINK_DEALLOCATED
@ WRITE_SET_CHECK_HAVOC_OBJECT
@ OBJ_SET_CREATE_INDEXED_BY_OBJECT_ID
@ WRITE_SET_CHECK_DEALLOCATE
@ PTR_PRED_CTX_RESET
@ PTR_PRED_CTX_INIT
@ WRITE_SET_CHECK_ALLOCATED_DEALLOCATED_IS_EMPTY
@ WRITE_SET_CHECK_ARRAY_SET
@ WRITE_SET_RECORD_DEAD
@ WRITE_SET_HAVOC_SLICE
@ WRITE_SET_CHECK_ASSIGNS_CLAUSE_INCLUSION
@ WRITE_SET_HAVOC_GET_ASSIGNABLE_TARGET
@ OBJ_SET_CONTAINS
@ WRITE_SET_CREATE
@ WRITE_SET_CHECK_ARRAY_COPY
@ WRITE_SET_ADD_FREEABLE
@ REPLACE_ENSURES_WAS_FREED_PRECONDITIONS
@ WRITE_SET_ADD_DECL
@ LINK_PTR_PRED_CTX
@ WRITE_SET_RECORD_DEALLOCATED
@ OBJ_SET_CONTAINS_EXACT
@ WRITE_SET_ADD_ALLOCATED
@ WRITE_SET_HAVOC_OBJECT_WHOLE
@ WRITE_SET_INSERT_OBJECT_FROM
dfcc_typet
One enum value per type defined by the cprover_dfcc.c library file.
@ WRITE_SET
type of descriptors of assignable/freeable sets of locations
@ PTR_PRED_CTX_PTR
type of pointers to context info for pointer predicates evaluation
@ CAR_SET_PTR
type of pointers to sets of CAR
@ CAR_SET
type of sets of CAR
@ OBJ_SET_PTR
type of pointers to sets of object identifiers
@ PTR_PRED_CTX
type of context info for pointer predicates evaluation
@ OBJ_SET
type of sets of object identifiers
@ WRITE_SET_PTR
type of pointers to descriptors of assignable/freeable sets of locations
@ CAR
type of descriptors of conditionally assignable ranges of bytes
Dynamic frame condition checking utility functions.
static format_containert< T > format(const T &o)
Definition format.h:37
std::unique_ptr< generate_function_bodiest > generate_function_bodies_factory(const std::string &options, const c_object_factory_parameterst &object_factory_parameters, const symbol_tablet &symbol_table, message_handlert &message_handler)
Create the type that actually generates the functions.
void generate_function_bodies(const std::regex &functions_regex, const generate_function_bodiest &generate_function_body, goto_modelt &model, message_handlert &message_handler, bool ignore_no_match)
Generate function bodies with some default behavior: assert-false, assume-false, assert-false-assume-...
void goto_convert(const codet &code, symbol_table_baset &symbol_table, goto_programt &dest, message_handlert &message_handler, const irep_idt &mode)
Goto Programs with Functions.
Goto Function.
Symbol Table + CFG.
#define Forall_goto_program_instructions(it, program)
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
double log(double x)
Definition math.c:2416
API to expression classes for Pointers.
exprt pointer_object(const exprt &p)
Various predicates over pointers in programs.
#define PRECONDITION_WITH_DIAGNOSTICS(CONDITION,...)
Definition invariant.h:464
#define PRECONDITION(CONDITION)
Definition invariant.h:463
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
API to expression classes.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:221
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition std_types.h:787
static symbolt & get_function_symbol(symbol_table_baset &, const irep_idt &function_id)
Returns the symbolt for function_id.
static void inline_function(goto_modelt &goto_model, const irep_idt &function_id, message_handlert &message_handler)
Inlines the given function, aborts on recursive calls during inlining.
static bool function_symbol_with_body_exists(const goto_modelt &, const irep_idt &function_id)
static const symbolt & create_static_symbol(symbol_table_baset &, const typet &type, const std::string &prefix, const std::string &base_name, const source_locationt &source_location, const irep_idt &mode, const irep_idt &module, const exprt &initial_value, const bool no_nondet_initialization=true)
Adds a new static symbol named prefix::base_name of type type with value initial_value in the symbol ...
#define size_type
Definition unistd.c:186
Loop unwinding.
Loop unwinding.