Enforcing error on msg.gas and block.blockhash()

This commit is contained in:
Leonardo Alt 2018-07-04 11:42:05 +02:00
parent 533d5d4b1c
commit 8202d512e0
9 changed files with 20 additions and 68 deletions

View File

@ -150,36 +150,18 @@ bool StaticAnalyzer::visit(ExpressionStatement const& _statement)
bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) bool StaticAnalyzer::visit(MemberAccess const& _memberAccess)
{ {
bool const v050 = m_currentContract->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
if (MagicType const* type = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type.get())) if (MagicType const* type = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type.get()))
{ {
if (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == "gas") if (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == "gas")
{
if (v050)
m_errorReporter.typeError( m_errorReporter.typeError(
_memberAccess.location(), _memberAccess.location(),
"\"msg.gas\" has been deprecated in favor of \"gasleft()\"" "\"msg.gas\" has been deprecated in favor of \"gasleft()\""
); );
else else if (type->kind() == MagicType::Kind::Block && _memberAccess.memberName() == "blockhash")
m_errorReporter.warning(
_memberAccess.location(),
"\"msg.gas\" has been deprecated in favor of \"gasleft()\""
);
}
if (type->kind() == MagicType::Kind::Block && _memberAccess.memberName() == "blockhash")
{
if (v050)
m_errorReporter.typeError( m_errorReporter.typeError(
_memberAccess.location(), _memberAccess.location(),
"\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
); );
else
m_errorReporter.warning(
_memberAccess.location(),
"\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
);
}
} }
if (m_nonPayablePublic && !m_library) if (m_nonPayablePublic && !m_library)

View File

@ -1856,7 +1856,7 @@ BOOST_AUTO_TEST_CASE(uncalled_blockhash)
contract C { contract C {
function f() public view returns (bytes32) function f() public view returns (bytes32)
{ {
return (block.blockhash)(block.number - 1); return (blockhash)(block.number - 1);
} }
} }
)"; )";

View File

@ -524,31 +524,16 @@ BOOST_AUTO_TEST_CASE(gas_left)
char const* sourceCode = R"( char const* sourceCode = R"(
contract test { contract test {
function f() returns (uint256 val) { function f() returns (uint256 val) {
return msg.gas; return gasleft();
} }
} }
)"; )";
bytes code = compileFirstExpression( bytes code = compileFirstExpression(
sourceCode, {}, {},
{make_shared<MagicVariableDeclaration>("msg", make_shared<MagicType>(MagicType::Kind::Message))}
);
bytes expectation({byte(Instruction::GAS)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
sourceCode = R"(
contract test {
function f() returns (uint256 val) {
return gasleft();
}
}
)";
code = compileFirstExpression(
sourceCode, {}, {}, sourceCode, {}, {},
{make_shared<MagicVariableDeclaration>("gasleft", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::GasLeft))} {make_shared<MagicVariableDeclaration>("gasleft", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::GasLeft))}
); );
expectation = bytes({byte(Instruction::GAS)}); bytes expectation = bytes({byte(Instruction::GAS)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
} }

View File

@ -43,13 +43,11 @@ BOOST_AUTO_TEST_CASE(environment_access)
vector<string> view{ vector<string> view{
"block.coinbase", "block.coinbase",
"block.timestamp", "block.timestamp",
"block.blockhash(7)",
"block.difficulty", "block.difficulty",
"block.number", "block.number",
"block.gaslimit", "block.gaslimit",
"blockhash(7)", "blockhash(7)",
"gasleft()", "gasleft()",
"msg.gas",
"msg.value", "msg.value",
"msg.sender", "msg.sender",
"tx.origin", "tx.origin",
@ -90,12 +88,11 @@ BOOST_AUTO_TEST_CASE(environment_access)
"Statement has no effect." "Statement has no effect."
})); }));
CHECK_WARNING_ALLOW_MULTI( CHECK_ERROR(
"contract C { function f() view public { block.blockhash; } }", "contract C { function f() view public { block.blockhash; } }",
(std::vector<std::string>{ TypeError,
"Function state mutability can be restricted to pure",
"\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
})); );
} }
BOOST_AUTO_TEST_CASE(assembly_staticcall) BOOST_AUTO_TEST_CASE(assembly_staticcall)

View File

@ -2,4 +2,4 @@ contract C {
function f() public view returns (uint256 val) { return msg.gas; } function f() public view returns (uint256 val) { return msg.gas; }
} }
// ---- // ----
// Warning: (73-80): "msg.gas" has been deprecated in favor of "gasleft()" // TypeError: (73-80): "msg.gas" has been deprecated in favor of "gasleft()"

View File

@ -1,6 +0,0 @@
pragma experimental "v0.5.0";
contract C {
function f() public returns (uint256 val) { return msg.gas; }
}
// ----
// TypeError: (98-105): "msg.gas" has been deprecated in favor of "gasleft()"

View File

@ -4,4 +4,4 @@ contract C {
} }
} }
// ---- // ----
// Warning: (77-92): "block.blockhash()" has been deprecated in favor of "blockhash()" // TypeError: (77-92): "block.blockhash()" has been deprecated in favor of "blockhash()"

View File

@ -1,6 +0,0 @@
pragma experimental "v0.5.0";
contract C {
function f() public returns (bytes32) { return block.blockhash(3); }
}
// ----
// TypeError: (94-109): "block.blockhash()" has been deprecated in favor of "blockhash()"

View File

@ -1,6 +1,6 @@
contract C { contract C {
function f() public pure { function f() public pure {
bytes32 h = keccak256(abi.encodePacked(keccak256, f, this.f.gas, block.blockhash)); bytes32 h = keccak256(abi.encodePacked(keccak256, f, this.f.gas, blockhash));
h; h;
} }
} }
@ -8,4 +8,4 @@ contract C {
// TypeError: (91-100): This type cannot be encoded. // TypeError: (91-100): This type cannot be encoded.
// TypeError: (102-103): This type cannot be encoded. // TypeError: (102-103): This type cannot be encoded.
// TypeError: (105-115): This type cannot be encoded. // TypeError: (105-115): This type cannot be encoded.
// TypeError: (117-132): This type cannot be encoded. // TypeError: (117-126): This type cannot be encoded.