aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-11-24 23:18:41 +0800
committerchriseth <c@ethdev.com>2015-11-24 23:18:41 +0800
commitaa8e9e66ed5e7dda20a7b91d7e4a65fff2264237 (patch)
treef5e2ad4578cbaf5579a0478d2929ad965b94d27b
parente59b9b445aead10dfd83a9e33a4f97853094de74 (diff)
parent68f1da1e3ad6ab914e8f633ac7f661b38894ca2b (diff)
downloaddexon-solidity-aa8e9e66ed5e7dda20a7b91d7e4a65fff2264237.tar.gz
dexon-solidity-aa8e9e66ed5e7dda20a7b91d7e4a65fff2264237.tar.zst
dexon-solidity-aa8e9e66ed5e7dda20a7b91d7e4a65fff2264237.zip
Merge pull request #244 from chriseth/fix_stringAlloc
Fix for memory allocation bug.
-rw-r--r--libsolidity/ast/Types.cpp4
-rw-r--r--libsolidity/ast/Types.h5
-rw-r--r--libsolidity/codegen/ArrayUtils.cpp2
-rw-r--r--libsolidity/codegen/Compiler.h7
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp2
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp2
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp31
7 files changed, 39 insertions, 14 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 0253e843..cb97eae8 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -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]);
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 59c84b7a..f5aefa25 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -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
diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp
index ba26caa6..f1acce31 100644
--- a/libsolidity/codegen/ArrayUtils.cpp
+++ b/libsolidity/codegen/ArrayUtils.cpp
@@ -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);
diff --git a/libsolidity/codegen/Compiler.h b/libsolidity/codegen/Compiler.h
index 14314434..9d069f7c 100644
--- a/libsolidity/codegen/Compiler.h
+++ b/libsolidity/codegen/Compiler.h
@@ -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;
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index ce20f2d1..2ebf5b64 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -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)
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 05d9ea1c..1a089d63 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -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();
}
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 20fef48d..93b42c51 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -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()
}