mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Encode storage items correctly for library calls.
This commit is contained in:
parent
421dcf4c1a
commit
ce25ddfa6a
@ -189,7 +189,14 @@ void CompilerUtils::encodeToMemory(
|
|||||||
copyToStackTop(argSize - stackPos + dynPointers + 2, _givenTypes[i]->sizeOnStack());
|
copyToStackTop(argSize - stackPos + dynPointers + 2, _givenTypes[i]->sizeOnStack());
|
||||||
solAssert(!!targetType, "Externalable type expected.");
|
solAssert(!!targetType, "Externalable type expected.");
|
||||||
TypePointer type = targetType;
|
TypePointer type = targetType;
|
||||||
if (
|
if (_givenTypes[i]->dataStoredIn(DataLocation::Storage) && targetType->isValueType())
|
||||||
|
{
|
||||||
|
// special case: convert storage reference type to value type - this is only
|
||||||
|
// possible for library calls where we just forward the storage reference
|
||||||
|
solAssert(_encodeAsLibraryTypes, "");
|
||||||
|
solAssert(_givenTypes[i]->sizeOnStack() == 1, "");
|
||||||
|
}
|
||||||
|
else if (
|
||||||
_givenTypes[i]->dataStoredIn(DataLocation::Storage) ||
|
_givenTypes[i]->dataStoredIn(DataLocation::Storage) ||
|
||||||
_givenTypes[i]->dataStoredIn(DataLocation::CallData) ||
|
_givenTypes[i]->dataStoredIn(DataLocation::CallData) ||
|
||||||
_givenTypes[i]->category() == Type::Category::StringLiteral
|
_givenTypes[i]->category() == Type::Category::StringLiteral
|
||||||
|
@ -1179,7 +1179,8 @@ void ExpressionCompiler::appendExternalFunctionCall(
|
|||||||
argumentTypes,
|
argumentTypes,
|
||||||
_functionType.parameterTypes(),
|
_functionType.parameterTypes(),
|
||||||
_functionType.padArguments(),
|
_functionType.padArguments(),
|
||||||
_functionType.takesArbitraryParameters()
|
_functionType.takesArbitraryParameters(),
|
||||||
|
isCallCode
|
||||||
);
|
);
|
||||||
|
|
||||||
// Stack now:
|
// Stack now:
|
||||||
|
@ -5383,6 +5383,32 @@ BOOST_AUTO_TEST_CASE(internal_types_in_library)
|
|||||||
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(4), u256(17)));
|
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(4), u256(17)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(differentiate_storage_and_memory_in_libraries)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
library Lib {
|
||||||
|
function f(uint[] storage x) returns (uint) { return 1; }
|
||||||
|
function f(uint[] memory x) returns (uint) { return 2; }
|
||||||
|
}
|
||||||
|
contract Test {
|
||||||
|
uint[] data;
|
||||||
|
function f() returns (uint a,)
|
||||||
|
{
|
||||||
|
uint[] memory d = data;
|
||||||
|
Lib.f(d)
|
||||||
|
data["abc"].length = 20;
|
||||||
|
data["abc"][4] = 9;
|
||||||
|
data["abc"][17] = 3;
|
||||||
|
a = Lib.find(data["abc"], 9);
|
||||||
|
b = Lib.find(data["abc"], 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode, 0, "Lib");
|
||||||
|
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}});
|
||||||
|
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(4), u256(17)));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(short_strings)
|
BOOST_AUTO_TEST_CASE(short_strings)
|
||||||
{
|
{
|
||||||
// This test verifies that the byte array encoding that combines length and data works
|
// This test verifies that the byte array encoding that combines length and data works
|
||||||
|
Loading…
Reference in New Issue
Block a user