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:
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:
Here, the
bar::baz
constant is used to implicitly construct a C++ object, whilefoo()
has anint
operator overload. The ternary expression have a type offoo()
. Dredd would mutatedbaz::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,
Since the final type of resultant expression is exposed in the AST, we can then use this information to mutate the expression:
This might offer an elegant fix for some of the bugs, while still allowing for mutation in these cases.