diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 92b80e875..88f3e7263 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -110,7 +111,7 @@ private: solUnimplementedAssert(varDecl, ""); string const& suffix = reference.suffix; - if (suffix.empty()) + if (suffix.empty() && !varDecl->isStateVariable()) { auto const& var = m_context.localVariable(*varDecl); solAssert(var.type().sizeOnStack() == 1, ""); @@ -122,7 +123,48 @@ private: } string value; - if (varDecl->isStateVariable()) + if (varDecl->isConstant()) + { + VariableDeclaration const* variable = rootConstVariableDeclaration(*varDecl); + solAssert(variable, ""); + + if (variable->value()->annotation().type->category() == Type::Category::RationalNumber) + { + u256 intValue = dynamic_cast(*variable->value()->annotation().type).literalValue(nullptr); + if (auto const* bytesType = dynamic_cast(variable->type())) + intValue <<= 256 - 8 * bytesType->numBytes(); + else + solAssert(variable->type()->category() == Type::Category::Integer, ""); + value = intValue.str(); + } + else if (auto const* literal = dynamic_cast(variable->value().get())) + { + TypePointer type = literal->annotation().type; + + switch (type->category()) + { + case Type::Category::Bool: + case Type::Category::Address: + solAssert(type->category() == variable->annotation().type->category(), ""); + value = toCompactHexWithPrefix(type->literalValue(literal)); + break; + case Type::Category::StringLiteral: + { + auto const& stringLiteral = dynamic_cast(*type); + solAssert(variable->type()->category() == Type::Category::FixedBytes, ""); + unsigned const numBytes = dynamic_cast(*variable->type()).numBytes(); + solAssert(stringLiteral.value().size() <= numBytes, ""); + value = formatNumber(u256(h256(stringLiteral.value(), h256::AlignLeft))); + break; + } + default: + solAssert(false, ""); + } + } + else + solAssert(false, "Invalid constant in inline assembly."); + } + else if (varDecl->isStateVariable()) { if (suffix == "slot") value = m_context.storageLocationOfStateVariable(*varDecl).first.str(); diff --git a/test/libsolidity/semanticTests/constants/asm_address_constant_regression.sol b/test/libsolidity/semanticTests/constants/asm_address_constant_regression.sol index 730b04746..823a94d30 100644 --- a/test/libsolidity/semanticTests/constants/asm_address_constant_regression.sol +++ b/test/libsolidity/semanticTests/constants/asm_address_constant_regression.sol @@ -8,5 +8,7 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // f() -> 0x00 diff --git a/test/libsolidity/semanticTests/inlineAssembly/constant_access.sol b/test/libsolidity/semanticTests/inlineAssembly/constant_access.sol index 835048b85..9b3f4c93d 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/constant_access.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/constant_access.sol @@ -14,5 +14,7 @@ contract C { } } } +// ==== +// compileViaYul: also // ---- // f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212 diff --git a/test/libsolidity/semanticTests/inlineAssembly/constant_access_referencing.sol b/test/libsolidity/semanticTests/inlineAssembly/constant_access_referencing.sol index d2e24a70e..74d563222 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/constant_access_referencing.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/constant_access_referencing.sol @@ -22,5 +22,7 @@ contract C { } } } +// ==== +// compileViaYul: also // ---- // f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212