diff --git a/src/libdredd/src/mutation_replace_expr.cc b/src/libdredd/src/mutation_replace_expr.cc index 79f358e2..32d18c42 100644 --- a/src/libdredd/src/mutation_replace_expr.cc +++ b/src/libdredd/src/mutation_replace_expr.cc @@ -538,18 +538,18 @@ void MutationReplaceExpr::ReplaceExprWithFunctionCall( suffix.append("; }"); } - if (!ast_context.getLangOpts().CPlusPlus) { - if (expr_->isLValue() && input_type.ends_with('*')) { - prefix.append("&("); - suffix.append(")"); - } else if (const auto* binary_expr = - llvm::dyn_cast(expr_)) { - // The comma operator requires special care in C, to avoid it appearing to - // provide multiple parameters for an enclosing function call. - if (binary_expr->isCommaOp()) { - prefix.append("("); - suffix.append(")"); - } + if (!ast_context.getLangOpts().CPlusPlus && expr_->isLValue() && + input_type.ends_with('*')) { + prefix.append("&("); + suffix = ")" + suffix; + } + + if (const auto* binary_expr = llvm::dyn_cast(expr_)) { + // The comma operator requires special care to avoid it appearing to + // provide multiple parameters for an enclosing function call. + if (binary_expr->isCommaOp()) { + prefix.append("("); + suffix = ")" + suffix; } } diff --git a/test/single_file/comma_initialization.c b/test/single_file/comma_initialization.c new file mode 100644 index 00000000..9843f02a --- /dev/null +++ b/test/single_file/comma_initialization.c @@ -0,0 +1,3 @@ +int main() { + int x = (1,0); +} diff --git a/test/single_file/comma_initialization.c.expected b/test/single_file/comma_initialization.c.expected new file mode 100644 index 00000000..4ebe758b --- /dev/null +++ b/test/single_file/comma_initialization.c.expected @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#ifdef _MSC_VER +#define thread_local __declspec(thread) +#elif __APPLE__ +#define thread_local __thread +#else +#include +#endif + +static thread_local int __dredd_some_mutation_enabled = 1; +static int __dredd_enabled_mutation(int local_mutation_id) { + static thread_local int initialized = 0; + static thread_local uint64_t enabled_bitset[1]; + if (!initialized) { + int some_mutation_enabled = 0; + const char* dredd_environment_variable = getenv("DREDD_ENABLED_MUTATION"); + if (dredd_environment_variable) { + char* temp = malloc(strlen(dredd_environment_variable) + 1); + strcpy(temp, dredd_environment_variable); + char* token; + token = strtok(temp, ","); + while(token) { + int value = atoi(token); + int local_value = value - 0; + if (local_value >= 0 && local_value < 7) { + enabled_bitset[local_value / 64] |= (1 << (local_value % 64)); + some_mutation_enabled = 1; + } + token = strtok(NULL, ","); + } + free(temp); + } + initialized = 1; + __dredd_some_mutation_enabled = some_mutation_enabled; + } + return enabled_bitset[local_mutation_id / 64] & (1 << (local_mutation_id % 64)); +} + +static int __dredd_replace_expr_int_zero(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return -1; + return arg; +} + +static int __dredd_replace_expr_int_one(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return ~(arg); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return 0; + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -1; + return arg; +} + +int main() { + int x = (__dredd_replace_expr_int_zero((__dredd_replace_expr_int_one(1, 0),__dredd_replace_expr_int_zero(0, 3)), 5)); +} diff --git a/test/single_file/comma_initialization.c.noopt.expected b/test/single_file/comma_initialization.c.noopt.expected new file mode 100644 index 00000000..e16fe37e --- /dev/null +++ b/test/single_file/comma_initialization.c.noopt.expected @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +#ifdef _MSC_VER +#define thread_local __declspec(thread) +#elif __APPLE__ +#define thread_local __thread +#else +#include +#endif + +static thread_local int __dredd_some_mutation_enabled = 1; +static int __dredd_enabled_mutation(int local_mutation_id) { + static thread_local int initialized = 0; + static thread_local uint64_t enabled_bitset[1]; + if (!initialized) { + int some_mutation_enabled = 0; + const char* dredd_environment_variable = getenv("DREDD_ENABLED_MUTATION"); + if (dredd_environment_variable) { + char* temp = malloc(strlen(dredd_environment_variable) + 1); + strcpy(temp, dredd_environment_variable); + char* token; + token = strtok(temp, ","); + while(token) { + int value = atoi(token); + int local_value = value - 0; + if (local_value >= 0 && local_value < 24) { + enabled_bitset[local_value / 64] |= (1 << (local_value % 64)); + some_mutation_enabled = 1; + } + token = strtok(NULL, ","); + } + free(temp); + } + initialized = 1; + __dredd_some_mutation_enabled = some_mutation_enabled; + } + return enabled_bitset[local_mutation_id / 64] & (1 << (local_mutation_id % 64)); +} + +static int __dredd_replace_expr_int(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return !(arg); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~(arg); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -(arg); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return 0; + if (__dredd_enabled_mutation(local_mutation_id + 4)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 5)) return -1; + return arg; +} + +int main() { + int x = __dredd_replace_expr_int((__dredd_replace_expr_int((__dredd_replace_expr_int(1, 0),__dredd_replace_expr_int(0, 6)), 12)), 18); +} diff --git a/test/single_file/comma_initialization.cc b/test/single_file/comma_initialization.cc new file mode 100644 index 00000000..37226a11 --- /dev/null +++ b/test/single_file/comma_initialization.cc @@ -0,0 +1,3 @@ +int main() { + int b((1,0)); +} diff --git a/test/single_file/comma_initialization.cc.expected b/test/single_file/comma_initialization.cc.expected new file mode 100644 index 00000000..56c094e8 --- /dev/null +++ b/test/single_file/comma_initialization.cc.expected @@ -0,0 +1,62 @@ +#include +#include +#include +#include + + +#ifdef _MSC_VER +#define thread_local __declspec(thread) +#elif __APPLE__ +#define thread_local __thread +#endif + +static thread_local bool __dredd_some_mutation_enabled = true; +static bool __dredd_enabled_mutation(int local_mutation_id) { + static thread_local bool initialized = false; + static thread_local uint64_t enabled_bitset[1]; + if (!initialized) { + bool some_mutation_enabled = false; + const char* dredd_environment_variable = std::getenv("DREDD_ENABLED_MUTATION"); + if (dredd_environment_variable != nullptr) { + std::string contents(dredd_environment_variable); + while (true) { + size_t pos = contents.find(","); + std::string token = (pos == std::string::npos ? contents : contents.substr(0, pos)); + if (!token.empty()) { + int value = std::stoi(token); + int local_value = value - 0; + if (local_value >= 0 && local_value < 7) { + enabled_bitset[local_value / 64] |= (1 << (local_value % 64)); + some_mutation_enabled = true; + } + } + if (pos == std::string::npos) { + break; + } + contents.erase(0, pos + 1); + } + } + initialized = true; + __dredd_some_mutation_enabled = some_mutation_enabled; + } + return (enabled_bitset[local_mutation_id / 64] & (1 << (local_mutation_id % 64))) != 0; +} + +static int __dredd_replace_expr_int_zero(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return -1; + return arg; +} + +static int __dredd_replace_expr_int_one(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return ~(arg); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return 0; + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -1; + return arg; +} + +int main() { + int b((__dredd_replace_expr_int_zero((__dredd_replace_expr_int_one(1, 0),__dredd_replace_expr_int_zero(0, 3)), 5))); +} diff --git a/test/single_file/comma_initialization.cc.noopt.expected b/test/single_file/comma_initialization.cc.noopt.expected new file mode 100644 index 00000000..350d23cb --- /dev/null +++ b/test/single_file/comma_initialization.cc.noopt.expected @@ -0,0 +1,58 @@ +#include +#include +#include +#include + + +#ifdef _MSC_VER +#define thread_local __declspec(thread) +#elif __APPLE__ +#define thread_local __thread +#endif + +static thread_local bool __dredd_some_mutation_enabled = true; +static bool __dredd_enabled_mutation(int local_mutation_id) { + static thread_local bool initialized = false; + static thread_local uint64_t enabled_bitset[1]; + if (!initialized) { + bool some_mutation_enabled = false; + const char* dredd_environment_variable = std::getenv("DREDD_ENABLED_MUTATION"); + if (dredd_environment_variable != nullptr) { + std::string contents(dredd_environment_variable); + while (true) { + size_t pos = contents.find(","); + std::string token = (pos == std::string::npos ? contents : contents.substr(0, pos)); + if (!token.empty()) { + int value = std::stoi(token); + int local_value = value - 0; + if (local_value >= 0 && local_value < 24) { + enabled_bitset[local_value / 64] |= (1 << (local_value % 64)); + some_mutation_enabled = true; + } + } + if (pos == std::string::npos) { + break; + } + contents.erase(0, pos + 1); + } + } + initialized = true; + __dredd_some_mutation_enabled = some_mutation_enabled; + } + return (enabled_bitset[local_mutation_id / 64] & (1 << (local_mutation_id % 64))) != 0; +} + +static int __dredd_replace_expr_int(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return !(arg); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~(arg); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -(arg); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return 0; + if (__dredd_enabled_mutation(local_mutation_id + 4)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 5)) return -1; + return arg; +} + +int main() { + int b(__dredd_replace_expr_int((__dredd_replace_expr_int((__dredd_replace_expr_int(1, 0),__dredd_replace_expr_int(0, 6)), 12)), 18)); +} diff --git a/test/single_file/comma_side_effects.c b/test/single_file/comma_side_effects.c new file mode 100644 index 00000000..56cbc44c --- /dev/null +++ b/test/single_file/comma_side_effects.c @@ -0,0 +1,4 @@ +int main() { + int x = 0; + x = (0, x++); +} diff --git a/test/single_file/comma_side_effects.c.expected b/test/single_file/comma_side_effects.c.expected new file mode 100644 index 00000000..62b43b77 --- /dev/null +++ b/test/single_file/comma_side_effects.c.expected @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +#ifdef _MSC_VER +#define thread_local __declspec(thread) +#elif __APPLE__ +#define thread_local __thread +#else +#include +#endif + +static thread_local int __dredd_some_mutation_enabled = 1; +static int __dredd_enabled_mutation(int local_mutation_id) { + static thread_local int initialized = 0; + static thread_local uint64_t enabled_bitset[1]; + if (!initialized) { + int some_mutation_enabled = 0; + const char* dredd_environment_variable = getenv("DREDD_ENABLED_MUTATION"); + if (dredd_environment_variable) { + char* temp = malloc(strlen(dredd_environment_variable) + 1); + strcpy(temp, dredd_environment_variable); + char* token; + token = strtok(temp, ","); + while(token) { + int value = atoi(token); + int local_value = value - 0; + if (local_value >= 0 && local_value < 32) { + enabled_bitset[local_value / 64] |= (1 << (local_value % 64)); + some_mutation_enabled = 1; + } + token = strtok(NULL, ","); + } + free(temp); + } + initialized = 1; + __dredd_some_mutation_enabled = some_mutation_enabled; + } + return enabled_bitset[local_mutation_id / 64] & (1 << (local_mutation_id % 64)); +} + +static int __dredd_replace_unary_operator_PostInc_int(int* arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return (*arg)++; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return (*arg)--; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~(*arg); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -(*arg); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return !(*arg); + if (__dredd_enabled_mutation(local_mutation_id + 4)) return (*arg); + return (*arg)++; +} + +static int __dredd_replace_expr_int_zero(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return -1; + return arg; +} + +static int __dredd_replace_expr_int(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return !(arg); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~(arg); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -(arg); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return 0; + if (__dredd_enabled_mutation(local_mutation_id + 4)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 5)) return -1; + return arg; +} + +static int __dredd_replace_binary_operator_Assign_arg1_int_arg2_int(int* arg1, int arg2, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return (*arg1) = arg2; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return (*arg1) += arg2; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return (*arg1) &= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 2)) return (*arg1) /= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 3)) return (*arg1) *= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 4)) return (*arg1) |= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 5)) return (*arg1) %= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 6)) return (*arg1) <<= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 7)) return (*arg1) >>= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 8)) return (*arg1) -= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 9)) return (*arg1) ^= arg2; + return (*arg1) = arg2; +} + +int main() { + int x = __dredd_replace_expr_int_zero(0, 0); + if (!__dredd_enabled_mutation(31)) { __dredd_replace_binary_operator_Assign_arg1_int_arg2_int(&(x) , (__dredd_replace_expr_int((__dredd_replace_expr_int_zero(0, 2), __dredd_replace_expr_int(__dredd_replace_unary_operator_PostInc_int(&(x), 4), 9)), 15)), 21); } +} diff --git a/test/single_file/comma_side_effects.c.noopt.expected b/test/single_file/comma_side_effects.c.noopt.expected new file mode 100644 index 00000000..ec6b399f --- /dev/null +++ b/test/single_file/comma_side_effects.c.noopt.expected @@ -0,0 +1,82 @@ +#include +#include +#include +#include + +#ifdef _MSC_VER +#define thread_local __declspec(thread) +#elif __APPLE__ +#define thread_local __thread +#else +#include +#endif + +static thread_local int __dredd_some_mutation_enabled = 1; +static int __dredd_enabled_mutation(int local_mutation_id) { + static thread_local int initialized = 0; + static thread_local uint64_t enabled_bitset[1]; + if (!initialized) { + int some_mutation_enabled = 0; + const char* dredd_environment_variable = getenv("DREDD_ENABLED_MUTATION"); + if (dredd_environment_variable) { + char* temp = malloc(strlen(dredd_environment_variable) + 1); + strcpy(temp, dredd_environment_variable); + char* token; + token = strtok(temp, ","); + while(token) { + int value = atoi(token); + int local_value = value - 0; + if (local_value >= 0 && local_value < 52) { + enabled_bitset[local_value / 64] |= (1 << (local_value % 64)); + some_mutation_enabled = 1; + } + token = strtok(NULL, ","); + } + free(temp); + } + initialized = 1; + __dredd_some_mutation_enabled = some_mutation_enabled; + } + return enabled_bitset[local_mutation_id / 64] & (1 << (local_mutation_id % 64)); +} + +static int __dredd_replace_unary_operator_PostInc_int(int* arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return (*arg)++; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return (*arg)--; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~(*arg); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -(*arg); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return !(*arg); + if (__dredd_enabled_mutation(local_mutation_id + 4)) return (*arg); + return (*arg)++; +} + +static int __dredd_replace_expr_int(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return !(arg); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~(arg); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -(arg); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return 0; + if (__dredd_enabled_mutation(local_mutation_id + 4)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 5)) return -1; + return arg; +} + +static int __dredd_replace_binary_operator_Assign_arg1_int_arg2_int(int* arg1, int arg2, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return (*arg1) = arg2; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return (*arg1) += arg2; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return (*arg1) &= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 2)) return (*arg1) /= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 3)) return (*arg1) *= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 4)) return (*arg1) |= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 5)) return (*arg1) %= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 6)) return (*arg1) <<= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 7)) return (*arg1) >>= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 8)) return (*arg1) -= arg2; + if (__dredd_enabled_mutation(local_mutation_id + 9)) return (*arg1) ^= arg2; + return (*arg1) = arg2; +} + +int main() { + int x = __dredd_replace_expr_int(0, 0); + if (!__dredd_enabled_mutation(51)) { __dredd_replace_expr_int(__dredd_replace_binary_operator_Assign_arg1_int_arg2_int(&(x) , __dredd_replace_expr_int((__dredd_replace_expr_int((__dredd_replace_expr_int(0, 6), __dredd_replace_expr_int(__dredd_replace_unary_operator_PostInc_int(&(x), 12), 17)), 23)), 29), 35), 45); } +} diff --git a/test/single_file/comma_side_effects.cc b/test/single_file/comma_side_effects.cc new file mode 100644 index 00000000..56cbc44c --- /dev/null +++ b/test/single_file/comma_side_effects.cc @@ -0,0 +1,4 @@ +int main() { + int x = 0; + x = (0, x++); +} diff --git a/test/single_file/comma_side_effects.cc.expected b/test/single_file/comma_side_effects.cc.expected new file mode 100644 index 00000000..cbd5db97 --- /dev/null +++ b/test/single_file/comma_side_effects.cc.expected @@ -0,0 +1,91 @@ +#include +#include +#include +#include + + +#ifdef _MSC_VER +#define thread_local __declspec(thread) +#elif __APPLE__ +#define thread_local __thread +#endif + +static thread_local bool __dredd_some_mutation_enabled = true; +static bool __dredd_enabled_mutation(int local_mutation_id) { + static thread_local bool initialized = false; + static thread_local uint64_t enabled_bitset[1]; + if (!initialized) { + bool some_mutation_enabled = false; + const char* dredd_environment_variable = std::getenv("DREDD_ENABLED_MUTATION"); + if (dredd_environment_variable != nullptr) { + std::string contents(dredd_environment_variable); + while (true) { + size_t pos = contents.find(","); + std::string token = (pos == std::string::npos ? contents : contents.substr(0, pos)); + if (!token.empty()) { + int value = std::stoi(token); + int local_value = value - 0; + if (local_value >= 0 && local_value < 32) { + enabled_bitset[local_value / 64] |= (1 << (local_value % 64)); + some_mutation_enabled = true; + } + } + if (pos == std::string::npos) { + break; + } + contents.erase(0, pos + 1); + } + } + initialized = true; + __dredd_some_mutation_enabled = some_mutation_enabled; + } + return (enabled_bitset[local_mutation_id / 64] & (1 << (local_mutation_id % 64))) != 0; +} + +static int& __dredd_replace_binary_operator_Assign_arg1_int_arg2_int(int& arg1, std::function arg2, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg1 = arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 0)) return arg1 += arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return arg1 &= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return arg1 /= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return arg1 *= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 4)) return arg1 |= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 5)) return arg1 %= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 6)) return arg1 <<= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 7)) return arg1 >>= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 8)) return arg1 -= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 9)) return arg1 ^= arg2(); + return arg1 = arg2(); +} + +static int __dredd_replace_unary_operator_PostInc_int(std::function arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg()++; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return arg()--; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~arg(); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -arg(); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return !arg(); + if (__dredd_enabled_mutation(local_mutation_id + 4)) return arg(); + return arg()++; +} + +static int __dredd_replace_expr_int_zero(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return -1; + return arg; +} + +static int __dredd_replace_expr_int(std::function arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg(); + if (__dredd_enabled_mutation(local_mutation_id + 0)) return !(arg()); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~(arg()); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -(arg()); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return 0; + if (__dredd_enabled_mutation(local_mutation_id + 4)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 5)) return -1; + return arg(); +} + +int main() { + int x = __dredd_replace_expr_int_zero(0, 0); + if (!__dredd_enabled_mutation(31)) { __dredd_replace_binary_operator_Assign_arg1_int_arg2_int(x , [&]() -> int { return static_cast((__dredd_replace_expr_int([&]() -> int { return static_cast((__dredd_replace_expr_int_zero(0, 2), __dredd_replace_expr_int([&]() -> int { return static_cast(__dredd_replace_unary_operator_PostInc_int([&]() -> int& { return static_cast(x); }, 4)); }, 9))); }, 15))); }, 21); } +} diff --git a/test/single_file/comma_side_effects.cc.noopt.expected b/test/single_file/comma_side_effects.cc.noopt.expected new file mode 100644 index 00000000..4fe5c605 --- /dev/null +++ b/test/single_file/comma_side_effects.cc.noopt.expected @@ -0,0 +1,95 @@ +#include +#include +#include +#include + + +#ifdef _MSC_VER +#define thread_local __declspec(thread) +#elif __APPLE__ +#define thread_local __thread +#endif + +static thread_local bool __dredd_some_mutation_enabled = true; +static bool __dredd_enabled_mutation(int local_mutation_id) { + static thread_local bool initialized = false; + static thread_local uint64_t enabled_bitset[1]; + if (!initialized) { + bool some_mutation_enabled = false; + const char* dredd_environment_variable = std::getenv("DREDD_ENABLED_MUTATION"); + if (dredd_environment_variable != nullptr) { + std::string contents(dredd_environment_variable); + while (true) { + size_t pos = contents.find(","); + std::string token = (pos == std::string::npos ? contents : contents.substr(0, pos)); + if (!token.empty()) { + int value = std::stoi(token); + int local_value = value - 0; + if (local_value >= 0 && local_value < 46) { + enabled_bitset[local_value / 64] |= (1 << (local_value % 64)); + some_mutation_enabled = true; + } + } + if (pos == std::string::npos) { + break; + } + contents.erase(0, pos + 1); + } + } + initialized = true; + __dredd_some_mutation_enabled = some_mutation_enabled; + } + return (enabled_bitset[local_mutation_id / 64] & (1 << (local_mutation_id % 64))) != 0; +} + +static int& __dredd_replace_binary_operator_Assign_arg1_int_arg2_int(int& arg1, std::function arg2, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg1 = arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 0)) return arg1 += arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return arg1 &= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return arg1 /= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return arg1 *= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 4)) return arg1 |= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 5)) return arg1 %= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 6)) return arg1 <<= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 7)) return arg1 >>= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 8)) return arg1 -= arg2(); + if (__dredd_enabled_mutation(local_mutation_id + 9)) return arg1 ^= arg2(); + return arg1 = arg2(); +} + +static int __dredd_replace_unary_operator_PostInc_int(std::function arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg()++; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return arg()--; + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~arg(); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -arg(); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return !arg(); + if (__dredd_enabled_mutation(local_mutation_id + 4)) return arg(); + return arg()++; +} + +static int __dredd_replace_expr_int(std::function arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg(); + if (__dredd_enabled_mutation(local_mutation_id + 0)) return !(arg()); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~(arg()); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -(arg()); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return 0; + if (__dredd_enabled_mutation(local_mutation_id + 4)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 5)) return -1; + return arg(); +} + +static int __dredd_replace_expr_int(int arg, int local_mutation_id) { + if (!__dredd_some_mutation_enabled) return arg; + if (__dredd_enabled_mutation(local_mutation_id + 0)) return !(arg); + if (__dredd_enabled_mutation(local_mutation_id + 1)) return ~(arg); + if (__dredd_enabled_mutation(local_mutation_id + 2)) return -(arg); + if (__dredd_enabled_mutation(local_mutation_id + 3)) return 0; + if (__dredd_enabled_mutation(local_mutation_id + 4)) return 1; + if (__dredd_enabled_mutation(local_mutation_id + 5)) return -1; + return arg; +} + +int main() { + int x = __dredd_replace_expr_int(0, 0); + if (!__dredd_enabled_mutation(45)) { __dredd_replace_binary_operator_Assign_arg1_int_arg2_int(x , [&]() -> int { return static_cast(__dredd_replace_expr_int([&]() -> int { return static_cast((__dredd_replace_expr_int([&]() -> int { return static_cast((__dredd_replace_expr_int(0, 6), __dredd_replace_expr_int([&]() -> int { return static_cast(__dredd_replace_unary_operator_PostInc_int([&]() -> int& { return static_cast(x); }, 12)); }, 17))); }, 23))); }, 29)); }, 35); } +}