mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
commit
e19c4125af
@ -5,6 +5,7 @@ Features:
|
|||||||
* Assembly: Display auxiliary data in the assembly output.
|
* Assembly: Display auxiliary data in the assembly output.
|
||||||
* Assembly: Add ``CREATE2`` (EIP86), ``STATICCALL`` (EIP214), ``RETURNDATASIZE`` and ``RETURNDATACOPY`` (EIP211) instructions.
|
* Assembly: Add ``CREATE2`` (EIP86), ``STATICCALL`` (EIP214), ``RETURNDATASIZE`` and ``RETURNDATACOPY`` (EIP211) instructions.
|
||||||
* AST: export all attributes to JSON format.
|
* AST: export all attributes to JSON format.
|
||||||
|
* Type Checker: Warn about type inference from literal numbers.
|
||||||
* C API (``jsonCompiler``): Use the Standard JSON I/O internally.
|
* C API (``jsonCompiler``): Use the Standard JSON I/O internally.
|
||||||
* Inline Assembly: Present proper error message when not supplying enough arguments to a functional
|
* Inline Assembly: Present proper error message when not supplying enough arguments to a functional
|
||||||
instruction.
|
instruction.
|
||||||
|
@ -956,6 +956,38 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
|||||||
var.location(),
|
var.location(),
|
||||||
"Cannot declare variable with void (empty tuple) type."
|
"Cannot declare variable with void (empty tuple) type."
|
||||||
);
|
);
|
||||||
|
else if (valueComponentType->category() == Type::Category::RationalNumber)
|
||||||
|
{
|
||||||
|
string typeName = var.annotation().type->toString(true);
|
||||||
|
string extension;
|
||||||
|
if (auto type = dynamic_cast<IntegerType const*>(var.annotation().type.get()))
|
||||||
|
{
|
||||||
|
int numBits = type->numBits();
|
||||||
|
bool isSigned = type->isSigned();
|
||||||
|
string minValue;
|
||||||
|
string maxValue;
|
||||||
|
if (isSigned)
|
||||||
|
{
|
||||||
|
numBits--;
|
||||||
|
minValue = "-" + bigint(bigint(1) << numBits).str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
minValue = "0";
|
||||||
|
maxValue = bigint((bigint(1) << numBits) - 1).str();
|
||||||
|
extension = ", which can hold values between " + minValue + " and " + maxValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
solAssert(dynamic_cast<FixedPointType const*>(var.annotation().type.get()), "Unknown type.");
|
||||||
|
|
||||||
|
m_errorReporter.warning(
|
||||||
|
_statement.location(),
|
||||||
|
"The type of this variable was inferred as " +
|
||||||
|
typeName +
|
||||||
|
extension +
|
||||||
|
". This is probably not desired. Use an explicit type to silence this warning."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var.accept(*this);
|
var.accept(*this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -29,6 +29,15 @@ using namespace std;
|
|||||||
bool dev::solidity::searchErrorMessage(Error const& _err, std::string const& _substr)
|
bool dev::solidity::searchErrorMessage(Error const& _err, std::string const& _substr)
|
||||||
{
|
{
|
||||||
if (string const* errorMessage = boost::get_error_info<dev::errinfo_comment>(_err))
|
if (string const* errorMessage = boost::get_error_info<dev::errinfo_comment>(_err))
|
||||||
return errorMessage->find(_substr) != std::string::npos;
|
{
|
||||||
|
if (errorMessage->find(_substr) == std::string::npos)
|
||||||
|
{
|
||||||
|
cout << "Expected message \"" << _substr << "\" but found" << *errorMessage << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cout << "Expected error message but found none." << endl;
|
||||||
return _substr.empty();
|
return _substr.empty();
|
||||||
}
|
}
|
||||||
|
@ -103,17 +103,23 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false,
|
|||||||
if (success)
|
if (success)
|
||||||
if (!StaticAnalyzer(errorReporter).analyze(*sourceUnit))
|
if (!StaticAnalyzer(errorReporter).analyze(*sourceUnit))
|
||||||
success = false;
|
success = false;
|
||||||
if (errorReporter.errors().size() > 1 && !_allowMultipleErrors)
|
std::shared_ptr<Error const> error;
|
||||||
BOOST_FAIL("Multiple errors found");
|
|
||||||
for (auto const& currentError: errorReporter.errors())
|
for (auto const& currentError: errorReporter.errors())
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(_reportWarnings && currentError->type() == Error::Type::Warning) ||
|
(_reportWarnings && currentError->type() == Error::Type::Warning) ||
|
||||||
(!_reportWarnings && currentError->type() != Error::Type::Warning)
|
(!_reportWarnings && currentError->type() != Error::Type::Warning)
|
||||||
)
|
)
|
||||||
return make_pair(sourceUnit, currentError);
|
{
|
||||||
|
if (error && !_allowMultipleErrors)
|
||||||
|
BOOST_FAIL("Multiple errors found");
|
||||||
|
if (!error)
|
||||||
|
error = currentError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (error)
|
||||||
|
return make_pair(sourceUnit, error);
|
||||||
|
}
|
||||||
catch (InternalCompilerError const& _e)
|
catch (InternalCompilerError const& _e)
|
||||||
{
|
{
|
||||||
string message("Internal compiler error");
|
string message("Internal compiler error");
|
||||||
@ -1142,7 +1148,7 @@ BOOST_AUTO_TEST_CASE(modifier_overrides_function)
|
|||||||
)";
|
)";
|
||||||
// Error: Identifier already declared.
|
// Error: Identifier already declared.
|
||||||
// Error: Override changes modifier to function.
|
// Error: Override changes modifier to function.
|
||||||
CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "");
|
CHECK_ERROR_ALLOW_MULTI(text, DeclarationError, "Identifier already declared");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_overrides_modifier)
|
BOOST_AUTO_TEST_CASE(function_overrides_modifier)
|
||||||
@ -1781,6 +1787,46 @@ BOOST_AUTO_TEST_CASE(exp_warn_literal_base)
|
|||||||
CHECK_SUCCESS(sourceCode);
|
CHECK_SUCCESS(sourceCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(warn_var_from_zero)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
function f() returns (uint) {
|
||||||
|
var i = 1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_WARNING(sourceCode, "uint8, which can hold values between 0 and 255");
|
||||||
|
sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
var i = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
|
||||||
|
i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_WARNING(sourceCode, "uint256, which can hold values between 0 and 115792089237316195423570985008687907853269984665640564039457584007913129639935");
|
||||||
|
sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
var i = -2;
|
||||||
|
i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_WARNING(sourceCode, "int8, which can hold values between -128 and 127");
|
||||||
|
sourceCode = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
for (var i = 0; i < msg.data.length; i++) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_WARNING(sourceCode, "uint8, which can hold");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(enum_member_access)
|
BOOST_AUTO_TEST_CASE(enum_member_access)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
@ -3175,9 +3221,9 @@ BOOST_AUTO_TEST_CASE(tuples)
|
|||||||
contract C {
|
contract C {
|
||||||
function f() {
|
function f() {
|
||||||
uint a = (1);
|
uint a = (1);
|
||||||
var (b,) = (1,);
|
var (b,) = (uint8(1),);
|
||||||
var (c,d) = (1, 2 + a);
|
var (c,d) = (uint32(1), 2 + a);
|
||||||
var (e,) = (1, 2, b);
|
var (e,) = (uint64(1), 2, b);
|
||||||
a;b;c;d;e;
|
a;b;c;d;e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5518,7 +5564,7 @@ BOOST_AUTO_TEST_CASE(invalid_address_checksum)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract C {
|
contract C {
|
||||||
function f() {
|
function f() {
|
||||||
var x = 0xFA0bFc97E48458494Ccd857e1A85DC91F7F0046E;
|
address x = 0xFA0bFc97E48458494Ccd857e1A85DC91F7F0046E;
|
||||||
x;
|
x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5531,7 +5577,7 @@ BOOST_AUTO_TEST_CASE(invalid_address_no_checksum)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract C {
|
contract C {
|
||||||
function f() {
|
function f() {
|
||||||
var x = 0xfa0bfc97e48458494ccd857e1a85dc91f7f0046e;
|
address x = 0xfa0bfc97e48458494ccd857e1a85dc91f7f0046e;
|
||||||
x;
|
x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5544,7 +5590,7 @@ BOOST_AUTO_TEST_CASE(invalid_address_length)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract C {
|
contract C {
|
||||||
function f() {
|
function f() {
|
||||||
var x = 0xA0bFc97E48458494Ccd857e1A85DC91F7F0046E;
|
address x = 0xA0bFc97E48458494Ccd857e1A85DC91F7F0046E;
|
||||||
x;
|
x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5927,7 +5973,7 @@ BOOST_AUTO_TEST_CASE(warn_unused_local_assigned)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract C {
|
contract C {
|
||||||
function f() {
|
function f() {
|
||||||
var a = 1;
|
uint a = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
Loading…
Reference in New Issue
Block a user