mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #244 from chriseth/fix_stringAlloc
Fix for memory allocation bug.
This commit is contained in:
commit
aa8e9e66ed
@ -781,7 +781,7 @@ bool ArrayType::operator==(Type const& _other) const
|
||||
unsigned ArrayType::calldataEncodedSize(bool _padded) const
|
||||
{
|
||||
if (isDynamicallySized())
|
||||
return 0;
|
||||
return 32;
|
||||
bigint size = bigint(length()) * (isByteArray() ? 1 : baseType()->calldataEncodedSize(_padded));
|
||||
size = ((size + 31) / 32) * 32;
|
||||
solAssert(size <= numeric_limits<unsigned>::max(), "Array size does not fit unsigned.");
|
||||
@ -1698,7 +1698,7 @@ FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary) const
|
||||
TypePointers returnParameterTypes;
|
||||
vector<string> returnParameterNames;
|
||||
for (size_t i = 0; i < m_returnParameterTypes.size(); ++i)
|
||||
if (m_returnParameterTypes[i]->calldataEncodedSize() > 0)
|
||||
if (!m_returnParameterTypes[i]->isDynamicallySized())
|
||||
{
|
||||
returnParameterTypes.push_back(m_returnParameterTypes[i]);
|
||||
returnParameterNames.push_back(m_returnParameterNames[i]);
|
||||
|
@ -175,8 +175,9 @@ public:
|
||||
virtual bool operator==(Type const& _other) const { return category() == _other.category(); }
|
||||
virtual bool operator!=(Type const& _other) const { return !this->operator ==(_other); }
|
||||
|
||||
/// @returns number of bytes used by this type when encoded for CALL, or 0 if the encoding
|
||||
/// is not a simple big-endian encoding or the type cannot be stored in calldata.
|
||||
/// @returns number of bytes used by this type when encoded for CALL. If it is a dynamic type,
|
||||
/// returns the size of the pointer (usually 32). Returns 0 if the type cannot be encoded
|
||||
/// in calldata.
|
||||
/// If @a _padded then it is assumed that each element is padded to a multiple of 32 bytes.
|
||||
virtual unsigned calldataEncodedSize(bool _padded) const { (void)_padded; return 0; }
|
||||
/// @returns the size of this data type in bytes when stored in memory. For memory-reference
|
||||
|
@ -271,7 +271,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
|
||||
void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWordBoundaries) const
|
||||
{
|
||||
solAssert(
|
||||
_sourceType.baseType()->calldataEncodedSize() > 0,
|
||||
!_sourceType.baseType()->isDynamicallySized(),
|
||||
"Nested dynamic arrays not implemented here."
|
||||
);
|
||||
CompilerUtils utils(m_context);
|
||||
|
@ -92,13 +92,6 @@ private:
|
||||
void registerStateVariables(ContractDefinition const& _contract);
|
||||
void initializeStateVariables(ContractDefinition const& _contract);
|
||||
|
||||
/// Initialises all memory arrays in the local variables to point to an empty location.
|
||||
void initialiseMemoryArrays(std::vector<VariableDeclaration const*> _variables);
|
||||
/// Pushes the initialised value of the given type to the stack. If the type is a memory
|
||||
/// reference type, allocates memory and pushes the memory pointer.
|
||||
/// Not to be used for storage references.
|
||||
void initialiseInMemory(Type const& _type);
|
||||
|
||||
virtual bool visit(VariableDeclaration const& _variableDeclaration) override;
|
||||
virtual bool visit(FunctionDefinition const& _function) override;
|
||||
virtual bool visit(IfStatement const& _ifStatement) override;
|
||||
|
@ -613,7 +613,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerUtils::pushZeroValue(const Type& _type)
|
||||
void CompilerUtils::pushZeroValue(Type const& _type)
|
||||
{
|
||||
auto const* referenceType = dynamic_cast<ReferenceType const*>(&_type);
|
||||
if (!referenceType || referenceType->location() == DataLocation::Storage)
|
||||
|
@ -1226,7 +1226,7 @@ void ExpressionCompiler::appendExternalFunctionCall(
|
||||
else
|
||||
for (auto const& retType: _functionType.returnParameterTypes())
|
||||
{
|
||||
solAssert(retType->calldataEncodedSize() > 0, "Unable to return dynamic type from external call.");
|
||||
solAssert(!retType->isDynamicallySized(), "Unable to return dynamic type from external call.");
|
||||
retSize += retType->calldataEncodedSize();
|
||||
}
|
||||
|
||||
|
@ -5849,6 +5849,37 @@ BOOST_AUTO_TEST_CASE(addmod_mulmod)
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(0)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(string_allocation_bug)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract Sample
|
||||
{
|
||||
struct s { uint16 x; uint16 y; string a; string b;}
|
||||
s[2] public p;
|
||||
function Sample() {
|
||||
s memory m;
|
||||
m.x = 0xbbbb;
|
||||
m.y = 0xcccc;
|
||||
m.a = "hello";
|
||||
m.b = "world";
|
||||
p[0] = m;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("p(uint256)") == encodeArgs(
|
||||
u256(0xbbbb),
|
||||
u256(0xcccc),
|
||||
u256(0x80),
|
||||
u256(0xc0),
|
||||
u256(5),
|
||||
string("hello"),
|
||||
u256(5),
|
||||
string("world")
|
||||
));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user