-
Notifications
You must be signed in to change notification settings - Fork 27
SV-COMP fixes #157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
SV-COMP fixes #157
Changes from 10 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
deceb82
Update CBMC prerequisites
viktormalik 6318811
Fix dynobj_instance_analysis
viktormalik eff6f0f
Workaround problem with GOTO targets
viktormalik c88cdd7
SSA: drop conditional update of dynamic objects
viktormalik 090c38d
Correctly add allocation guards
FrNecas bc5b1da
Heap: improve obtaining pointed object from solver
viktormalik 646ac5d
Fix collection of free::record vars
viktormalik 25f05f5
malloc: fix getting malloc size
viktormalik 5a63242
Fix assert to limit array size
viktormalik 2c45caf
Disable unsupported operations in competition mode
viktormalik 11606bc
Configure gcc preprocessing to fix linking
FrNecas 12cc730
Correctly guard hoisted assertions
FrNecas 3f21ab9
Fix workaround for signed shl
FrNecas 9071c90
Propagate #concrete for byte-array dynamic objs
viktormalik File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Submodule cbmc
updated
3 files
| +7 −3 | src/analyses/goto_check.cpp | |
| +2 −0 | src/goto-programs/graphml_witness.cpp | |
| +0 −10 | src/xmllang/graphml.cpp |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,35 +1,6 @@ | ||
| KNOWNBUG | ||
| CORE | ||
| main.c | ||
| --heap --intervals --pointer-check --no-assertions | ||
| ^EXIT=0$ | ||
| ^SIGNAL=0$ | ||
| ^VERIFICATION SUCCESSFUL$ | ||
| -- | ||
| -- | ||
| CBMC 5.9 introduced changes to its implementation of some built-in functions, | ||
| the ones affecting this test are malloc and free. Malloc changes have been | ||
| already accounted for in 2LS codebase, however the control flow of free | ||
| is most likely causing problems in this test making one of the asserts fail: | ||
|
|
||
| [main.pointer_dereference.27] dereference failure: deallocated dynamic object in *p: UNKNOWN | ||
|
|
||
| This may be related to double free assertion, where GOTO changed from: | ||
|
|
||
| ... | ||
| IF !(__CPROVER_deallocated == ptr) THEN GOTO 6 | ||
| // 144 file <builtin-library-free> line 18 function free | ||
| ASSERT 0 != 0 // double free | ||
| // 145 no location | ||
| ASSUME 0 != 0 | ||
| // 146 file <builtin-library-free> line 29 function free | ||
| 6: _Bool record; | ||
| ... | ||
|
|
||
| to: | ||
| ASSERT ptr == NULL || __CPROVER_deallocated != ptr // double free | ||
|
|
||
| Note the new ptr == NULL condition, this could be the root cause of | ||
| the problem. However further investigation is required | ||
| and will be done once the CBMC rebase is completed. According to the | ||
| C standard, free(NULL) is a valid construct (no operation) but 2LS doesn't | ||
| seem to handle this case correctly. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| void *my_malloc(unsigned int size) { | ||
| return malloc(size); | ||
| } | ||
|
|
||
| int main() { | ||
| void *a = my_malloc(sizeof(int)); | ||
| free(a); | ||
| free(a); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| CORE | ||
| main.c | ||
| --pointer-check --inline | ||
| ^EXIT=10$ | ||
| ^SIGNAL=0$ | ||
| ^VERIFICATION FAILED$ | ||
| \[free.precondition.6\] free argument must be NULL or valid pointer: FAILURE |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,36 +1,6 @@ | ||
| KNOWNBUG | ||
| CORE | ||
| main.c | ||
| --heap --intervals --pointer-check --no-assertions | ||
| ^EXIT=0$ | ||
| ^SIGNAL=0$ | ||
| ^VERIFICATION SUCCESSFUL$ | ||
| -- | ||
| -- | ||
| CBMC 5.9 introduced changes to its implementation of some built-in functions, | ||
| the ones affecting this test are malloc and free. Malloc changes have been | ||
| already accounted for in 2LS codebase, however the control flow of free | ||
| is most likely causing problems in this test making one of the asserts fail: | ||
|
|
||
| [main.pointer_dereference.27] dereference failure: deallocated dynamic object in *p: UNKNOWN | ||
|
|
||
| This may be related to double free assertion, where GOTO changed from: | ||
|
|
||
| ... | ||
| IF !(__CPROVER_deallocated == ptr) THEN GOTO 6 | ||
| // 144 file <builtin-library-free> line 18 function free | ||
| ASSERT 0 != 0 // double free | ||
| // 145 no location | ||
| ASSUME 0 != 0 | ||
| // 146 file <builtin-library-free> line 29 function free | ||
| 6: _Bool record; | ||
| ... | ||
|
|
||
| to: | ||
| ASSERT ptr == NULL || __CPROVER_deallocated != ptr // double free | ||
|
|
||
| Note the new ptr == NULL condition, this could be the root cause of | ||
| the problem. However further investigation is required | ||
| and will be done once the CBMC rebase is completed. According to the | ||
| C standard, free(NULL) is a valid construct (no operation) but 2LS doesn't | ||
| seem to handle this case correctly. | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ Author: Daniel Kroening, [email protected] | |
| #include <util/expr_util.h> | ||
| #include <util/pointer_expr.h> | ||
| #include <util/byte_operators.h> | ||
| #include <util/optional.h> | ||
| #include <solvers/decision_procedure.h> | ||
|
|
||
| #include <goto-programs/adjust_float_expressions.h> | ||
|
|
@@ -50,6 +51,9 @@ void local_SSAt::build_SSA() | |
| build_function_call(i_it); | ||
| // build_unknown_objs(i_it); | ||
| collect_record_frees(i_it); | ||
|
|
||
| if (options.get_bool_option("competition-mode")) | ||
| disable_unsupported_instructions(i_it); | ||
| } | ||
|
|
||
| // collect custom templates in loop heads | ||
|
|
@@ -883,17 +887,18 @@ exprt local_SSAt::read_rhs_rec(const exprt &expr, locationt loc) const | |
| { | ||
| // If the last definition of an object is at its allocation, we can only use | ||
| // the corresponding symbol if the object has truly been allocated | ||
| // (allocation guard holds). Otherwise we need to use the last definition | ||
| // before the allocation. | ||
| // (allocation guard holds). After the rebase to a newer version of CBMC, | ||
| // the last definition may also be a PHI node at the end of malloc ( | ||
| // which covers the case-split whether malloc can fail). | ||
| // Otherwise we need to use the last definition before the allocation. | ||
| auto def_it=ssa_analysis[loc].def_map.find(object.get_identifier()); | ||
| if(def_it!=ssa_analysis[loc].def_map.end() && | ||
| def_it->second.def.kind==ssa_domaint::deft::ALLOCATION) | ||
| auto maybe_alloc_def=get_recent_object_alloc_def(loc, def_it); | ||
| if(maybe_alloc_def.has_value()) | ||
| { | ||
| locationt alloc_loc=def_it->second.def.loc; | ||
| return if_exprt( | ||
| read_rhs(def_it->second.def.guard, alloc_loc), | ||
| read_rhs(maybe_alloc_def->guard, maybe_alloc_def->loc), | ||
| read_rhs(object, loc), | ||
| read_rhs(object, alloc_loc)); | ||
| read_rhs(object, maybe_alloc_def->loc)); | ||
| } | ||
| else | ||
| return read_rhs(object, loc); | ||
|
|
@@ -904,6 +909,32 @@ exprt local_SSAt::read_rhs_rec(const exprt &expr, locationt loc) const | |
| } | ||
| } | ||
|
|
||
| /// Checks whether the last definition of the object is its allocation and | ||
| /// if so, return the allocation def. Otherwise returns nullopt. | ||
| optionalt<ssa_domaint::deft> local_SSAt::get_recent_object_alloc_def( | ||
| locationt loc, | ||
| const ssa_domaint::def_mapt::const_iterator &def) const | ||
| { | ||
| if(def==ssa_analysis[loc].def_map.end()) | ||
| return nullopt; | ||
|
|
||
| if(def->second.def.is_allocation()) | ||
| return def->second.def; | ||
|
|
||
| // Not a direct allocation, follow the split if it is a phi node and add | ||
| // guard if at least one of the branches is an allocation. | ||
| if(def->second.def.is_phi()) | ||
| { | ||
| const auto &phi_branches= | ||
| ssa_analysis[def->second.def.loc].phi_nodes.find(def->first); | ||
| if(phi_branches!=ssa_analysis[def->second.def.loc].phi_nodes.end()) | ||
| for(const auto &phi_branch : phi_branches->second) | ||
| if(phi_branch.second.is_allocation()) | ||
| return phi_branch.second; | ||
| } | ||
| return nullopt; | ||
| } | ||
|
|
||
| void local_SSAt::replace_side_effects_rec( | ||
| exprt &expr, locationt loc, unsigned &counter) const | ||
| { | ||
|
|
@@ -1110,40 +1141,8 @@ void local_SSAt::assign_rec( | |
| { | ||
| const if_exprt &if_expr=to_if_expr(lhs); | ||
|
|
||
| exprt::operandst other_cond_conj; | ||
| if(if_expr.true_case().get_bool("#heap_access") && | ||
| if_expr.cond().id()==ID_equal) | ||
| { | ||
| const exprt heap_object=if_expr.true_case(); | ||
| const ssa_objectt ptr_object(to_equal_expr(if_expr.cond()).lhs(), ns); | ||
| if(ptr_object) | ||
| { | ||
| const irep_idt ptr_id=ptr_object.get_identifier(); | ||
| const exprt cond=read_rhs(if_expr.cond(), loc); | ||
|
|
||
| for(const dyn_obj_assignt &do_assign : dyn_obj_assigns[heap_object]) | ||
| { | ||
| if(!alias_analysis[loc].aliases.same_set( | ||
| ptr_id, do_assign.pointer_id)) | ||
| { | ||
| other_cond_conj.push_back(do_assign.cond); | ||
| } | ||
| } | ||
|
|
||
| dyn_obj_assigns[heap_object].emplace_back(ptr_id, cond); | ||
| } | ||
| } | ||
|
|
||
| exprt cond=if_expr.cond(); | ||
| if(!other_cond_conj.empty()) | ||
| { | ||
| const exprt other_cond=or_exprt( | ||
| not_exprt(conjunction(other_cond_conj)), | ||
| name(guard_symbol(), OBJECT_SELECT, loc)); | ||
| cond=and_exprt(cond, other_cond); | ||
| } | ||
| exprt orig_rhs=fresh_rhs ? name(ssa_objectt(rhs, ns), OUT, loc) : rhs; | ||
| exprt new_rhs=if_exprt(cond, orig_rhs, if_expr.true_case()); | ||
| exprt new_rhs=if_exprt(if_expr.cond(), orig_rhs, if_expr.true_case()); | ||
| assign_rec( | ||
| if_expr.true_case(), | ||
| new_rhs, | ||
|
|
@@ -1545,10 +1544,10 @@ void local_SSAt::collect_allocation_guards( | |
|
|
||
| void local_SSAt::collect_record_frees(local_SSAt::locationt loc) | ||
| { | ||
| if(loc->is_decl()) | ||
| if(loc->is_assign()) | ||
| { | ||
| const code_declt &code_decl=code_declt{loc->decl_symbol()}; | ||
| const exprt &symbol=code_decl.symbol(); | ||
| const code_assignt &code_assign=to_code_assign(loc->get_code()); | ||
| const exprt &symbol=code_assign.lhs(); | ||
| if(symbol.id()!=ID_symbol) | ||
| return; | ||
|
|
||
|
|
@@ -1648,3 +1647,13 @@ bool local_SSAt::can_reuse_symderef( | |
|
|
||
| return true; | ||
| } | ||
|
|
||
| void local_SSAt::disable_unsupported_instructions(locationt loc) | ||
| { | ||
| if (loc->is_other()) | ||
| { | ||
| auto st = loc->get_code().get_statement(); | ||
| if(st=="array_copy" || st=="array_replace") | ||
| assert(false); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we could file an issue for support of memcpy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: #160.