diff --git a/Changelog.md b/Changelog.md index 98a0ca408..d17bbadf8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,7 +10,7 @@ Compiler Features: Bugfixes: * ABI: Skip ``private`` or ``internal`` constructors. - + * Type Checker: Disallow accessing ``runtimeCode`` for contract types that contain immutable state variables. diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 7277714b8..71b3f3a3c 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -2663,9 +2663,19 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) )) { annotation.isPure = true; - m_scope->annotation().contractDependencies.insert( - &dynamic_cast(*magicType->typeArgument()).contractDefinition() - ); + ContractType const& accessedContractType = dynamic_cast(*magicType->typeArgument()); + m_scope->annotation().contractDependencies.insert(&accessedContractType.contractDefinition()); + + if ( + memberName == "runtimeCode" && + !accessedContractType.immutableVariables().empty() + ) + m_errorReporter.typeError( + 9274_error, + _memberAccess.location(), + "\"runtimeCode\" is not available for contracts containing immutable variables." + ); + if (contractDependenciesAreCyclic(*m_scope)) m_errorReporter.typeError( 4224_error, diff --git a/test/libsolidity/syntaxTests/immutable/creationCode.sol b/test/libsolidity/syntaxTests/immutable/creationCode.sol new file mode 100644 index 000000000..aa747ba3e --- /dev/null +++ b/test/libsolidity/syntaxTests/immutable/creationCode.sol @@ -0,0 +1,9 @@ +contract A { + address public immutable user = address(0x0); +} + +contract Test { + function test() public pure returns(bytes memory) { + return type(A).creationCode; + } +} diff --git a/test/libsolidity/syntaxTests/immutable/runtimeCode.sol b/test/libsolidity/syntaxTests/immutable/runtimeCode.sol new file mode 100644 index 000000000..7db3245dc --- /dev/null +++ b/test/libsolidity/syntaxTests/immutable/runtimeCode.sol @@ -0,0 +1,11 @@ +contract A { + address public immutable user = address(0x0); +} + +contract Test { + function test() public pure returns(bytes memory) { + return type(A).runtimeCode; + } +} +// ---- +// TypeError: (153-172): "runtimeCode" is not available for contracts containing immutable variables. diff --git a/test/libsolidity/syntaxTests/immutable/runtimeCodeInheritance.sol b/test/libsolidity/syntaxTests/immutable/runtimeCodeInheritance.sol new file mode 100644 index 000000000..aec4acd2e --- /dev/null +++ b/test/libsolidity/syntaxTests/immutable/runtimeCodeInheritance.sol @@ -0,0 +1,13 @@ +contract Base { + address public immutable user = address(0x0); +} + +contract Derived is Base {} + +contract Test { + function test() public pure returns(bytes memory) { + return type(Derived).runtimeCode; + } +} +// ---- +// TypeError: (185-210): "runtimeCode" is not available for contracts containing immutable variables.