diff --git a/libsolidity/codegen/CompilerUtils.h b/libsolidity/codegen/CompilerUtils.h index 721f65614..f51f8c3cd 100644 --- a/libsolidity/codegen/CompilerUtils.h +++ b/libsolidity/codegen/CompilerUtils.h @@ -95,9 +95,9 @@ public: /// @returns the number of bytes consumed in memory. unsigned loadFromMemory( unsigned _offset, - Type const& _type = *TypeProvider::uint256(), - bool _fromCalldata = false, - bool _padToWords = false + Type const& _type, + bool _fromCalldata, + bool _padToWords ); /// Dynamic version of @see loadFromMemory, expects the memory offset on the stack. /// Stack pre: memory_offset diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 5df08e0cb..357cc8b2d 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -192,7 +192,12 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont auto const& immutables = contractType.immutableVariables(); // Push all immutable values on the stack. for (auto const& immutable: immutables) - CompilerUtils(m_context).loadFromMemory(static_cast(m_context.immutableMemoryOffset(*immutable)), *immutable->annotation().type); + CompilerUtils(m_context).loadFromMemory( + static_cast(m_context.immutableMemoryOffset(*immutable)), + *immutable->annotation().type, + false, + true + ); m_context.pushSubroutineSize(m_context.runtimeSub()); if (immutables.empty()) m_context << Instruction::DUP1; @@ -439,7 +444,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac // retrieve the function signature hash from the calldata if (!interfaceFunctions.empty()) { - CompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true); + CompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true, false); // stack now is: ? vector> sortedIDs; diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp index 2622f2967..75a7f2749 100644 --- a/libsolidity/codegen/LValue.cpp +++ b/libsolidity/codegen/LValue.cpp @@ -159,7 +159,9 @@ void ImmutableItem::retrieveValue(SourceLocation const&, bool) const if (m_context.runtimeContext()) CompilerUtils(m_context).loadFromMemory( static_cast(m_context.immutableMemoryOffset(m_variable)), - *m_dataType + *m_dataType, + false, + true ); else for (auto&& slotName: m_context.immutableVariableSlotNames(m_variable)) @@ -178,7 +180,7 @@ void ImmutableItem::storeValue(Type const& _sourceType, SourceLocation const&, b utils.moveIntoStack(m_dataType->sizeOnStack()); else utils.copyToStackTop(m_dataType->sizeOnStack() + 1, m_dataType->sizeOnStack()); - utils.storeInMemoryDynamic(*m_dataType, false); + utils.storeInMemoryDynamic(*m_dataType); m_context << Instruction::POP; } diff --git a/test/libsolidity/semanticTests/immutable/immutable_signed.sol b/test/libsolidity/semanticTests/immutable/immutable_signed.sol new file mode 100644 index 000000000..752048739 --- /dev/null +++ b/test/libsolidity/semanticTests/immutable/immutable_signed.sol @@ -0,0 +1,15 @@ +contract C { + int8 immutable a = -2; + bytes2 immutable b = "ab"; + function() internal returns (uint) immutable f = g; + function viaasm() view external returns (bytes32 x, bytes32 y) { + int8 _a = a; + bytes2 _b = b; + assembly { x := _a y := _b } + } + function g() internal pure returns (uint) { return 2; } +} +// ==== +// compileViaYul: also +// ---- +// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/immutable/small_types_in_reverse.sol b/test/libsolidity/semanticTests/immutable/small_types_in_reverse.sol new file mode 100644 index 000000000..677b87d32 --- /dev/null +++ b/test/libsolidity/semanticTests/immutable/small_types_in_reverse.sol @@ -0,0 +1,21 @@ +contract A { + uint16 public immutable a; + uint16 public immutable b; + uint16 public immutable c; + uint16[3] public x; + constructor() { + c = 0xffff; + b = 0x0f0f; + a = 0x1234; + x = [a, b, c]; + } +} +// ==== +// compileViaYul: also +// ---- +// a() -> 4660 +// b() -> 0x0f0f +// c() -> 0xffff +// x(uint256): 0 -> 4660 +// x(uint256): 1 -> 0x0f0f +// x(uint256): 2 -> 0xffff