Merge pull request #10710 from ethereum/implicit-conversion-bug

Disallow certain implicit conversions between integer types.
This commit is contained in:
chriseth 2021-01-12 15:42:12 +01:00 committed by GitHub
commit 99add1e4e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 8 deletions

View File

@ -17,6 +17,7 @@ Bugfixes:
* SMTChecker: Fix false negatives when analyzing external function calls. * SMTChecker: Fix false negatives when analyzing external function calls.
* SMTChecker: Fix missing type constraints for block variables. * SMTChecker: Fix missing type constraints for block variables.
* SMTChecker: Fix internal error on ``block.chainid``. * SMTChecker: Fix internal error on ``block.chainid``.
* Type System: Disallow implicit conversion from ``uintN`` to ``intM`` when ``M > N``, and by extension, explicit conversion between the same types is also disallowed.
### 0.8.0 (2020-12-16) ### 0.8.0 (2020-12-16)

View File

@ -510,12 +510,13 @@ BoolResult IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
if (_convertTo.category() == category()) if (_convertTo.category() == category())
{ {
IntegerType const& convertTo = dynamic_cast<IntegerType const&>(_convertTo); IntegerType const& convertTo = dynamic_cast<IntegerType const&>(_convertTo);
if (convertTo.m_bits < m_bits) // disallowing unsigned to signed conversion of different bits
if (isSigned() != convertTo.isSigned())
return false;
else if (convertTo.m_bits < m_bits)
return false; return false;
else if (isSigned())
return convertTo.isSigned();
else else
return !convertTo.isSigned() || convertTo.m_bits > m_bits; return true;
} }
else if (_convertTo.category() == Category::FixedPoint) else if (_convertTo.category() == Category::FixedPoint)
{ {

View File

@ -61,7 +61,7 @@ contract ScalarEvent is Event {
convertedWinningOutcome = OUTCOME_RANGE; convertedWinningOutcome = OUTCOME_RANGE;
// Map outcome to outcome range // Map outcome to outcome range
else else
convertedWinningOutcome = uint24(uint(OUTCOME_RANGE * (outcome - lowerBound) / (upperBound - lowerBound))); convertedWinningOutcome = uint24(uint(int(uint(OUTCOME_RANGE)) * (outcome - lowerBound) / (upperBound - lowerBound)));
uint factorShort = OUTCOME_RANGE - convertedWinningOutcome; uint factorShort = OUTCOME_RANGE - convertedWinningOutcome;
uint factorLong = OUTCOME_RANGE - factorShort; uint factorLong = OUTCOME_RANGE - factorShort;
uint shortOutcomeTokenCount = outcomeTokens[SHORT].balanceOf(msg.sender); uint shortOutcomeTokenCount = outcomeTokens[SHORT].balanceOf(msg.sender);

View File

@ -1,6 +1,6 @@
contract test { contract test {
function f() public { uint32(2) == int64(2); } function f() public { uint32(2) == uint64(2); }
} }
// ---- // ----
// Warning 6133: (42-63): Statement has no effect. // Warning 6133: (42-64): Statement has no effect.
// Warning 2018: (20-66): Function state mutability can be restricted to pure // Warning 2018: (20-67): Function state mutability can be restricted to pure

View File

@ -0,0 +1,13 @@
contract C
{
function f() public pure {
uint16 a = 1;
int32 b = a;
uint256 c = 10;
int8 d = c;
}
}
// ----
// TypeError 9574: (74-85): Type uint16 is not implicitly convertible to expected type int32.
// TypeError 9574: (120-130): Type uint256 is not implicitly convertible to expected type int8.

View File

@ -37,6 +37,10 @@ contract C
B n = B(address(uint160(uint(int(100))))); B n = B(address(uint160(uint(int(100)))));
n; n;
uint8 o = 1;
int16 p = int16(o);
} }
} }
// ---- // ----
// TypeError 9640: (801-809): Explicit type conversion not allowed from "uint8" to "int16".