aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-09-10 20:22:11 +0800
committerGitHub <noreply@github.com>2018-09-10 20:22:11 +0800
commitcd26fa8300c37c7c119004acbc2acc67679174a7 (patch)
treef99f90303203d3edcfde35378302ac4e95f25bcb
parent255eda2ea69cf1996b1d6e1289b47f394ae28712 (diff)
parent9f6a12eeb5b44d7e9de82864d89c98a2349fb929 (diff)
downloaddexon-solidity-cd26fa8300c37c7c119004acbc2acc67679174a7.tar.gz
dexon-solidity-cd26fa8300c37c7c119004acbc2acc67679174a7.tar.zst
dexon-solidity-cd26fa8300c37c7c119004acbc2acc67679174a7.zip
Merge pull request #4896 from ethereum/expCleanup
Exp cleanup
-rw-r--r--Changelog.md3
-rw-r--r--docs/bugs.json8
-rw-r--r--docs/bugs_by_version.json43
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp4
-rw-r--r--test/buglist_test_vectors.md34
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp40
6 files changed, 131 insertions, 1 deletions
diff --git a/Changelog.md b/Changelog.md
index 8f3bfff9..997c4069 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -91,6 +91,9 @@ Compiler Features:
* Code Generator: Allocate and free local variables according to their scope.
* Removed ``pragma experimental "v0.5.0";``.
+Critical Bugfixes:
+ * Code Generator: Properly perform cleanup for exponentiation and non-256 bit types.
+
Bugfixes:
* Build System: Support versions of CVC4 linked against CLN instead of GMP. In case of compilation issues due to the experimental SMT solver support, the solvers can be disabled when configuring the project with CMake using ``-DUSE_CVC4=OFF`` or ``-DUSE_Z3=OFF``.
* Tests: Fix chain parameters to make ipc tests work with newer versions of cpp-ethereum.
diff --git a/docs/bugs.json b/docs/bugs.json
index cf03adfe..980b3897 100644
--- a/docs/bugs.json
+++ b/docs/bugs.json
@@ -1,5 +1,13 @@
[
{
+ "name": "ExpExponentCleanup",
+ "summary": "Using the ** operator with an exponent of type shorter than 256 bits can result in unexpected values.",
+ "description": "Higher order bits in the exponent are not properly cleaned before the EXP opcode is applied if the type of the exponent expression is smaller than 256 bits and not smaller than the type of the base. In that case, the result might be larger than expected if the exponent is assumed to lie within the value range of the type. Literal numbers as exponents are unaffected as are exponents or bases of type uint256.",
+ "fixed": "0.4.25",
+ "severity": "medium/high",
+ "check": {"regex-source": "[^/]\\*\\* *[^/0-9 ]"}
+ },
+ {
"name": "EventStructWrongData",
"summary": "Using structs in events logged wrong data.",
"description": "If a struct is used in an event, the address of the struct is logged instead of the actual data.",
diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json
index ab200036..96cc3c5c 100644
--- a/docs/bugs_by_version.json
+++ b/docs/bugs_by_version.json
@@ -1,6 +1,7 @@
{
"0.1.0": {
"bugs": [
+ "ExpExponentCleanup",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@@ -18,6 +19,7 @@
},
"0.1.1": {
"bugs": [
+ "ExpExponentCleanup",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@@ -35,6 +37,7 @@
},
"0.1.2": {
"bugs": [
+ "ExpExponentCleanup",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@@ -52,6 +55,7 @@
},
"0.1.3": {
"bugs": [
+ "ExpExponentCleanup",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
"SkipEmptyStringLiteral",
@@ -69,6 +73,7 @@
},
"0.1.4": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
@@ -87,6 +92,7 @@
},
"0.1.5": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
@@ -105,6 +111,7 @@
},
"0.1.6": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
@@ -124,6 +131,7 @@
},
"0.1.7": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
@@ -143,6 +151,7 @@
},
"0.2.0": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
@@ -162,6 +171,7 @@
},
"0.2.1": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
@@ -181,6 +191,7 @@
},
"0.2.2": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"ECRecoverMalformedInput",
@@ -200,6 +211,7 @@
},
"0.3.0": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -219,6 +231,7 @@
},
"0.3.1": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -237,6 +250,7 @@
},
"0.3.2": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -255,6 +269,7 @@
},
"0.3.3": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -272,6 +287,7 @@
},
"0.3.4": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -289,6 +305,7 @@
},
"0.3.5": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -306,6 +323,7 @@
},
"0.3.6": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -321,6 +339,7 @@
},
"0.4.0": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -336,6 +355,7 @@
},
"0.4.1": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -351,6 +371,7 @@
},
"0.4.10": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -362,6 +383,7 @@
},
"0.4.11": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -372,6 +394,7 @@
},
"0.4.12": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -381,6 +404,7 @@
},
"0.4.13": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -390,6 +414,7 @@
},
"0.4.14": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue"
@@ -398,6 +423,7 @@
},
"0.4.15": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector"
],
@@ -405,6 +431,7 @@
},
"0.4.16": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector"
],
@@ -412,6 +439,7 @@
},
"0.4.17": {
"bugs": [
+ "ExpExponentCleanup",
"EventStructWrongData",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector"
@@ -420,6 +448,7 @@
},
"0.4.18": {
"bugs": [
+ "ExpExponentCleanup",
"EventStructWrongData",
"NestedArrayFunctionCallDecoder"
],
@@ -427,6 +456,7 @@
},
"0.4.19": {
"bugs": [
+ "ExpExponentCleanup",
"EventStructWrongData",
"NestedArrayFunctionCallDecoder"
],
@@ -434,6 +464,7 @@
},
"0.4.2": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -448,6 +479,7 @@
},
"0.4.20": {
"bugs": [
+ "ExpExponentCleanup",
"EventStructWrongData",
"NestedArrayFunctionCallDecoder"
],
@@ -455,6 +487,7 @@
},
"0.4.21": {
"bugs": [
+ "ExpExponentCleanup",
"EventStructWrongData",
"NestedArrayFunctionCallDecoder"
],
@@ -462,6 +495,7 @@
},
"0.4.22": {
"bugs": [
+ "ExpExponentCleanup",
"EventStructWrongData",
"OneOfTwoConstructorsSkipped"
],
@@ -469,18 +503,21 @@
},
"0.4.23": {
"bugs": [
+ "ExpExponentCleanup",
"EventStructWrongData"
],
"released": "2018-04-19"
},
"0.4.24": {
"bugs": [
+ "ExpExponentCleanup",
"EventStructWrongData"
],
"released": "2018-05-16"
},
"0.4.3": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -494,6 +531,7 @@
},
"0.4.4": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -506,6 +544,7 @@
},
"0.4.5": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -519,6 +558,7 @@
},
"0.4.6": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -531,6 +571,7 @@
},
"0.4.7": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -542,6 +583,7 @@
},
"0.4.8": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
@@ -553,6 +595,7 @@
},
"0.4.9": {
"bugs": [
+ "ExpExponentCleanup",
"NestedArrayFunctionCallDecoder",
"ZeroFunctionSelector",
"DelegateCallReturnValue",
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 4150bc11..45e58bd0 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -2138,7 +2138,9 @@ bool ExpressionCompiler::cleanupNeededForOp(Type::Category _type, Token::Value _
{
if (Token::isCompareOp(_op) || Token::isShiftOp(_op))
return true;
- else if (_type == Type::Category::Integer && (_op == Token::Div || _op == Token::Mod))
+ else if (_type == Type::Category::Integer && (_op == Token::Div || _op == Token::Mod || _op == Token::Exp))
+ // We need cleanup for EXP because 0**0 == 1, but 0**0x100 == 0
+ // It would suffice to clean the exponent, though.
return true;
else
return false;
diff --git a/test/buglist_test_vectors.md b/test/buglist_test_vectors.md
index f15cf151..e683f481 100644
--- a/test/buglist_test_vectors.md
+++ b/test/buglist_test_vectors.md
@@ -68,6 +68,40 @@ function f() m(uint[2][2]) { }
function f() returns (uint, uint) { uint[2][2] memory x; }
+# ExpExponentCleanup
+
+## buggy
+
+x ** y
+
+--
+
+x ** uint8(y)
+
+--
+
+x**y
+
+## fine
+
+x ** 2
+
+--
+
+x**2
+
+--
+
+x**200
+
+--
+
+/** bla **/
+
+--
+
+/**/
+
# EventStructWrongData
## buggy
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 85582ece..6be9d95b 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -11870,6 +11870,46 @@ BOOST_AUTO_TEST_CASE(shift_bytes_cleanup)
ABI_CHECK(callContractFunction("right(uint8)", 8 * 8), encodeArgs(string(8, 0) + "123456789012"));
}
+BOOST_AUTO_TEST_CASE(exp_cleanup)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() public pure returns (uint8 x) {
+ uint8 y = uint8(2) ** uint8(8);
+ return 0 ** y;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0x1)));
+}
+
+BOOST_AUTO_TEST_CASE(exp_cleanup_direct)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() public pure returns (uint8 x) {
+ return uint8(0) ** uint8(uint8(2) ** uint8(8));
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0x1)));
+}
+
+BOOST_AUTO_TEST_CASE(exp_cleanup_nonzero_base)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() public pure returns (uint8 x) {
+ return uint8(0x166) ** uint8(uint8(2) ** uint8(8));
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0x1)));
+}
+
BOOST_AUTO_TEST_CASE(cleanup_in_compound_assign)
{
char const* sourceCode = R"(