mc-imperial / dredd

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

Problem with inline operators when using Dredd to mutate tint #221

Closed ambergorzynski closed 3 months ago

ambergorzynski commented 4 months ago

Dredd appears to have problems mutating inline operators within tint. I have run into this issue in several different files and with multiple operators, but they all follow the example below.

Example

Using Dredd to mutate this tint file gives the following error message:

/data/dev/dawn_mutated_transform/src/tint/lang/core/ir/transform/robustness.cc:533:97: error: no matching member function for call to 'Constant'
                    if (!__dredd_enabled_mutation(277)) { return b.Subtract(ty.u32(), length, b.Constant(__dredd_replace_expr_unsigned_long_long_one(1_u, 273)))->Result(__dredd_replace_expr_unsigned_long_zero(0, 275)); }
                                                                                              ~~^~~~~~~~
/data/dev/dawn_mutated_transform/src/tint/lang/core/ir/builder.h:331:19: note: candidate function not viable: no known conversion from 'unsigned long long' to 'const core::constant::Value *' for 1st argument
    ir::Constant* Constant(const core::constant::Value* val) {
                  ^
/data/dev/dawn_mutated_transform/src/tint/lang/core/ir/builder.h:339:19: note: candidate function not viable: no known conversion from 'unsigned long long' to 'core::i32' (aka 'Number<int>') for 1st argument
    ir::Constant* Constant(core::i32 v) { return Constant(ConstantValue(v)); }
                  ^
/data/dev/dawn_mutated_transform/src/tint/lang/core/ir/builder.h:344:19: note: candidate function not viable: no known conversion from 'unsigned long long' to 'core::u32' (aka 'Number<unsigned int>') for 1st argument
    ir::Constant* Constant(core::u32 v) { return Constant(ConstantValue(v)); }
                  ^
/data/dev/dawn_mutated_transform/src/tint/lang/core/ir/builder.h:349:19: note: candidate function not viable: no known conversion from 'unsigned long long' to 'core::f32' (aka 'Number<float>') for 1st argument
    ir::Constant* Constant(core::f32 v) { return Constant(ConstantValue(v)); }
                  ^
/data/dev/dawn_mutated_transform/src/tint/lang/core/ir/builder.h:354:19: note: candidate function not viable: no known conversion from 'unsigned long long' to 'core::f16' (aka 'Number<tint::core::detail::NumberKindF16>') for 1st argument
    ir::Constant* Constant(core::f16 v) { return Constant(ConstantValue(v)); }
                  ^
/data/dev/dawn_mutated_transform/src/tint/lang/core/ir/builder.h:360:19: note: candidate template ignored: requirement 'std::is_same_v<unsigned long long, bool>' was not satisfied [with BOOL = unsigned long long]
    ir::Constant* Constant(BOOL v) {
                  ^

The unmutated tint code is here, and the relevant expression is:

b.Constant(1_u)

Dredd mutates this to:

b.Constant(__dredd_replace_expr_unsigned_long_long_one(1_u, 273))

Where the function __dredd_replace_expr_unsigned_long_long_one(unsigned long long int, int) has return type unsigned long long int. However, the overloaded tint function Constant(declared here) only accepts a parameter of type core::constant::Value*, core::i32, core::u32, core::f32, core::f16, or BOOL.

The problem appears to be that Dredd appears is incorrectly parsing the expression 1_u. Tint defines _u as an inline suffix operator here:

/// Literal suffix for u32 literals
inline u32 operator""_u(unsigned long long int value) {  // NOLINT
    return u32(static_cast<uint32_t>(value));
}

Dredd appears to not understand _u as an inline operator that has return type u32. It is correct that the value 1 in the expression b.Constant(1_u) has type unsigned long long int, however I think that the correct mutation should be within the _u suffix like so:

b.Constant((__dredd_replace_expr_unsigned_long_long_one(1, 273))_u)

afd commented 4 months ago

Very interesting - are you able to provide a minimal example on which Dredd does the wrong thing?