Skip to content

Commit

Permalink
c++ compatibility:
Browse files Browse the repository at this point in the history
To generate C++ compatible code add --lang-cpp to cmith command line.
Previously you'd also need to add --no-consts --no-volatiles.
Consts and volatiles are supported now, with limitation:
"--match-exact-qualifiers --no-vol-struct-union-fields --no-const-struct-union-fields" are auto-added.

New switch:
--const-struct-union-fields|--no-const-struct-union-fields

Note:
Mixing signed and unsigned int pointers isn't supported anymore.
Explicit casts were emitted for these cases, but casts need to take CVqualifiers into account.
  • Loading branch information
natgla committed Mar 25, 2016
1 parent 075c863 commit 97df4f5
Show file tree
Hide file tree
Showing 8 changed files with 347 additions and 89 deletions.
11 changes: 11 additions & 0 deletions src/CGOptions.cpp
Expand Up @@ -191,6 +191,7 @@ DEFINE_GETTER_SETTER_BOOL(use_embedded_assigns);
DEFINE_GETTER_SETTER_BOOL(use_comma_exprs);
DEFINE_GETTER_SETTER_BOOL(take_union_field_addr);
DEFINE_GETTER_SETTER_BOOL(vol_struct_union_fields);
DEFINE_GETTER_SETTER_BOOL(const_struct_union_fields);
DEFINE_GETTER_SETTER_BOOL(lang_cpp);

void
Expand Down Expand Up @@ -299,12 +300,22 @@ CGOptions::set_default_settings(void)
use_comma_exprs(true);
take_union_field_addr(true);
vol_struct_union_fields(true);
const_struct_union_fields(true);
addr_taken_of_locals(true);
lang_cpp(false);

set_default_builtin_kinds();
}

// Add options necessary for cpp
void
CGOptions::fix_options_for_cpp(void)
{
match_exact_qualifiers(true);
vol_struct_union_fields(false); // makes implementation of volatile structs easier
const_struct_union_fields(false); // restriction of current implementation; TODO
}

