diff options
-rw-r--r-- | .travis.yml | 6 | ||||
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | Changelog.md | 2 | ||||
-rw-r--r-- | circle.yml | 2 | ||||
-rw-r--r-- | cmake/EthCompilerSettings.cmake | 4 | ||||
-rw-r--r-- | libevmasm/RuleList.h | 11 | ||||
-rw-r--r-- | libsolidity/analysis/SyntaxChecker.cpp | 14 | ||||
-rw-r--r-- | libsolidity/analysis/SyntaxChecker.h | 2 | ||||
-rw-r--r-- | lllc/CMakeLists.txt | 16 | ||||
-rwxr-xr-x | scripts/release_ppa.sh | 3 | ||||
-rwxr-xr-x | test/externalTests.sh | 45 | ||||
-rw-r--r-- | test/libjulia/Simplifier.cpp | 12 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 32 | ||||
-rw-r--r-- | test/libsolidity/ViewPureChecker.cpp | 14 |
14 files changed, 126 insertions, 39 deletions
diff --git a/.travis.yml b/.travis.yml index 708d3620..ebe91939 100644 --- a/.travis.yml +++ b/.travis.yml @@ -97,12 +97,12 @@ matrix: sudo: required compiler: gcc node_js: - - "6" + - "7" services: - docker before_install: - - nvm install 6 - - nvm use 6 + - nvm install 7 + - nvm use 7 - docker pull trzeci/emscripten:sdk-tag-1.35.4-64bit env: - SOLC_EMSCRIPTEN=On diff --git a/CMakeLists.txt b/CMakeLists.txt index 8993f372..a0b52621 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,8 @@ set(PROJECT_VERSION "0.4.20") project(solidity VERSION ${PROJECT_VERSION}) option(SOLC_LINK_STATIC "Link solc executable statically on supported platforms" OFF) +option(LLLC_LINK_STATIC "Link lllc executable statically on supported platforms" OFF) +option(INSTALL_LLLC "Include lllc executable in installation" OFF) # Setup cccache. include(EthCcache) diff --git a/Changelog.md b/Changelog.md index 66273ca1..ab1b35cd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,8 +7,10 @@ Features: * Limit the number of warnings raised for creating abstract contracts. * Inline Assembly: Issue warning for using jump labels (already existed for jump instructions). * Inline Assembly: Support some restricted tokens (return, byte, address) as identifiers in Julia mode. + * Optimiser: Replace `x % 2**i` by `x & (2**i-1)`. * SMT Checker: If-else branch conditions are taken into account in the SMT encoding of the program variables. + * Syntax Checker: Deprecate the ``var`` keyword (and mark it an error as experimental 0.5.0 feature). * Type Checker: Issue warning for using ``public`` visibility for interface functions. Bugfixes: @@ -76,7 +76,7 @@ jobs: export NVM_DIR="/usr/local/nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm nvm --version - nvm install 6 + nvm install 7 node --version npm --version - run: diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index ddb6c426..7199f537 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -120,7 +120,7 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA endif() if (EMSCRIPTEN) - # Do emit a separate memory initialiser file + # Do not emit a separate memory initialiser file set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --memory-init-file 0") # Leave only exported symbols as public and agressively remove others set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections -Wl,--gc-sections -fvisibility=hidden") @@ -138,6 +138,8 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ALLOW_MEMORY_GROWTH=1") # Disable eval() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NO_DYNAMIC_EXECUTION=1") + # Disable greedy exception catcher + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NODEJS_CATCH_EXIT=0") add_definitions(-DETH_EMSCRIPTEN=1) endif() endif() diff --git a/libevmasm/RuleList.h b/libevmasm/RuleList.h index 2312d673..da522cec 100644 --- a/libevmasm/RuleList.h +++ b/libevmasm/RuleList.h @@ -153,6 +153,17 @@ std::vector<SimplificationRule<Pattern>> simplificationRuleList( {{Instruction::OR, {{Instruction::NOT, {X}}, X}}, [=]{ return ~u256(0); }, true}, }; + // Replace MOD X, <power-of-two> with AND X, <power-of-two> - 1 + for (size_t i = 0; i < 256; ++i) + { + u256 value = u256(1) << i; + rules.push_back({ + {Instruction::MOD, {X, value}}, + [=]() -> Pattern { return {Instruction::AND, {X, value - 1}}; }, + false + }); + } + // Double negation of opcodes with boolean result for (auto const& op: std::vector<Instruction>{ Instruction::EQ, diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index b6cc04da..5a3745b0 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -224,3 +224,17 @@ bool SyntaxChecker::visit(FunctionTypeName const& _node) return true; } + +bool SyntaxChecker::visit(VariableDeclaration const& _declaration) +{ + bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050); + + if (!_declaration.typeName()) + { + if (v050) + m_errorReporter.syntaxError(_declaration.location(), "Use of the \"var\" keyword is deprecated."); + else + m_errorReporter.warning(_declaration.location(), "Use of the \"var\" keyword is deprecated."); + } + return true; +} diff --git a/libsolidity/analysis/SyntaxChecker.h b/libsolidity/analysis/SyntaxChecker.h index d5d72f14..871bf0a9 100644 --- a/libsolidity/analysis/SyntaxChecker.h +++ b/libsolidity/analysis/SyntaxChecker.h @@ -69,6 +69,8 @@ private: virtual bool visit(FunctionDefinition const& _function) override; virtual bool visit(FunctionTypeName const& _node) override; + virtual bool visit(VariableDeclaration const& _declaration) override; + ErrorReporter& m_errorReporter; /// Flag that indicates whether a function modifier actually contains '_'. diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 7bebd0b1..5c480093 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -1,3 +1,19 @@ add_executable(lllc main.cpp) target_link_libraries(lllc PRIVATE lll) +if (INSTALL_LLLC) + include(GNUInstallDirs) + install(TARGETS lllc DESTINATION ${CMAKE_INSTALL_BINDIR}) + + if(LLLC_LINK_STATIC AND UNIX AND NOT APPLE) + # Produce lllc as statically linked binary (includes C/C++ standard libraries) + # This is not supported on macOS, see + # https://developer.apple.com/library/content/qa/qa1118/_index.html. + set_target_properties( + lllc PROPERTIES + LINK_FLAGS -static + LINK_SEARCH_START_STATIC ON + LINK_SEARCH_END_STATIC ON + ) + endif() +endif() diff --git a/scripts/release_ppa.sh b/scripts/release_ppa.sh index 2dd43302..b314d00d 100755 --- a/scripts/release_ppa.sh +++ b/scripts/release_ppa.sh @@ -166,6 +166,9 @@ override_dh_auto_test: override_dh_shlibdeps: dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info + +override_dh_auto_configure: + dh_auto_configure -- -DINSTALL_LLLC=Off EOF cat <<EOF > debian/copyright Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ diff --git a/test/externalTests.sh b/test/externalTests.sh index f707d6db..2a5ff7ef 100755 --- a/test/externalTests.sh +++ b/test/externalTests.sh @@ -36,21 +36,32 @@ fi SOLJSON="$1" -DIR=$(mktemp -d) -( - echo "Running Zeppelin tests..." - git clone --depth 1 https://github.com/OpenZeppelin/zeppelin-solidity.git "$DIR" - cd "$DIR" +function test_truffle +{ + name="$1" + repo="$2" + echo "Running $name tests..." + DIR=$(mktemp -d) + ( + git clone --depth 1 "$repo" "$DIR" + cd "$DIR" + npm install + find . -name soljson.js -exec cp "$SOLJSON" {} \; + if [ "$name" == "Zeppelin" ]; then + # Fix some things that look like bugs (only seemed to fail on Node 6 and not Node 8) + # FIXME: report upstream or to web3.js? + sed -i -e 's/let token = await ERC827TokenMock.new();//;' test/token/ERC827/ERC827Token.js + sed -i -e 's/CappedCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0)/CappedCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, this.token.address)/' test/crowdsale/CappedCrowdsale.test.js + sed -i -e 's/RefundableCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, { from: owner })/RefundableCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, this.token.address, { from: owner })/' test/crowdsale/RefundableCrowdsale.test.js + fi + if [ "$name" == "Gnosis" ]; then + # Replace fixed-version pragmas in Gnosis (part of Consensys best practice) + find contracts test -name '*.sol' -type f -print0 | xargs -0 sed -i -e 's/pragma solidity 0/pragma solidity ^0/' + fi + npm run test + ) + rm -rf "$DIR" +} - # Fix some things that look like bugs (only seemed to fail on Node 6 and not Node 8) - # FIXME: report upstream or to web3.js? - sed -i -e 's/let token = await ERC827TokenMock.new();//;' test/token/ERC827/ERC827Token.js - sed -i -e 's/CappedCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0)/CappedCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, this.token.address)/' test/crowdsale/CappedCrowdsale.test.js - sed -i -e 's/RefundableCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, { from: owner })/RefundableCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, this.token.address, { from: owner })/' test/crowdsale/RefundableCrowdsale.test.js - - npm install - find . -name soljson.js -exec cp "$SOLJSON" {} \; - - npm run test -) -rm -rf "$DIR" +test_truffle Gnosis https://github.com/gnosis/gnosis-contracts.git +test_truffle Zeppelin https://github.com/OpenZeppelin/zeppelin-solidity.git diff --git a/test/libjulia/Simplifier.cpp b/test/libjulia/Simplifier.cpp index b48d45c8..4d4e8d53 100644 --- a/test/libjulia/Simplifier.cpp +++ b/test/libjulia/Simplifier.cpp @@ -127,4 +127,16 @@ BOOST_AUTO_TEST_CASE(inside_for) ); } +BOOST_AUTO_TEST_CASE(mod_and) +{ + CHECK( + "{ mstore(0, mod(calldataload(0), exp(2, 8))) }", + "{ mstore(0, and(calldataload(0), 255)) }" + ); + CHECK( + "{ mstore(0, mod(calldataload(0), exp(2, 255))) }", + "{ mstore(0, and(calldataload(0), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) }" + ); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 4eade7f1..e757c755 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -1844,7 +1844,10 @@ BOOST_AUTO_TEST_CASE(warn_var_from_zero) } } )"; - CHECK_WARNING(sourceCode, "uint8, which can hold values between 0 and 255"); + CHECK_WARNING_ALLOW_MULTI(sourceCode, (std::vector<std::string>{ + "uint8, which can hold values between 0 and 255", + "Use of the \"var\" keyword is deprecated." + })); sourceCode = R"( contract test { function f() pure public { @@ -1853,7 +1856,10 @@ BOOST_AUTO_TEST_CASE(warn_var_from_zero) } } )"; - CHECK_WARNING(sourceCode, "uint256, which can hold values between 0 and 115792089237316195423570985008687907853269984665640564039457584007913129639935"); + CHECK_WARNING_ALLOW_MULTI(sourceCode, (std::vector<std::string>{ + "uint256, which can hold values between 0 and 115792089237316195423570985008687907853269984665640564039457584007913129639935", + "Use of the \"var\" keyword is deprecated." + })); sourceCode = R"( contract test { function f() pure public { @@ -1862,7 +1868,10 @@ BOOST_AUTO_TEST_CASE(warn_var_from_zero) } } )"; - CHECK_WARNING(sourceCode, "int8, which can hold values between -128 and 127"); + CHECK_WARNING_ALLOW_MULTI(sourceCode, (std::vector<std::string>{ + "int8, which can hold values between -128 and 127", + "Use of the \"var\" keyword is deprecated." + })); sourceCode = R"( contract test { function f() pure public { @@ -1870,7 +1879,10 @@ BOOST_AUTO_TEST_CASE(warn_var_from_zero) } } )"; - CHECK_WARNING(sourceCode, "uint8, which can hold"); + CHECK_WARNING_ALLOW_MULTI(sourceCode, (std::vector<std::string>{ + "uint8, which can hold", + "Use of the \"var\" keyword is deprecated." + })); } BOOST_AUTO_TEST_CASE(enum_member_access) @@ -4887,8 +4899,7 @@ BOOST_AUTO_TEST_CASE(warn_about_callcode) char const* text = R"( contract test { function f() pure public { - var x = address(0x12).callcode; - x; + address(0x12).callcode; } } )"; @@ -4897,8 +4908,7 @@ BOOST_AUTO_TEST_CASE(warn_about_callcode) pragma experimental "v0.5.0"; contract test { function f() pure public { - var x = address(0x12).callcode; - x; + address(0x12).callcode; } } )"; @@ -6918,7 +6928,7 @@ BOOST_AUTO_TEST_CASE(function_types_sig) } } )"; - CHECK_SUCCESS_NO_WARNINGS(text); + CHECK_WARNING(text, "Use of the \"var\" keyword is deprecated."); text = R"( contract C { function h() pure external { @@ -6941,7 +6951,7 @@ BOOST_AUTO_TEST_CASE(function_types_sig) } } )"; - CHECK_SUCCESS_NO_WARNINGS(text); + CHECK_WARNING(text, "Use of the \"var\" keyword is deprecated."); } BOOST_AUTO_TEST_CASE(using_this_in_constructor) @@ -7349,7 +7359,7 @@ BOOST_AUTO_TEST_CASE(warn_about_sha3) char const* text = R"( contract test { function f() pure public { - var x = sha3(uint8(1)); + bytes32 x = sha3(uint8(1)); x; } } diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp index debeb4dc..e91e713c 100644 --- a/test/libsolidity/ViewPureChecker.cpp +++ b/test/libsolidity/ViewPureChecker.cpp @@ -136,10 +136,12 @@ BOOST_AUTO_TEST_CASE(environment_access) } for (string const& x: pure) { - CHECK_WARNING( + CHECK_WARNING_ALLOW_MULTI( "contract C { function f() view public { var x = " + x + "; x; } }", - "restricted to pure" - ); + (std::vector<std::string>{ + "Function state mutability can be restricted to pure", + "Use of the \"var\" keyword is deprecated." + })); } } @@ -282,9 +284,9 @@ BOOST_AUTO_TEST_CASE(builtin_functions) require(this.call()); } function g() pure public { - var x = keccak256("abc"); - var y = sha256("abc"); - var z = ecrecover(1, 2, 3, 4); + bytes32 x = keccak256("abc"); + bytes32 y = sha256("abc"); + address z = ecrecover(1, 2, 3, 4); require(true); assert(true); x; y; z; |