mc-imperial / dredd

Framework for evaluating C/C++ compiler testing tools
Apache License 2.0
11 stars 3 forks source link

Generate templated mutator function in C++ program #282

Open JonathanFoo0523 opened 1 month ago

JonathanFoo0523 commented 1 month ago

Several bugs (#264, #270) have been discovered in Dredd due to the mutation of certain expressions forcing a type on the expression.

This test case taken from the single file test of PR #267 capture this issue:

struct foo {
  foo(int) {};
  operator int();
};

enum baz { bar };

int main() { 
  0 ? foo(0) : baz::bar;
}

Here, the bar::baz constant is used to implicitly construct a C++ object, while foo() has an int operator overload. The ternary expression have a type of foo(). Dredd would mutated baz::bar; to __dredd_replace_expr_int_zero(baz::bar, 3);, which cause ambiguity on the final type of resultant expression. PR #267 addressed this issue by detecting this special case and avoid mutation on the enum constant.

We might be able to solve this issue by using templated static function. For instance,

template <typename T> 
static T __dredd_replace_expr_int_like_zero(T 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;
}

Since the final type of resultant expression is exposed in the AST, we can then use this information to mutate the expression:

__dredd_replace_expr_int_like_zero<foo>(baz::bar, 3)

This might offer an elegant fix for some of the bugs, while still allowing for mutation in these cases.