/*
looking for the platform info file in the working directory
and load platform specific information. If not found, use
Expand Down
6 changes: 6 additions & 0 deletions src/CGOptions.h
Expand Up @@ -444,6 +444,9 @@ class CGOptions {
static bool vol_struct_union_fields(void);
static bool vol_struct_union_fields(bool p);

static bool const_struct_union_fields(void);
static bool const_struct_union_fields(bool p);

static int int_size(void);
static void int_size(int p) { int_size_ = p;}

Expand All @@ -459,6 +462,8 @@ class CGOptions {
static void disable_builtin_kinds(const string &kinds);
static bool enabled_builtin(const string &ks);

static void fix_options_for_cpp(void);

private:
static bool enabled_builtin_kind(const string &kind);

Expand Down Expand Up @@ -598,6 +603,7 @@ class CGOptions {
static int pointer_size_;
static bool take_union_field_addr_;
static bool vol_struct_union_fields_;
static bool const_struct_union_fields_;
static Reducer* reducer_;

// flag to indicate language
Expand Down
56 changes: 48 additions & 8 deletions src/CVQualifiers.cpp
Expand Up @@ -284,6 +284,26 @@ CVQualifiers::random_qualifiers(const Type* t, Effect::Access access,
return random_qualifiers(t, access, cg_context, no_volatile, RegularConstProb, RegularVolatileProb);
}

static bool is_volatile_ok_on_one_level(const Type* t)
{
if (!CGOptions::lang_cpp()) return true;
bool volatile_ok = (t->eType != eStruct && t->eType != eUnion) || (t->has_assign_ops());
// Union with a struct field: we can't make it volatile, or we won't be able to assign to/from that field
if (volatile_ok && (t->eType == eUnion)){
for (const auto& field : t->fields){
if (field->eType == eStruct){
volatile_ok = false;
break;
}
else if (field->eType == eUnion){
volatile_ok = is_volatile_ok_on_one_level(field);
if (!volatile_ok) break;
}
}
}
return volatile_ok;
}

CVQualifiers
CVQualifiers::random_qualifiers(const Type* t, Effect::Access access, const CGContext &cg_context, bool no_volatile,
unsigned int const_prob, unsigned int volatile_prob)
Expand All @@ -298,22 +318,42 @@ CVQualifiers::random_qualifiers(const Type* t, Effect::Access access, const CGCo
const Effect &effect_context = cg_context.get_effect_context();

// set random volatile/const properties for each level of indirection for pointers
// First set up the vectors with correct number of qualifiers:
unsigned level = 0;
const Type* tmp = t->ptr_type;
while (tmp) {
DEPTH_GUARD_BY_DEPTH_RETURN(2, ret_qfer);
isVolatile = rnd_flipcoin(volatile_prob);
ERROR_GUARD(ret_qfer);
++level;
is_consts.push_back(false);
is_volatiles.push_back(false);
tmp = tmp->ptr_type;
}
// Then make the random properties (properties need to be in reverse order):
tmp = t->ptr_type;
while (tmp) {
bool volatile_ok = is_volatile_ok_on_one_level(tmp);
if (volatile_ok){
DEPTH_GUARD_BY_DEPTH_RETURN(2, ret_qfer);
isVolatile = rnd_flipcoin(volatile_prob);
ERROR_GUARD(ret_qfer);
}
else{
DEPTH_GUARD_BY_DEPTH_RETURN(1, ret_qfer);
isVolatile = false;
}
isConst = rnd_flipcoin(const_prob);
ERROR_GUARD(ret_qfer);
if (isVolatile && isConst && !CGOptions::allow_const_volatile()) {
isConst = false;
}
is_consts.push_back(isConst);
is_volatiles.push_back(isVolatile);
assert(level > 0);
is_consts[level-1] = isConst;
is_volatiles[level-1] = isVolatile;
--level;
tmp = tmp->ptr_type;
}

// set random volatile/const properties for variable itself
bool volatile_ok = effect_context.is_side_effect_free();
bool volatile_ok = effect_context.is_side_effect_free() && is_volatile_ok_on_one_level(t);
bool const_ok = (access != Effect::WRITE);

isVolatile = false;
Expand Down Expand Up @@ -688,8 +728,8 @@ CVQualifiers::get_all_qualifiers(vector<CVQualifiers> &quals, unsigned int const
qual_enumerator.add_bool_elem("volatile_prob", volatile_prob);
Enumerator<string> *i;
for (i = qual_enumerator.begin(); i != qual_enumerator.end(); i = i->next()) {
bool isConst = i->get_elem("const_prob");
bool isVolatile = i->get_elem("volatile_prob");
bool isConst = i->get_elem("const_prob") != 0;
bool isVolatile = i->get_elem("volatile_prob") != 0;

vector<bool> consts;
vector<bool> volatiles;
Expand Down
8 changes: 5 additions & 3 deletions src/Constant.cpp
Expand Up @@ -527,18 +527,20 @@ Constant::get_type(void) const
void
Constant::Output(std::ostream &out) const
{
output_cast(out);
//enclose negative numbers in parenthesis to avoid syntax errors such as "--8"
if (!value.empty() && value[0] == '-') {
out << "(" << value << ")";
output_cast(out);
out << "(" << value << ")";
} else if (type->eType == ePointer && equals(0)){
// don't output cast for NULL:
if (CGOptions::lang_cpp()) {
out << "NULL";
} else {
out << "(void*)" << value;
}
} else {
out << value;
output_cast(out);
out << value;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Probabilities.cpp
Expand Up @@ -565,7 +565,7 @@ Probabilities::initialize_single_probs()
else
m[pFieldVolatileProb] = 0;

if (CGOptions::consts())
if (CGOptions::consts() && CGOptions::const_struct_union_fields())
m[pFieldConstProb] = 20;
else
m[pFieldConstProb] = 0;
Expand Down Expand Up @@ -873,7 +873,7 @@ Probabilities::check_extra_filter(ProbName pname, int v)
{
assert(v >= 0);
std::map<ProbName, Filter*>::iterator i = extra_filters_.find(pname);
if (i != extra_filters_.end())
if (i != extra_filters_.end() && ((*i).second != NULL))
return (*i).second->filter(v);
else
return false;
Expand Down
15 changes: 15 additions & 0 deletions src/RandomProgramGenerator.cpp
Expand Up @@ -260,6 +260,7 @@ static void print_advanced_help()
cout << " --arg-unions | --no-arg-unions: enable | disable unions being used as args (enabled by default)." << endl << endl;
cout << " --take-union-field-addr | --take-no-union-field-addr: allow | disallow addresses of union fields to be taken (allowed by default)." << endl << endl;
cout << " --vol-struct-union-fields | --no-vol-struct-union-fields: enable | disable volatile struct/union fields (enabled by default)" << endl << endl;
cout << " --const-struct-union-fields | --no-const-struct-union-fields: enable | disable const struct/union fields (enabled by default)" << endl << endl;

// delta related options
cout << " --delta-monitor [simple]: specify the type of delta monitor. Only [simple] type is supported now." << endl << endl;
Expand Down Expand Up @@ -1361,6 +1362,16 @@ main(int argc, char **argv)
continue;
}

if (strcmp(argv[i], "--const-struct-union-fields") == 0) {
CGOptions::const_struct_union_fields(true);
continue;
}

if (strcmp(argv[i], "--no-const-struct-union-fields") == 0) {
CGOptions::const_struct_union_fields(false);
continue;
}

if (strcmp (argv[i], "--no-hash-value-printf") == 0) {
CGOptions::hash_value_printf(false);
continue;
Expand Down Expand Up @@ -1415,6 +1426,10 @@ main(int argc, char **argv)
exit(-1);
}

if (CGOptions::lang_cpp()) {
CGOptions::fix_options_for_cpp();
}

if (CGOptions::has_conflict()) {
cout << "error: options conflict - " << CGOptions::conflict_msg() << std::endl;
exit(-1);
Expand Down

0 comments on commit 97df4f5

Please sign in to comment.