From 19e0cab011cba28d6b8cfb3f126fee8e5aa9aa2a Mon Sep 17 00:00:00 2001 From: Xuejun Yang Date: Fri, 19 Aug 2011 11:49:31 -0600 Subject: [PATCH] get rid of macro CSMITH_BITFIELD instead collect some platform specific information such as integer size before the random generation. Users can control these information through file "platform.info" in the working directory. --- src/Bookkeeper.cpp | 10 +++++ src/Bookkeeper.h | 3 ++ src/CGOptions.cpp | 73 ++++++++++++++++++++++++++++------ src/CGOptions.h | 20 +++++----- src/RandomProgramGenerator.cpp | 1 - src/Type.cpp | 10 ++--- 6 files changed, 87 insertions(+), 30 deletions(-) diff --git a/src/Bookkeeper.cpp b/src/Bookkeeper.cpp index f79722588..c0d367bc9 100644 --- a/src/Bookkeeper.cpp +++ b/src/Bookkeeper.cpp @@ -86,6 +86,8 @@ int Bookkeeper::forward_jump_cnt = 0; int Bookkeeper::backward_jump_cnt = 0; int Bookkeeper::use_new_var_cnt = 0; int Bookkeeper::use_old_var_cnt = 0; +bool Bookkeeper::rely_on_int_size = false; +bool Bookkeeper::rely_on_ptr_size = false; /* * @@ -190,6 +192,14 @@ Bookkeeper::output_statistics(std::ostream &out) output_stmts_statistics(out); out << endl; output_var_freshness(out); + if (rely_on_int_size) { + out << "FYI: the random generator makes assumptions about the integer size. See "; + out << PLATFORM_CONFIG_FILE << " for more details." << endl; + } + if (rely_on_ptr_size) { + out << "FYI: the random generator makes assumptions about the pointer size. See "; + out << PLATFORM_CONFIG_FILE << " for more details." << endl; + } } void diff --git a/src/Bookkeeper.h b/src/Bookkeeper.h index d116b6ef2..1d94ca623 100644 --- a/src/Bookkeeper.h +++ b/src/Bookkeeper.h @@ -140,6 +140,9 @@ class Bookkeeper static int use_new_var_cnt; static int use_old_var_cnt; + + static bool rely_on_int_size; + static bool rely_on_ptr_size; }; void incr_counter(std::vector& counters, int index); diff --git a/src/CGOptions.cpp b/src/CGOptions.cpp index b2f553ad0..56cd0aeae 100644 --- a/src/CGOptions.cpp +++ b/src/CGOptions.cpp @@ -34,6 +34,7 @@ #include #include "Fact.h" #include "DefaultOutputMgr.h" +#include "Bookkeeper.h" #include "CompatibleChecker.h" #include "PartialExpander.h" #include "DeltaMonitor.h" @@ -44,6 +45,8 @@ using namespace std; Reducer* CGOptions::reducer_ = NULL; vector CGOptions::safe_math_wrapper_ids_; +int CGOptions::int_size_ = 0; +int CGOptions::pointer_size_ = 0; /* * @@ -114,7 +117,6 @@ DEFINE_GETTER_SETTER_BOOL(coverage_test) DEFINE_GETTER_SETTER_INT(coverage_test_size) DEFINE_GETTER_SETTER_BOOL(packed_struct) DEFINE_GETTER_SETTER_BOOL(bitfields) -DEFINE_GETTER_SETTER_INT(bitfields_length) DEFINE_GETTER_SETTER_BOOL(prefix_name) DEFINE_GETTER_SETTER_BOOL(sequence_name_prefix) DEFINE_GETTER_SETTER_BOOL(compatible_check) @@ -167,12 +169,11 @@ DEFINE_GETTER_SETTER_BOOL(union_read_type_sensitive); DEFINE_GETTER_SETTER_BOOL(use_incr_decr_opers); DEFINE_GETTER_SETTER_BOOL(use_embedded_assigns); DEFINE_GETTER_SETTER_BOOL(use_comma_exprs); -DEFINE_GETTER_SETTER_INT(int_bytes); -DEFINE_GETTER_SETTER_INT(pointer_bytes); void CGOptions::set_default_settings(void) { + set_platform_specific_options(); compute_hash(true); max_funcs(CGOPTIONS_DEFAULT_MAX_SPLIT_FILES); max_funcs(CGOPTIONS_DEFAULT_MAX_FUNCS); @@ -211,7 +212,6 @@ CGOptions::set_default_settings(void) coverage_test(false); coverage_test_size(CGOPTIONS_DEFAULT_COVERAGE_TEST_SIZE); packed_struct(true); - resolve_bitfields_length(); bitfields(true); prefix_name(false); sequence_name_prefix(false); @@ -254,19 +254,66 @@ CGOptions::set_default_settings(void) use_incr_decr_opers(true); use_embedded_assigns(true); use_comma_exprs(true); - // these are defaults for x86-64 machine, our most used platform. - // configure them to generate *correct* random programs for other platforms. - int_bytes(4); - pointer_bytes(8); +} + +/* + looking for the platform info file in the working directory + and load platform specific information. If not found, use + info from the platform that Csmith is running, and output them + to the file +*/ +void +CGOptions::set_platform_specific_options(void) +{ + const char* int_str = "integer size = "; + const char* ptr_str = "pointer size = "; + ifstream conf(PLATFORM_CONFIG_FILE); + if (conf.fail()) { + ofstream conf(PLATFORM_CONFIG_FILE); + conf << int_str << sizeof(int) << endl; + conf << ptr_str << sizeof(int*) << endl; + int_size(sizeof(int)); + pointer_size(sizeof(int*)); + conf.close(); + } + else { + string line; + while(!conf.eof()) { + getline(conf, line); + if (line.substr(0, strlen(int_str)) == int_str) { + string s = line.substr(strlen(int_str)); + StringUtils::chop(s); + int_size(StringUtils::str2int(s)); + } + if (line.substr(0, strlen(ptr_str)) == ptr_str) { + string s = line.substr(strlen(ptr_str)); + StringUtils::chop(s); + pointer_size(StringUtils::str2int(s)); + } + } + if (!int_size_) { + cout << "please specify integer size in " << PLATFORM_CONFIG_FILE << endl; + exit(-1); + } + if (!pointer_size_) { + cout << "please specify pointer size in " << PLATFORM_CONFIG_FILE << endl; + exit(-1); + } + conf.close(); + } } -#define MAX_INTEGER_LENGTH 64 +int +CGOptions::int_size(void) +{ + Bookkeeper::rely_on_int_size = true; + return int_size_; +} -bool -CGOptions::resolve_bitfields_length(void) +int +CGOptions::pointer_size(void) { - CGOptions::bitfields_length(MAX_INTEGER_LENGTH - 1); - return true; + return pointer_size_; } bool diff --git a/src/CGOptions.h b/src/CGOptions.h index 6cb74c1ff..1f947d32b 100644 --- a/src/CGOptions.h +++ b/src/CGOptions.h @@ -63,6 +63,7 @@ using namespace std; #define CGOPTIONS_DEFAULT_SPLIT_FILES_DIR ("./output") #define CGOPTIONS_DEFAULT_OUTPUT_FILE ("") #define CGOPTIONS_DEFAULT_VOL_ADDR_FILE ("vol_addr.txt") +#define PLATFORM_CONFIG_FILE ("platform.info") /* * @@ -216,9 +217,6 @@ class CGOptions { static bool bitfields(void); static bool bitfields(bool p); - static int bitfields_length(void); - static int bitfields_length(int p); - static std::string partial_expand(void); static std::string partial_expand(std::string p); @@ -340,7 +338,6 @@ class CGOptions { static const std::string& conflict_msg(void); static bool is_random(void); - static bool resolve_bitfields_length(); static bool has_extension_support(); @@ -390,11 +387,13 @@ class CGOptions { static bool use_comma_exprs(void); static bool use_comma_exprs(bool p); - static int int_bytes(void); - static int int_bytes(int p); + static int int_size(void); + static void int_size(int p) { int_size_ = p;} + + static int pointer_size(void); + static void pointer_size(int p) { pointer_size_ = p;} - static int pointer_bytes(void); - static int pointer_bytes(int p); + static void set_platform_specific_options(void); private: static bool resolve_exhaustive_options(); @@ -456,7 +455,6 @@ class CGOptions { static int coverage_test_size_; static bool packed_struct_; static bool bitfields_; - static int bitfields_length_; static bool prefix_name_; static bool sequence_name_prefix_; static bool compatible_check_; @@ -510,8 +508,8 @@ class CGOptions { static bool use_incr_decr_opers_; static bool use_embedded_assigns_; static bool use_comma_exprs_; - static int int_bytes_; - static int pointer_bytes_; + static int int_size_; + static int pointer_size_; static Reducer* reducer_; private: diff --git a/src/RandomProgramGenerator.cpp b/src/RandomProgramGenerator.cpp index b01a82510..f24f06908 100644 --- a/src/RandomProgramGenerator.cpp +++ b/src/RandomProgramGenerator.cpp @@ -461,7 +461,6 @@ main(int argc, char **argv) } if (strcmp (argv[i], "--bitfields") == 0) { - CGOptions::resolve_bitfields_length(); CGOptions::bitfields(true); continue; } diff --git a/src/Type.cpp b/src/Type.cpp index d360d6e5e..9fc0c5b26 100644 --- a/src/Type.cpp +++ b/src/Type.cpp @@ -454,7 +454,7 @@ Type::has_int_field() const bool Type::signed_overflow_possible() const { - return eType == eSimple && is_signed() && ((int)SizeInBytes()) >= CGOptions::int_bytes(); + return eType == eSimple && is_signed() && ((int)SizeInBytes()) >= CGOptions::int_size(); } void @@ -580,7 +580,7 @@ Type::choose_random_nonvoid_simple(void) void Type::make_one_bitfield(vector &random_fields, vector &qualifiers, vector &fields_length) { - int max_length = CGOptions::bitfields_length(); + int max_length = CGOptions::int_size() * 8; bool sign = rnd_flipcoin(BitFieldsSignedProb); ERROR_RETURN(); @@ -757,7 +757,7 @@ Type::init_fields_enumerator(Enumerator &enumerator, int Type::get_bitfield_length(int length_flag) { - int max_length = CGOptions::bitfields_length(); + int max_length = CGOptions::int_size() * 8; assert(max_length > 0); int length; switch (length_flag) { @@ -1451,7 +1451,7 @@ Type::SizeInBytes(void) const return total_size; } case ePointer: - CGOptions::pointer_bytes(); + CGOptions::pointer_size(); break; } return 0; @@ -1606,7 +1606,7 @@ void OutputStructUnion(Type* type, std::ostream &out) out << " : "; else out << " f" << j++ << " : "; - out << "_CSMITH_BITFIELD(" << length << ");"; + out << length << ";"; } else { type->qfers_[i].output_qualified_type(field, out);