| 4298 | } |
| 4299 | |
| 4300 | std::string YulUtilFunctions::zeroValueFunction(Type const& _type, bool _splitFunctionTypes) |
| 4301 | { |
| 4302 | solAssert(_type.category() != Type::Category::Mapping, ""); |
| 4303 | |
| 4304 | std::string const functionName = "zero_value_for_" + std::string(_splitFunctionTypes ? "split_" : "") + _type.identifier(); |
| 4305 | |
| 4306 | return m_functionCollector.createFunction(functionName, [&]() { |
| 4307 | FunctionType const* fType = dynamic_cast<FunctionType const*>(&_type); |
| 4308 | if (fType && fType->kind() == FunctionType::Kind::External && _splitFunctionTypes) |
| 4309 | return Whiskers(R"( |
| 4310 | function <functionName>() -> retAddress, retFunction { |
| 4311 | retAddress := 0 |
| 4312 | retFunction := 0 |
| 4313 | } |
| 4314 | )") |
| 4315 | ("functionName", functionName) |
| 4316 | .render(); |
| 4317 | |
| 4318 | if (_type.dataStoredIn(DataLocation::CallData)) |
| 4319 | { |
| 4320 | solAssert( |
| 4321 | _type.category() == Type::Category::Struct || |
| 4322 | _type.category() == Type::Category::Array, |
| 4323 | ""); |
| 4324 | Whiskers templ(R"( |
| 4325 | function <functionName>() -> offset<?hasLength>, length</hasLength> { |
| 4326 | offset := calldatasize() |
| 4327 | <?hasLength> length := 0 </hasLength> |
| 4328 | } |
| 4329 | )"); |
| 4330 | templ("functionName", functionName); |
| 4331 | templ("hasLength", |
| 4332 | _type.category() == Type::Category::Array && |
| 4333 | dynamic_cast<ArrayType const&>(_type).isDynamicallySized() |
| 4334 | ); |
| 4335 | |
| 4336 | return templ.render(); |
| 4337 | } |
| 4338 | |
| 4339 | Whiskers templ(R"( |
| 4340 | function <functionName>() -> ret { |
| 4341 | ret := <zeroValue> |
| 4342 | } |
| 4343 | )"); |
| 4344 | templ("functionName", functionName); |
| 4345 | |
| 4346 | if (_type.isValueType()) |
| 4347 | { |
| 4348 | solAssert(( |
| 4349 | _type.hasSimpleZeroValueInMemory() || |
| 4350 | (fType && (fType->kind() == FunctionType::Kind::Internal || fType->kind() == FunctionType::Kind::External)) |
| 4351 | ), ""); |
| 4352 | templ("zeroValue", "0"); |
| 4353 | } |
| 4354 | else |
| 4355 | { |
| 4356 | solAssert(_type.dataStoredIn(DataLocation::Memory), ""); |
| 4357 | if (auto const* arrayType = dynamic_cast<ArrayType const*>(&_type)) |
no test coverage detected