diff options
-rw-r--r-- | libevmasm/Assembly.cpp | 1 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerContext.h | 2 | ||||
-rw-r--r-- | libsolidity/codegen/LValue.cpp | 26 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 4 |
4 files changed, 19 insertions, 14 deletions
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index e881c1e2..e19b6b0d 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -485,6 +485,7 @@ LinkerObject const& Assembly::assemble() const break; case Tag: tagPos[(unsigned)i.data()] = ret.bytecode.size(); + assertThrow(ret.bytecode.size() < 0xffffffffL, AssemblyException, "Tag too large."); assertThrow(i.data() != 0, AssemblyException, ""); ret.bytecode.push_back((byte)Instruction::JUMPDEST); break; diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 0c1500b0..6c509685 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -44,6 +44,8 @@ namespace solidity { class CompilerContext { public: + bool isCreationPhase() const { return m_mode == CompilationMode::Creation; } + void addMagicGlobal(MagicVariableDeclaration const& _declaration); void addStateVariable(VariableDeclaration const& _declaration, u256 const& _storageOffset, unsigned _byteOffset); void addVariable(VariableDeclaration const& _declaration, unsigned _offsetToCurrent = 0); diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index d2c75445..66449fc4 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -190,11 +190,11 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const dynamic_cast<IntegerType const&>(*m_dataType).isSigned() ) m_context << u256(m_dataType->storageBytes() - 1) << Instruction::SIGNEXTEND; - else if ( - m_dataType->category() == Type::Category::Function && - dynamic_cast<FunctionType const&>(*m_dataType).location() == FunctionType::Location::External - ) - CompilerUtils(m_context).splitExternalFunctionType(false); + else if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType)) + { + if (fun->location() == FunctionType::Location::External) + CompilerUtils(m_context).splitExternalFunctionType(false); + } else { solAssert(m_dataType->sizeOnStack() == 1, ""); @@ -236,12 +236,16 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc // stack: value storage_ref cleared_value multiplier utils.copyToStackTop(3 + m_dataType->sizeOnStack(), m_dataType->sizeOnStack()); // stack: value storage_ref cleared_value multiplier value - if ( - m_dataType->category() == Type::Category::Function && - dynamic_cast<FunctionType const&>(*m_dataType).location() == FunctionType::Location::External - ) - // Combine the two-item function type into a single stack slot. - utils.combineExternalFunctionType(false); + if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType)) + { + if (fun->location() == FunctionType::Location::External) + // Combine the two-item function type into a single stack slot. + utils.combineExternalFunctionType(false); + else + m_context << + ((u256(1) << (8 * m_dataType->storageBytes())) - 1) << + Instruction::AND; + } else if (m_dataType->category() == Type::Category::FixedBytes) m_context << (u256(0x1) << (256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes())) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 44dba9b2..c665b050 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7631,8 +7631,6 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function) BOOST_AUTO_TEST_CASE(calling_uninitialized_function_in_detail) { - // Storage default value of zero would be correct jump dest, this tests that - // that is properly handled. char const* sourceCode = R"( contract C { function() internal returns (uint) x; @@ -7641,7 +7639,7 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function_in_detail) if (mutex > 0) return 7; mutex = 1; - // If this test fails, it will jump to "0" and re-execute this function. + // Avoid re-executing this function if we jump somewhere. x(); return 2; } |