Merge pull request #2449 from federicobond/warn-bytesxx-decimal

Warn if decimal literals are used in a bytesXX context
This commit is contained in:
chriseth 2017-06-26 09:13:41 +02:00 committed by GitHub
commit f879489291
2 changed files with 50 additions and 3 deletions

View File

@ -22,6 +22,7 @@
#include <libsolidity/analysis/TypeChecker.h>
#include <memory>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <libsolidity/ast/AST.h>
#include <libsolidity/inlineasm/AsmAnalysis.h>
@ -1800,7 +1801,23 @@ void TypeChecker::expectType(Expression const& _expression, Type const& _expecte
_expectedType.toString() +
"."
);
}
}
if (
type(_expression)->category() == Type::Category::RationalNumber &&
_expectedType.category() == Type::Category::FixedBytes
)
{
auto literal = dynamic_cast<Literal const*>(&_expression);
if (literal && !boost::starts_with(literal->value(), "0x"))
m_errorReporter.warning(
_expression.location(),
"Decimal literal assigned to bytesXX variable will be left-aligned. "
"Use an explicit conversion to silence this warning."
);
}
}
void TypeChecker::requireLValue(Expression const& _expression)

View File

@ -2183,6 +2183,36 @@ BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1)
ETH_TEST_REQUIRE_NO_THROW(parseAndAnalyse(text), "Type resolving failed");
}
BOOST_AUTO_TEST_CASE(warns_assigning_decimal_to_bytesxx)
{
char const* text = R"(
contract Foo {
bytes32 a = 7;
}
)";
CHECK_WARNING(text, "Decimal literal assigned to bytesXX variable will be left-aligned.");
}
BOOST_AUTO_TEST_CASE(does_not_warn_assigning_hex_number_to_bytesxx)
{
char const* text = R"(
contract Foo {
bytes32 a = 0x1234;
}
)";
CHECK_SUCCESS_NO_WARNINGS(text);
}
BOOST_AUTO_TEST_CASE(explicit_conversion_from_decimal_to_bytesxx)
{
char const* text = R"(
contract Foo {
bytes32 a = bytes32(7);
}
)";
CHECK_SUCCESS_NO_WARNINGS(text);
}
BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable)
{
char const* text = R"(
@ -3718,12 +3748,12 @@ BOOST_AUTO_TEST_CASE(conditional_with_all_types)
byte[2] memory a;
byte[2] memory b;
var k = true ? a : b;
k[0] = 0; //Avoid unused var warning
k[0] = byte(0); //Avoid unused var warning
bytes memory e;
bytes memory f;
var l = true ? e : f;
l[0] = 0; // Avoid unused var warning
l[0] = byte(0); // Avoid unused var warning
// fixed bytes
bytes2 c;