diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 7faf0d43c..553f618cd 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1304,7 +1304,20 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) solAssert(false, "Blockhash has been removed."); else if (member == "creationCode" || member == "runtimeCode") { - solUnimplementedAssert(false, ""); + solUnimplementedAssert(member != "runtimeCode", ""); + TypePointer arg = dynamic_cast(*_memberAccess.expression().annotation().type).typeArgument(); + ContractDefinition const& contract = dynamic_cast(*arg).contractDefinition(); + m_context.subObjectsCreated().insert(&contract); + m_code << Whiskers(R"( + let := datasize("") + let := (add(, 32)) + mstore(, ) + datacopy(add(, 32), dataoffset(""), ) + )") + ("allocationFunction", m_utils.allocationFunction()) + ("size", m_context.newYulVariable()) + ("objectName", m_context.creationObjectName(contract)) + ("result", IRVariable(_memberAccess).commaSeparatedList()).render(); } else if (member == "name") { diff --git a/test/libsolidity/semanticTests/constructor/callvalue_check.sol b/test/libsolidity/semanticTests/constructor/callvalue_check.sol index 7a327e695..c096382d0 100644 --- a/test/libsolidity/semanticTests/constructor/callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/callvalue_check.sol @@ -29,6 +29,7 @@ contract C { } // ==== // EVMVersion: >homestead +// compileViaYul: also // ---- // f(uint256), 2000 ether: 0 -> true // f(uint256), 2000 ether: 100 -> false diff --git a/test/libsolidity/semanticTests/various/code_access_create.sol b/test/libsolidity/semanticTests/various/code_access_create.sol index 3fbcf6132..9029e59ec 100644 --- a/test/libsolidity/semanticTests/various/code_access_create.sol +++ b/test/libsolidity/semanticTests/various/code_access_create.sol @@ -22,5 +22,7 @@ contract C { } } +// ==== +// compileViaYul: also // ---- // test() -> 7 diff --git a/test/libsolidity/semanticTests/various/code_access_runtime.sol b/test/libsolidity/semanticTests/various/code_access_runtime.sol new file mode 100644 index 000000000..cc1401c6f --- /dev/null +++ b/test/libsolidity/semanticTests/various/code_access_runtime.sol @@ -0,0 +1,27 @@ +contract D { + uint256 x; + + constructor() public { + x = 7; + } + + function f() public view returns (uint256) { + return x; + } +} + + +contract C { + function test() public returns (uint256) { + D d = new D(); + bytes32 hash; + assembly { hash := extcodehash(d) } + assert(hash == keccak256(type(D).runtimeCode)); + return 42; + } +} + +// ==== +// EVMVersion: >=constantinople +// ---- +// test() -> 42