diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index e881c1e26..e19b6b0dd 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 0c1500b04..6c509685a 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 d2c75445f..66449fc46 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(*m_dataType).isSigned() ) m_context << u256(m_dataType->storageBytes() - 1) << Instruction::SIGNEXTEND; - else if ( - m_dataType->category() == Type::Category::Function && - dynamic_cast(*m_dataType).location() == FunctionType::Location::External - ) - CompilerUtils(m_context).splitExternalFunctionType(false); + else if (FunctionType const* fun = dynamic_cast(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(*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(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(*m_dataType).numBytes())) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 44dba9b26..c665b050e 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; }