Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/libdredd/src/mutate_ast_consumer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,13 @@ void MutateAstConsumer::RewriteExpressionsInMainFile() {
}

// Rewrite the constant integer arguments of builtin functions and templates.
std::unordered_set<const clang::Expr*> already_rewritten;
for (const auto* constant_argument_expresion :
visitor_->GetConstantArgumentsToRewrite()) {
if (already_rewritten.contains(constant_argument_expresion)) {
continue;
}
already_rewritten.insert(constant_argument_expresion);
if (const auto integer_const_expr =
constant_argument_expresion->getIntegerConstantExpr(
compiler_instance_->getASTContext())) {
Expand Down
16 changes: 16 additions & 0 deletions test/single_file/true_template_arg.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
template <bool> class C {
public:
C(int*) {}
};

using S = C<true>;

void f() {
S SC(0);
}

bool g() {
S SC(0);
int x;
x = 0;
}
92 changes: 92 additions & 0 deletions test/single_file/true_template_arg.cc.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// DREDD PRELUDE START
// If this has been inserted at an inappropriate place in a source file,
// declare a placeholder function with the following signature to
// mandate where the prelude should be placed:
//
// void __dredd_prelude_start();
//
#include <atomic>
#include <cinttypes>
#include <cstddef>
#include <fstream>
#include <functional>
#include <sstream>
#include <string>


#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 < 13) {
enabled_bitset[local_value / 64] |= (static_cast<uint64_t>(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] & (static_cast<uint64_t>(1) << (local_mutation_id % 64))) != 0;
}

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;
}

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;
}

template <bool> class C {
public:
C(int*) {}
};

using S = C<1>;

void f() {
S SC(0);
}

bool g() {
S SC(0);
int x;
if (!__dredd_enabled_mutation(12)) { __dredd_replace_binary_operator_Assign_arg1_int_arg2_int(x , __dredd_replace_expr_int_zero(0, 0), 2); }
}
96 changes: 96 additions & 0 deletions test/single_file/true_template_arg.cc.noopt.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// DREDD PRELUDE START
// If this has been inserted at an inappropriate place in a source file,
// declare a placeholder function with the following signature to
// mandate where the prelude should be placed:
//
// void __dredd_prelude_start();
//
#include <atomic>
#include <cinttypes>
#include <cstddef>
#include <fstream>
#include <functional>
#include <sstream>
#include <string>


#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 < 17) {
enabled_bitset[local_value / 64] |= (static_cast<uint64_t>(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] & (static_cast<uint64_t>(1) << (local_mutation_id % 64))) != 0;
}

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;
}

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;
}

template <bool> class C {
public:
C(int*) {}
};

using S = C<1>;

void f() {
S SC(0);
}

bool g() {
S SC(0);
int x;
if (!__dredd_enabled_mutation(16)) { __dredd_replace_binary_operator_Assign_arg1_int_arg2_int(x , __dredd_replace_expr_int(0, 0), 6); }
}
Loading