aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2016-11-01 02:21:04 +0800
committerGitHub <noreply@github.com>2016-11-01 02:21:04 +0800
commit4633f3def897db0f91237f98cf46e5d84fb05e61 (patch)
tree2dcc45c6ff2c95dc8871469aaa8e71d39807c8d7
parent2353da71c77dd235b35d16e7e024fa62408df610 (diff)
parent979d18f19c711093cdc7f4112a76bf2135c97119 (diff)
downloaddexon-solidity-4633f3def897db0f91237f98cf46e5d84fb05e61.tar
dexon-solidity-4633f3def897db0f91237f98cf46e5d84fb05e61.tar.gz
dexon-solidity-4633f3def897db0f91237f98cf46e5d84fb05e61.tar.bz2
dexon-solidity-4633f3def897db0f91237f98cf46e5d84fb05e61.tar.lz
dexon-solidity-4633f3def897db0f91237f98cf46e5d84fb05e61.tar.xz
dexon-solidity-4633f3def897db0f91237f98cf46e5d84fb05e61.tar.zst
dexon-solidity-4633f3def897db0f91237f98cf46e5d84fb05e61.zip
Merge pull request #1308 from ethereum/develop
Merge for version 0.4.4
-rw-r--r--CMakeLists.txt2
-rw-r--r--Changelog.md6
-rw-r--r--cmake/EthCompilerSettings.cmake12
-rw-r--r--cmake/EthDependencies.cmake2
-rw-r--r--docs/conf.py4
-rw-r--r--docs/index.rst2
-rw-r--r--docs/installing-solidity.rst2
-rw-r--r--liblll/CodeFragment.cpp49
-rw-r--r--libsolidity/ast/Types.cpp5
-rw-r--r--libsolidity/codegen/LValue.cpp8
-rw-r--r--lllc/main.cpp7
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp20
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp16
13 files changed, 96 insertions, 39 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 62440265..7e38083b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,7 @@ include(EthPolicy)
eth_policy()
# project name and version should be set after cmake_policy CMP0048
-set(PROJECT_VERSION "0.4.3")
+set(PROJECT_VERSION "0.4.4")
project(solidity VERSION ${PROJECT_VERSION})
# Let's find our dependencies
diff --git a/Changelog.md b/Changelog.md
index b399c71a..c83bcffa 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,9 @@
+### 0.4.4 (2016-10-31)
+
+Bugfixes:
+ * Type checker: forbid signed exponential that led to an incorrect use of EXP opcode.
+ * Code generator: properly clean higher order bytes before storing in storage.
+
### 0.4.3 (2016-10-25)
Features:
diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake
index 066be4c1..af6ae928 100644
--- a/cmake/EthCompilerSettings.cmake
+++ b/cmake/EthCompilerSettings.cmake
@@ -180,12 +180,12 @@ elseif (DEFINED MSVC)
# Always use Release variant of C++ runtime.
# We don't want to provide Debug variants of all dependencies. Some default
# flags set by CMake must be tweaked.
- string(REPLACE "/MDd" "/MD" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
- string(REPLACE "/D_DEBUG" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
- string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
- string(REPLACE "/MDd" "/MD" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
- string(REPLACE "/D_DEBUG" "" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
- string(REPLACE "/RTC1" "" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
+ string(REPLACE "/MDd" "/MD" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+ string(REPLACE "/D_DEBUG" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+ string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+ string(REPLACE "/MDd" "/MD" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+ string(REPLACE "/D_DEBUG" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+ string(REPLACE "/RTC1" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS OFF)
# disable empty object file warning
diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake
index 72585d11..a5e9b0c5 100644
--- a/cmake/EthDependencies.cmake
+++ b/cmake/EthDependencies.cmake
@@ -119,7 +119,7 @@ function(eth_use TARGET REQUIRED)
endif()
foreach(MODULE ${ARGN})
- string(REPLACE "::" ";" MODULE_PARTS ${MODULE})
+ string(REPLACE "::" ";" MODULE_PARTS "${MODULE}")
list(GET MODULE_PARTS 0 MODULE_MAIN)
list(LENGTH MODULE_PARTS MODULE_LENGTH)
if (MODULE_LENGTH GREATER 1)
diff --git a/docs/conf.py b/docs/conf.py
index 4d22c9bd..ebc77124 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -56,9 +56,9 @@ copyright = '2016, Ethereum'
# built documents.
#
# The short X.Y version.
-version = '0.4.3'
+version = '0.4.4'
# The full version, including alpha/beta/rc tags.
-release = '0.4.3-develop'
+release = '0.4.4-develop'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/index.rst b/docs/index.rst
index 3b47ce78..9bee1515 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -5,7 +5,7 @@ Solidity is a contract-oriented, high-level language whose syntax is similar to
and it is designed to target the Ethereum Virtual Machine.
Solidity is statically typed, supports inheritance, libraries and complex
-user-defines types among other features.
+user-defined types among other features.
As you will see, it is possible to create contracts for voting,
crowdfunding, blind auctions, multi-signature wallets and more.
diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst
index 44ee34f4..ec40e822 100644
--- a/docs/installing-solidity.rst
+++ b/docs/installing-solidity.rst
@@ -12,7 +12,7 @@ Versioning
Solidity versions follow `semantic versioning <https://semver.org>`_ and in addition to
releases, **nightly development builds** are also made available. The nightly builds
are not guaranteed to be working and despite best efforts they might contain undocumented
-and/or broken changes. We recommend to use the latest release. Package installers below
+and/or broken changes. We recommend using the latest release. Package installers below
will use the latest release.
Browser-Solidity
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
index 9dcac845..0f8f2606 100644
--- a/liblll/CodeFragment.cpp
+++ b/liblll/CodeFragment.cpp
@@ -330,9 +330,32 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
if (nonStandard)
return;
- std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD }, { "&", Instruction::AND }, { "|", Instruction::OR }, { "^", Instruction::XOR } };
- std::map<std::string, pair<Instruction, bool>> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "S<", { Instruction::SLT, false } }, { "S<=", { Instruction::SGT, true } }, { "S>", { Instruction::SGT, false } }, { "S>=", { Instruction::SLT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } };
- std::map<std::string, Instruction> const c_unary = { { "!", Instruction::ISZERO } };
+ std::map<std::string, Instruction> const c_arith = {
+ { "+", Instruction::ADD },
+ { "-", Instruction::SUB },
+ { "*", Instruction::MUL },
+ { "/", Instruction::DIV },
+ { "%", Instruction::MOD },
+ { "&", Instruction::AND },
+ { "|", Instruction::OR },
+ { "^", Instruction::XOR }
+ };
+ std::map<std::string, pair<Instruction, bool>> const c_binary = {
+ { "<", { Instruction::LT, false } },
+ { "<=", { Instruction::GT, true } },
+ { ">", { Instruction::GT, false } },
+ { ">=", { Instruction::LT, true } },
+ { "S<", { Instruction::SLT, false } },
+ { "S<=", { Instruction::SGT, true } },
+ { "S>", { Instruction::SGT, false } },
+ { "S>=", { Instruction::SLT, true } },
+ { "=", { Instruction::EQ, false } },
+ { "!=", { Instruction::EQ, true } }
+ };
+ std::map<std::string, Instruction> const c_unary = {
+ { "!", Instruction::ISZERO },
+ { "~", Instruction::NOT }
+ };
vector<CodeFragment> code;
CompilerState ns = _s;
@@ -449,14 +472,15 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
m_asm << end.tag();
m_asm.donePaths();
}
- else if (us == "WHILE")
+ else if (us == "WHILE" || us == "UNTIL")
{
requireSize(2);
requireDeposit(0, 1);
auto begin = m_asm.append();
m_asm.append(code[0].m_asm);
- m_asm.append(Instruction::ISZERO);
+ if (us == "WHILE")
+ m_asm.append(Instruction::ISZERO);
auto end = m_asm.appendJumpI();
m_asm.append(code[1].m_asm, 0);
m_asm.appendJump(begin);
@@ -541,17 +565,6 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
// At end now.
m_asm.append(end);
}
- else if (us == "~")
- {
- requireSize(1);
- requireDeposit(0, 1);
-
- m_asm.append(code[0].m_asm, 1);
- m_asm.append((u256)1);
- m_asm.append((u256)0);
- m_asm.append(Instruction::SUB);
- m_asm.append(Instruction::SUB);
- }
else if (us == "SEQ")
{
unsigned ii = 0;
@@ -567,6 +580,10 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
m_asm.append(i.m_asm);
m_asm.popTo(1);
}
+ else if (us == "PANIC")
+ {
+ m_asm.appendJump(m_asm.errorTag());
+ }
else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
m_asm.append((u256)varAddress(s));
else
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 7cfed3c8..7fe97fa7 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<IntegerType const>(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<FixedPointType const>(commonType))
if (Token::Exp == _operator)
diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp
index 553e5518..c1e05792 100644
--- a/libsolidity/codegen/LValue.cpp
+++ b/libsolidity/codegen/LValue.cpp
@@ -231,10 +231,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
m_context
<< (u256(0x1) << (256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes()))
<< Instruction::SWAP1 << Instruction::DIV;
- else if (
- m_dataType->category() == Type::Category::Integer &&
- dynamic_cast<IntegerType const&>(*m_dataType).isSigned()
- )
+ else
// remove the higher order bits
m_context
<< (u256(1) << (8 * (32 - m_dataType->storageBytes())))
@@ -242,9 +239,6 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
<< Instruction::DUP2
<< Instruction::MUL
<< Instruction::DIV;
- else if (m_dataType->category() == Type::Category::FixedPoint)
- // implementation should be very similar to the integer case.
- solAssert(false, "Not yet implemented - FixedPointType.");
m_context << Instruction::MUL << Instruction::OR;
// stack: value storage_ref updated_value
m_context << Instruction::SWAP1 << Instruction::SSTORE;
diff --git a/lllc/main.cpp b/lllc/main.cpp
index 06611af0..f8677be0 100644
--- a/lllc/main.cpp
+++ b/lllc/main.cpp
@@ -41,6 +41,7 @@ void help()
<< " -x,--hex Parse, compile and assemble; output byte code in hex." << endl
<< " -a,--assembly Only parse and compile; show assembly." << endl
<< " -t,--parse-tree Only parse; show parse tree." << endl
+ << " -o,--optimise Turn on/off the optimiser; off by default." << endl
<< " -h,--help Show this help message and exit." << endl
<< " -V,--version Show the version and exit." << endl;
exit(0);
@@ -81,7 +82,7 @@ enum Mode { Binary, Hex, Assembly, ParseTree, Disassemble };
int main(int argc, char** argv)
{
setDefaultOrCLocale();
- unsigned optimise = 1;
+ unsigned optimise = 0;
string infile;
Mode mode = Hex;
@@ -98,8 +99,8 @@ int main(int argc, char** argv)
mode = Assembly;
else if (arg == "-t" || arg == "--parse-tree")
mode = ParseTree;
- else if ((arg == "-o" || arg == "--optimise") && argc > i + 1)
- optimise = atoi(argv[++i]);
+ else if (arg == "-o" || arg == "--optimise")
+ optimise = 1;
else if (arg == "-d" || arg == "--disassemble")
mode = Disassemble;
else if (arg == "-V" || arg == "--version")
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 8ef9a45b..8600443d 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -7533,6 +7533,26 @@ BOOST_AUTO_TEST_CASE(inline_assembly_in_modifiers)
BOOST_CHECK(callContractFunction("f()") == encodeArgs(true));
}
+BOOST_AUTO_TEST_CASE(packed_storage_overflow)
+{
+ char const* sourceCode = R"(
+ contract C {
+ uint16 x = 0x1234;
+ uint16 a = 0xffff;
+ uint16 b;
+ function f() returns (uint, uint, uint, uint) {
+ a++;
+ uint c = b;
+ delete b;
+ a -= 2;
+ return (x, c, b, a);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x1234), u256(0), u256(0), u256(0xfffe)));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 9fe91cca..640cc108 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"(