Merge pull request #6236 from ethereum/better-errors

isImplicitlyConvertibleTo(): Add better error messages
This commit is contained in:
chriseth 2019-03-11 14:58:45 +01:00 committed by GitHub
commit 0f98f2a15e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 29 additions and 6 deletions

View File

@ -5,6 +5,7 @@ Language Features:
Compiler Features:
* Type Checker: Give better error messages for some literal conversions
* Peephole Optimizer: Remove double ``iszero`` before ``jumpi``.
* SMTChecker: Support enums without typecast.
* SMTChecker: Support one-dimensional arrays.

View File

@ -98,7 +98,7 @@ public:
auto filterEmpty = boost::adaptors::filtered([](std::string const& _s) { return !_s.empty(); });
std::string errorStr = dev::joinHumanReadable(descs | filterEmpty);
std::string errorStr = dev::joinHumanReadable(descs | filterEmpty, " ");
error(Error::Type::TypeError, _location, errorStr);
}

View File

@ -126,9 +126,15 @@ bool fitsPrecisionBase2(bigint const& _mantissa, uint32_t _expBase2)
}
/// Checks whether _value fits into IntegerType _type.
bool fitsIntegerType(bigint const& _value, IntegerType const& _type)
BoolResult fitsIntegerType(bigint const& _value, IntegerType const& _type)
{
return (_type.minValue() <= _value) && (_value <= _type.maxValue());
if (_value < 0 && !_type.isSigned())
return BoolResult{std::string("Cannot implicitly convert signed literal to unsigned type.")};
if (_type.minValue() > _value || _value > _type.maxValue())
return BoolResult{"Literal is too large to fit in " + _type.toString(false)};
return true;
}
/// Checks whether _value fits into _bits bits when having 1 bit as the sign bit
@ -722,7 +728,9 @@ BoolResult FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) con
if (_convertTo.category() == category())
{
FixedPointType const& convertTo = dynamic_cast<FixedPointType const&>(_convertTo);
if (convertTo.numBits() < m_totalBits || convertTo.fractionalDigits() < m_fractionalDigits)
if (convertTo.fractionalDigits() < m_fractionalDigits)
return BoolResult{std::string("Too many fractional digits.")};
if (convertTo.numBits() < m_totalBits)
return false;
else
return convertTo.maxIntegerValue() >= maxIntegerValue() && convertTo.minIntegerValue() <= minIntegerValue();

View File

@ -6,4 +6,4 @@ contract Derived2 is Base {
constructor() Base(2) public { }
}
// ----
// TypeError: (74-77): Invalid type for argument in constructor call. Invalid implicit conversion from int_const 300 to uint8 requested.
// TypeError: (74-77): Invalid type for argument in constructor call. Invalid implicit conversion from int_const 300 to uint8 requested. Literal is too large to fit in uint8

View File

@ -5,4 +5,4 @@ contract test {
}
}
// ----
// TypeError: (75-92): Type ufixed128x18 is not implicitly convertible to expected type ufixed248x8.
// TypeError: (75-92): Type ufixed128x18 is not implicitly convertible to expected type ufixed248x8. Too many fractional digits.

View File

@ -0,0 +1,7 @@
contract c {
function f() public pure {
uint a = -1;
}
}
// ----
// TypeError: (52-63): Type int_const -1 is not implicitly convertible to expected type uint256. Cannot implicitly convert signed literal to unsigned type.

View File

@ -0,0 +1,7 @@
contract c {
function f() public pure {
uint8 a = 256;
}
}
// ----
// TypeError: (52-65): Type int_const 256 is not implicitly convertible to expected type uint8. Literal is too large to fit in uint8