[Sol->Yul] Fixing string calldata to bytes calldata conversion.

This commit is contained in:
Djordje Mijovic 2021-02-03 16:56:33 +01:00
parent 8a4e6acdac
commit 530435439d
3 changed files with 30 additions and 2 deletions

View File

@ -3391,7 +3391,11 @@ string YulUtilFunctions::copyStructToStorageFunction(StructType const& _from, St
string YulUtilFunctions::arrayConversionFunction(ArrayType const& _from, ArrayType const& _to) string YulUtilFunctions::arrayConversionFunction(ArrayType const& _from, ArrayType const& _to)
{ {
solAssert(_to.location() != DataLocation::CallData, ""); if (_to.dataStoredIn(DataLocation::CallData))
solAssert(
_from.dataStoredIn(DataLocation::CallData) && _from.isByteArray() && _to.isByteArray(),
""
);
// Other cases are done explicitly in LValue::storeValue, and only possible by assignment. // Other cases are done explicitly in LValue::storeValue, and only possible by assignment.
if (_to.location() == DataLocation::Storage) if (_to.location() == DataLocation::Storage)
@ -3409,16 +3413,22 @@ string YulUtilFunctions::arrayConversionFunction(ArrayType const& _from, ArrayTy
return m_functionCollector.createFunction(functionName, [&]() { return m_functionCollector.createFunction(functionName, [&]() {
Whiskers templ(R"( Whiskers templ(R"(
function <functionName>(value<?fromCalldataDynamic>, length</fromCalldataDynamic>) -> converted { function <functionName>(value<?fromCalldataDynamic>, length</fromCalldataDynamic>) -> converted <?toCalldataDynamic>, outLength</toCalldataDynamic> {
<body> <body>
<?toCalldataDynamic>
outLength := <length>
</toCalldataDynamic>
} }
)"); )");
templ("functionName", functionName); templ("functionName", functionName);
templ("fromCalldataDynamic", _from.dataStoredIn(DataLocation::CallData) && _from.isDynamicallySized()); templ("fromCalldataDynamic", _from.dataStoredIn(DataLocation::CallData) && _from.isDynamicallySized());
templ("toCalldataDynamic", _to.dataStoredIn(DataLocation::CallData) && _to.isDynamicallySized());
templ("length", _from.isDynamicallySized() ? "length" : _from.length().str());
if ( if (
_from == _to || _from == _to ||
(_from.dataStoredIn(DataLocation::Memory) && _to.dataStoredIn(DataLocation::Memory)) || (_from.dataStoredIn(DataLocation::Memory) && _to.dataStoredIn(DataLocation::Memory)) ||
(_from.dataStoredIn(DataLocation::CallData) && _to.dataStoredIn(DataLocation::CallData)) ||
_to.dataStoredIn(DataLocation::Storage) _to.dataStoredIn(DataLocation::Storage)
) )
templ("body", "converted := value"); templ("body", "converted := value");

View File

@ -0,0 +1,9 @@
contract C {
function f(bytes calldata c) public returns (string calldata s) {
return string(c);
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 3, "abc" -> 0x20, 3, "abc"

View File

@ -0,0 +1,9 @@
contract C {
function f(string calldata s) public returns (bytes calldata m) {
return bytes(s);
}
}
// ====
// compileViaYul: also
// ----
// f(string): 0x20, 3, "abc" -> 0x20, 3, "abc"