From 765ed13814b7547cc8c337b09d5bda098269e697 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 9 Nov 2020 17:12:29 +0100 Subject: [PATCH] Immutables with literal values are pure. --- Changelog.md | 1 + libsolidity/analysis/ViewPureChecker.cpp | 10 ++++++++-- .../standard_immutable_references/input.json | 2 +- .../standard_immutable_references/output.json | 2 +- .../syntaxTests/immutable/unrelated_reading.sol | 2 +- .../syntaxTests/viewPureChecker/immutable.sol | 1 - 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Changelog.md b/Changelog.md index 949eeff1f..b566dd52e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ Language Features: * Ability to select the abi coder using ``pragma abicoder v1`` and ``pragma abicoder v2``. + * Immutable variables with literal number values are considered pure. Compiler Features: * SMTChecker: Add division by zero checks in the CHC engine. diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index f684bc289..a5ec40eb4 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -186,7 +186,13 @@ void ViewPureChecker::endVisit(Identifier const& _identifier) bool writes = _identifier.annotation().willBeWrittenTo; if (VariableDeclaration const* varDecl = dynamic_cast(declaration)) { - if (varDecl->isStateVariable() && !varDecl->isConstant()) + if (varDecl->immutable()) + { + // Immutables that are assigned literals are pure. + if (!(varDecl->value() && varDecl->value()->annotation().type->category() == Type::Category::RationalNumber)) + mutability = StateMutability::View; + } + else if (varDecl->isStateVariable() && !varDecl->isConstant()) mutability = writes ? StateMutability::NonPayable : StateMutability::View; } else if (MagicVariableDeclaration const* magicVar = dynamic_cast(declaration)) @@ -291,7 +297,7 @@ void ViewPureChecker::reportMutability( m_currentFunction->stateMutability() == StateMutability::Pure || m_currentFunction->stateMutability() == StateMutability::NonPayable, "" - ); + ); } ViewPureChecker::MutabilityAndLocation const& ViewPureChecker::modifierMutability( diff --git a/test/cmdlineTests/standard_immutable_references/input.json b/test/cmdlineTests/standard_immutable_references/input.json index d81365c8a..6103dbed8 100644 --- a/test/cmdlineTests/standard_immutable_references/input.json +++ b/test/cmdlineTests/standard_immutable_references/input.json @@ -2,7 +2,7 @@ "language": "Solidity", "sources": { "a.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0\ncontract A { uint256 immutable x = 1; function f() public view returns (uint256) { return x; } }" + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract A { uint256 immutable x = 1 + 3; function f() public pure returns (uint256) { return x; } }" } }, "settings": { diff --git a/test/cmdlineTests/standard_immutable_references/output.json b/test/cmdlineTests/standard_immutable_references/output.json index 25537229f..2e17184ef 100644 --- a/test/cmdlineTests/standard_immutable_references/output.json +++ b/test/cmdlineTests/standard_immutable_references/output.json @@ -1,2 +1,2 @@ -{"contracts":{"a.sol":{"A":{"evm":{"deployedBytecode":{"generatedSources":[],"immutableReferences":{"3":[{"length":32,"start":77}]},"linkReferences":{},"object":"","opcodes":"","sourceMap":"36:96:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;108:7;126:1;119:8;;74:56;:::o"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version! +{"contracts":{"a.sol":{"A":{"evm":{"deployedBytecode":{"generatedSources":[],"immutableReferences":{"5":[{"length":32,"start":77}]},"linkReferences":{},"object":"","opcodes":"","sourceMap":"36:100:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;112:7;130:1;123:8;;78:56;:::o"}}}}},"errors":[{"component":"general","errorCode":"3420","formattedMessage":"a.sol: Warning: Source file does not specify required compiler version! ","message":"Source file does not specify required compiler version!","severity":"warning","sourceLocation":{"end":-1,"file":"a.sol","start":-1},"type":"Warning"}],"sources":{"a.sol":{"id":0}}} diff --git a/test/libsolidity/syntaxTests/immutable/unrelated_reading.sol b/test/libsolidity/syntaxTests/immutable/unrelated_reading.sol index 2b5614650..8eac18c7a 100644 --- a/test/libsolidity/syntaxTests/immutable/unrelated_reading.sol +++ b/test/libsolidity/syntaxTests/immutable/unrelated_reading.sol @@ -1,7 +1,7 @@ contract C { uint immutable x = 1; - function readX() internal view returns(uint) { + function readX() internal pure returns(uint) { return x + 3; } } diff --git a/test/libsolidity/syntaxTests/viewPureChecker/immutable.sol b/test/libsolidity/syntaxTests/viewPureChecker/immutable.sol index 2ef5d1023..a1081959e 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/immutable.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/immutable.sol @@ -5,4 +5,3 @@ contract B { } } // ---- -// TypeError 2527: (100-101): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".