diff --git a/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp b/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp index 325944a4b..c095342b7 100644 --- a/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp +++ b/test/tools/ossfuzz/protomutators/YulProtoMutator.cpp @@ -977,4 +977,39 @@ void YulProtoMutator::configureCall(FunctionCall *_call, unsigned int _seed) case FunctionCall_Returns_ZERO: break; } +} + +template +T YulProtoMutator::EnumTypeConverter::validEnum(unsigned _seed) +{ + auto ret = static_cast(_seed % (enumMax() + 1) + enumMin()); + if constexpr (std::is_same_v, FunctionCall_Returns>) + yulAssert(FunctionCall_Returns_IsValid(ret), "Yul proto mutator: Invalid enum"); + else if constexpr (std::is_same_v, StoreFunc_Storage>) + yulAssert(StoreFunc_Storage_IsValid(ret), "Yul proto mutator: Invalid enum"); + else + static_assert(AlwaysFalse::value, "Yul proto mutator: non-exhaustive visitor."); + return ret; +} + +template +int YulProtoMutator::EnumTypeConverter::enumMax() +{ + if constexpr (std::is_same_v, FunctionCall_Returns>) + return FunctionCall_Returns_Returns_MAX; + else if constexpr (std::is_same_v, StoreFunc_Storage>) + return StoreFunc_Storage_Storage_MAX; + else + static_assert(AlwaysFalse::value, "Yul proto mutator: non-exhaustive visitor."); +} + +template +int YulProtoMutator::EnumTypeConverter::enumMin() +{ + if constexpr (std::is_same_v, FunctionCall_Returns>) + return FunctionCall_Returns_Returns_MIN; + else if constexpr (std::is_same_v, StoreFunc_Storage>) + return StoreFunc_Storage_Storage_MIN; + else + static_assert(AlwaysFalse::value, "Yul proto mutator: non-exhaustive visitor."); } \ No newline at end of file diff --git a/test/tools/ossfuzz/protomutators/YulProtoMutator.h b/test/tools/ossfuzz/protomutators/YulProtoMutator.h index e68d266cd..9012b0b59 100644 --- a/test/tools/ossfuzz/protomutators/YulProtoMutator.h +++ b/test/tools/ossfuzz/protomutators/YulProtoMutator.h @@ -55,29 +55,15 @@ struct YulProtoMutator { T enumFromSeed(unsigned _seed) { - // TODO: Assert validity of return enum. - return static_cast(_seed % (enumMax() + 1) + enumMin()); + return validEnum(_seed); } - static int enumMax() - { - if constexpr (std::is_same_v, FunctionCall_Returns>) - return FunctionCall_Returns_Returns_MAX; - else if constexpr (std::is_same_v, StoreFunc_Storage>) - return StoreFunc_Storage_Storage_MAX; - else - static_assert(AlwaysFalse::value, "Yul proto mutator: non-exhaustive visitor."); - } - - static int enumMin() - { - if constexpr (std::is_same_v, FunctionCall_Returns>) - return FunctionCall_Returns_Returns_MIN; - else if constexpr (std::is_same_v, StoreFunc_Storage>) - return StoreFunc_Storage_Storage_MIN; - else - static_assert(AlwaysFalse::value, "Yul proto mutator: non-exhaustive visitor."); - } + /// Return a valid enum of type T from _seed + T validEnum(unsigned _seed); + /// Return maximum enum value for enum of type T + static int enumMax(); + /// Return minimum enum value for enum of type T + static int enumMin(); }; static constexpr unsigned s_lowIP = 827;