-
Notifications
You must be signed in to change notification settings - Fork 273
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3767 from chrisr-diffblue/validate_goto_programs_…
…symbol_check_fixup Fix up symbol naming checks so --validate-goto-model can be enabled in regression testing.
- Loading branch information
Showing
15 changed files
with
170 additions
and
39 deletions.
There are no files selected for viewing
This file contains 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,3 +1,3 @@ | ||
add_test_pl_tests( | ||
"$<TARGET_FILE:cbmc>" -X smt-backend | ||
"$<TARGET_FILE:cbmc> --validate-goto-model" -X smt-backend | ||
) |
This file contains 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 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,3 +1,5 @@ | ||
#include <stdlib.h> | ||
|
||
int global_var; | ||
|
||
struct S | ||
|
This file contains 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 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 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 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 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 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 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 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 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 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 |
---|---|---|
|
@@ -22,6 +22,8 @@ Author: Daniel Kroening, [email protected] | |
|
||
#include <langapi/language_util.h> | ||
|
||
#include "remove_returns.h" | ||
|
||
/// Writes to \p out a two/three line string representation of a given | ||
/// \p instruction. The output is of the format: | ||
/// ``` | ||
|
@@ -709,13 +711,75 @@ void goto_programt::instructiont::validate( | |
const auto &goto_id = goto_symbol_expr.get_identifier(); | ||
|
||
if(!ns.lookup(goto_id, table_symbol)) | ||
{ | ||
bool symbol_expr_type_matches_symbol_table = | ||
base_type_eq(goto_symbol_expr.type(), table_symbol->type, ns); | ||
|
||
if( | ||
!symbol_expr_type_matches_symbol_table && | ||
table_symbol->type.id() == ID_code) | ||
{ | ||
// Return removal sets the return type of a function symbol table | ||
// entry to 'void', but some callsites still expect the original | ||
// type (e.g. if a function is passed as a parameter) | ||
symbol_expr_type_matches_symbol_table = base_type_eq( | ||
goto_symbol_expr.type(), | ||
original_return_type(ns.get_symbol_table(), goto_id), | ||
ns); | ||
|
||
if( | ||
!symbol_expr_type_matches_symbol_table && | ||
goto_symbol_expr.type().id() == ID_code) | ||
{ | ||
// If a function declaration and its definition are in different | ||
// translation units they may have different return types, | ||
// which remove_returns patches up with a typecast. If thats | ||
// the case, then the return type in the symbol table may differ | ||
// from the return type in the symbol expr | ||
if( | ||
goto_symbol_expr.type().source_location().get_file() != | ||
table_symbol->type.source_location().get_file()) | ||
{ | ||
// temporarily fixup the return types | ||
auto goto_symbol_expr_type = | ||
to_code_type(goto_symbol_expr.type()); | ||
auto table_symbol_type = to_code_type(table_symbol->type); | ||
|
||
goto_symbol_expr_type.return_type() = | ||
table_symbol_type.return_type(); | ||
|
||
symbol_expr_type_matches_symbol_table = | ||
base_type_eq(goto_symbol_expr_type, table_symbol_type, ns); | ||
} | ||
} | ||
} | ||
|
||
if( | ||
!symbol_expr_type_matches_symbol_table && | ||
goto_symbol_expr.type().id() == ID_array && | ||
to_array_type(goto_symbol_expr.type()).is_incomplete()) | ||
{ | ||
// If the symbol expr has an incomplete array type, it may not have | ||
// a constant size value, whereas the symbol table entry may have | ||
// an (assumed) constant size of 1 (which mimics gcc behaviour) | ||
if(table_symbol->type.id() == ID_array) | ||
{ | ||
auto symbol_table_array_type = to_array_type(table_symbol->type); | ||
symbol_table_array_type.size() = nil_exprt(); | ||
|
||
symbol_expr_type_matches_symbol_table = base_type_eq( | ||
goto_symbol_expr.type(), symbol_table_array_type, ns); | ||
} | ||
} | ||
|
||
DATA_CHECK_WITH_DIAGNOSTICS( | ||
vm, | ||
base_type_eq(goto_symbol_expr.type(), table_symbol->type, ns), | ||
symbol_expr_type_matches_symbol_table, | ||
id2string(goto_id) + " type inconsistency\n" + | ||
"goto program type: " + goto_symbol_expr.type().id_string() + | ||
"\n" + "symbol table type: " + table_symbol->type.id_string(), | ||
current_source_location); | ||
} | ||
} | ||
}; | ||
|
||
|
This file contains 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 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 |
---|---|---|
|
@@ -12,6 +12,7 @@ Author: Daniel Kroening, [email protected] | |
|
||
#include "source_location.h" | ||
#include "std_expr.h" | ||
#include "string_utils.h" | ||
#include "suffix.h" | ||
|
||
/// Dump the state of a symbol object to a given output stream. | ||
|
@@ -137,11 +138,62 @@ bool symbolt::is_well_formed() const | |
// Well-formedness criterion number 2 is for a symbol | ||
// to have it's base name as a suffix to it's more | ||
// general name. | ||
|
||
// Exception: Java symbols' base names do not have type signatures | ||
// (for example, they can have name "someclass.method:(II)V" and base name | ||
// "method") | ||
if(!has_suffix(id2string(name), id2string(base_name)) && mode != ID_java) | ||
return false; | ||
{ | ||
bool criterion_must_hold = true; | ||
|
||
// There are some special cases where this criterion doesn't hold, check | ||
// to see if we have one of those cases | ||
|
||
if(is_type) | ||
{ | ||
// Typedefs | ||
if( | ||
type.find(ID_C_typedef).is_not_nil() && | ||
type.find(ID_C_typedef).id() == base_name) | ||
{ | ||
criterion_must_hold = false; | ||
} | ||
|
||
// Tag types | ||
if(type.find(ID_tag).is_not_nil() && type.find(ID_tag).id() == base_name) | ||
{ | ||
criterion_must_hold = false; | ||
} | ||
} | ||
|
||
// Linker renaming may have added $linkN suffixes to the name, and other | ||
// suffixes such as #return_value may have then be subsequently added. | ||
// Strip out the first $linkN substring and then see if the criterion holds | ||
const auto &unstripped_name = id2string(name); | ||
const size_t dollar_link_start_pos = unstripped_name.find("$link"); | ||
|
||
if(dollar_link_start_pos != std::string::npos) | ||
{ | ||
size_t dollar_link_end_pos = dollar_link_start_pos + 5; | ||
while(isdigit(unstripped_name[dollar_link_end_pos])) | ||
{ | ||
++dollar_link_end_pos; | ||
} | ||
|
||
const auto stripped_name = | ||
unstripped_name.substr(0, dollar_link_start_pos) + | ||
unstripped_name.substr(dollar_link_end_pos, std::string::npos); | ||
|
||
if(has_suffix(stripped_name, id2string(base_name))) | ||
criterion_must_hold = false; | ||
} | ||
|
||
if(criterion_must_hold) | ||
{ | ||
// For all other cases this criterion should hold | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|