diff --git a/Changelog.md b/Changelog.md index a24ac211c..8fa54c818 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ Features: Bugfixes: + * Type checker: forbid signed exponential that led to an incorrect use of EXP opcode. ### 0.4.3 (2016-10-25) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 7cfed3c88..7fe97fa76 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -349,11 +349,14 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe return commonType; if (Token::isBooleanOp(_operator)) return TypePointer(); - // Nothing else can be done with addresses if (auto intType = dynamic_pointer_cast(commonType)) { + // Nothing else can be done with addresses if (intType->isAddress()) return TypePointer(); + // Signed EXP is not allowed + if (Token::Exp == _operator && intType->isSigned()) + return TypePointer(); } else if (auto fixType = dynamic_pointer_cast(commonType)) if (Token::Exp == _operator) diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 9fe91cca5..640cc1080 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -2098,6 +2098,22 @@ BOOST_AUTO_TEST_CASE(integer_boolean_operators) BOOST_CHECK(expectError(sourceCode3) == Error::Type::TypeError); } +BOOST_AUTO_TEST_CASE(exp_signed_variable) +{ + char const* sourceCode1 = R"( + contract test { function() { uint x = 3; int y = -4; x ** y; } } + )"; + BOOST_CHECK(expectError(sourceCode1) == Error::Type::TypeError); + char const* sourceCode2 = R"( + contract test { function() { uint x = 3; int y = -4; y ** x; } } + )"; + BOOST_CHECK(expectError(sourceCode2) == Error::Type::TypeError); + char const* sourceCode3 = R"( + contract test { function() { int x = -3; int y = -4; x ** y; } } + )"; + BOOST_CHECK(expectError(sourceCode3) == Error::Type::TypeError); +} + BOOST_AUTO_TEST_CASE(reference_compare_operators) { char const* sourceCode1 = R"(