aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--docs/assembly.rst2
-rw-r--r--docs/contracts.rst2
-rw-r--r--docs/types.rst8
-rw-r--r--libsolidity/ast/Types.cpp2
-rw-r--r--libsolidity/inlineasm/AsmParser.cpp5
-rw-r--r--test/compilationTests/stringutils/strings.sol18
-rw-r--r--test/libsolidity/InlineAssembly.cpp6
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp59
9 files changed, 57 insertions, 46 deletions
diff --git a/Changelog.md b/Changelog.md
index c1077926..6877ae22 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -10,6 +10,7 @@ Breaking Changes:
* General: ``continue`` in a ``do...while`` loop jumps to the condition (it used to jump to the loop body). Warning: this may silently change the semantics of existing code.
* Type Checker: Disallow arithmetic operations for Boolean variables.
* Disallow trailing dots that are not followed by a number.
+ * Remove assembly instructions ``sha3`` and ``suicide``
Language Features:
* General: Allow appending ``calldata`` keyword to types, to explicitly specify data location for arguments of external functions.
diff --git a/docs/assembly.rst b/docs/assembly.rst
index f7b721ab..edc826ac 100644
--- a/docs/assembly.rst
+++ b/docs/assembly.rst
@@ -220,8 +220,6 @@ In the grammar, opcodes are represented as pre-defined identifiers.
+-------------------------+-----+---+-----------------------------------------------------------------+
| keccak256(p, n) | | F | keccak(mem[p...(p+n))) |
+-------------------------+-----+---+-----------------------------------------------------------------+
-| sha3(p, n) | | F | keccak(mem[p...(p+n))) |
-+-------------------------+-----+---+-----------------------------------------------------------------+
| jump(label) | `-` | F | jump to label / code position |
+-------------------------+-----+---+-----------------------------------------------------------------+
| jumpi(label, cond) | `-` | F | jump to label if cond is nonzero |
diff --git a/docs/contracts.rst b/docs/contracts.rst
index 3d6ee869..e4f49f43 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -774,7 +774,7 @@ The use in the JavaScript API would be as follows:
// watch for changes
event.watch(function(error, result){
// result will contain various information
- // including the argumets given to the `Deposit`
+ // including the arguments given to the `Deposit`
// call.
if (!error)
console.log(result);
diff --git a/docs/types.rst b/docs/types.rst
index b3631f74..08b74241 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -226,10 +226,6 @@ Dynamically-sized byte array
``string``:
Dynamically-sized UTF-8-encoded string, see :ref:`arrays`. Not a value-type!
-As a rule of thumb, use ``bytes`` for arbitrary-length raw byte data and ``string``
-for arbitrary-length string (UTF-8) data. If you can limit the length to a certain
-number of bytes, always use one of ``bytes1`` to ``bytes32`` because they are much cheaper.
-
.. index:: address, literal;address
.. _address_literals:
@@ -602,8 +598,10 @@ shaves off one level in the type from the right).
Variables of type ``bytes`` and ``string`` are special arrays. A ``bytes`` is similar to ``byte[]``,
but it is packed tightly in calldata. ``string`` is equal to ``bytes`` but does not allow
length or index access (for now).
-
So ``bytes`` should always be preferred over ``byte[]`` because it is cheaper.
+As a rule of thumb, use ``bytes`` for arbitrary-length raw byte data and ``string``
+for arbitrary-length string (UTF-8) data. If you can limit the length to a certain
+number of bytes, always use one of ``bytes1`` to ``bytes32`` because they are much cheaper.
.. note::
If you want to access the byte-representation of a string ``s``, use
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 7f5ec46a..eb56e8ae 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -2529,6 +2529,7 @@ string FunctionType::richIdentifier() const
case Kind::AddMod: id += "addmod"; break;
case Kind::MulMod: id += "mulmod"; break;
case Kind::ArrayPush: id += "arraypush"; break;
+ case Kind::ArrayPop: id += "arraypop"; break;
case Kind::ByteArrayPush: id += "bytearraypush"; break;
case Kind::ObjectCreation: id += "objectcreation"; break;
case Kind::Assert: id += "assert"; break;
@@ -2683,6 +2684,7 @@ unsigned FunctionType::sizeOnStack() const
case Kind::BareDelegateCall:
case Kind::Internal:
case Kind::ArrayPush:
+ case Kind::ArrayPop:
case Kind::ByteArrayPush:
size = 1;
break;
diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp
index d300f8fb..431f33e5 100644
--- a/libsolidity/inlineasm/AsmParser.cpp
+++ b/libsolidity/inlineasm/AsmParser.cpp
@@ -318,11 +318,6 @@ std::map<string, dev::solidity::Instruction> const& Parser::instructions()
transform(name.begin(), name.end(), name.begin(), [](unsigned char _c) { return tolower(_c); });
s_instructions[name] = instruction.second;
}
-
- // add alias for suicide
- s_instructions["suicide"] = solidity::Instruction::SELFDESTRUCT;
- // add alis for sha3
- s_instructions["sha3"] = solidity::Instruction::KECCAK256;
}
return s_instructions;
}
diff --git a/test/compilationTests/stringutils/strings.sol b/test/compilationTests/stringutils/strings.sol
index 0a2d68bd..771f7a53 100644
--- a/test/compilationTests/stringutils/strings.sol
+++ b/test/compilationTests/stringutils/strings.sol
@@ -339,7 +339,7 @@ library strings {
*/
function keccak(slice self) internal returns (bytes32 ret) {
assembly {
- ret := sha3(mload(add(self, 32)), mload(self))
+ ret := keccak256(mload(add(self, 32)), mload(self))
}
}
@@ -363,7 +363,7 @@ library strings {
let len := mload(needle)
let selfptr := mload(add(self, 0x20))
let needleptr := mload(add(needle, 0x20))
- equal := eq(sha3(selfptr, len), sha3(needleptr, len))
+ equal := eq(keccak256(selfptr, len), keccak256(needleptr, len))
}
return equal;
}
@@ -386,7 +386,7 @@ library strings {
let len := mload(needle)
let selfptr := mload(add(self, 0x20))
let needleptr := mload(add(needle, 0x20))
- equal := eq(sha3(selfptr, len), sha3(needleptr, len))
+ equal := eq(keccak256(selfptr, len), keccak256(needleptr, len))
}
}
@@ -419,7 +419,7 @@ library strings {
assembly {
let len := mload(needle)
let needleptr := mload(add(needle, 0x20))
- equal := eq(sha3(selfptr, len), sha3(needleptr, len))
+ equal := eq(keccak256(selfptr, len), keccak256(needleptr, len))
}
return equal;
@@ -443,7 +443,7 @@ library strings {
assembly {
let len := mload(needle)
let needleptr := mload(add(needle, 0x20))
- equal := eq(sha3(selfptr, len), sha3(needleptr, len))
+ equal := eq(keccak256(selfptr, len), keccak256(needleptr, len))
}
}
@@ -479,11 +479,11 @@ library strings {
} else {
// For long needles, use hashing
bytes32 hash;
- assembly { hash := sha3(needleptr, needlelen) }
+ assembly { hash := keccak256(needleptr, needlelen) }
ptr = selfptr;
for (idx = 0; idx <= selflen - needlelen; idx++) {
bytes32 testHash;
- assembly { testHash := sha3(ptr, needlelen) }
+ assembly { testHash := keccak256(ptr, needlelen) }
if (hash == testHash)
return ptr;
ptr += 1;
@@ -519,11 +519,11 @@ library strings {
} else {
// For long needles, use hashing
bytes32 hash;
- assembly { hash := sha3(needleptr, needlelen) }
+ assembly { hash := keccak256(needleptr, needlelen) }
ptr = selfptr + (selflen - needlelen);
while (ptr >= selfptr) {
bytes32 testHash;
- assembly { testHash := sha3(ptr, needlelen) }
+ assembly { testHash := keccak256(ptr, needlelen) }
if (hash == testHash)
return ptr + needlelen;
ptr -= 1;
diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp
index 181ca959..3046372f 100644
--- a/test/libsolidity/InlineAssembly.cpp
+++ b/test/libsolidity/InlineAssembly.cpp
@@ -178,9 +178,9 @@ BOOST_AUTO_TEST_CASE(simple_instructions)
BOOST_CHECK(successParse("{ dup1 dup1 mul dup1 sub pop }"));
}
-BOOST_AUTO_TEST_CASE(suicide_selfdestruct)
+BOOST_AUTO_TEST_CASE(selfdestruct)
{
- BOOST_CHECK(successParse("{ 0x01 suicide 0x02 selfdestruct }"));
+ BOOST_CHECK(successParse("{ 0x02 selfdestruct }"));
}
BOOST_AUTO_TEST_CASE(keywords)
@@ -740,8 +740,6 @@ BOOST_AUTO_TEST_CASE(keccak256)
{
BOOST_CHECK(successAssemble("{ 0 0 keccak256 pop }"));
BOOST_CHECK(successAssemble("{ pop(keccak256(0, 0)) }"));
- BOOST_CHECK(successAssemble("{ 0 0 sha3 pop }"));
- BOOST_CHECK(successAssemble("{ pop(sha3(0, 0)) }"));
}
BOOST_AUTO_TEST_CASE(returndatasize)
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index f1fac396..b53a9294 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -5397,6 +5397,40 @@ BOOST_AUTO_TEST_CASE(byte_array_pop_copy_long)
));
}
+BOOST_AUTO_TEST_CASE(array_pop_isolated)
+{
+ char const* sourceCode = R"(
+ // This tests that the compiler knows the correct size of the function on the stack.
+ contract c {
+ uint[] data;
+ function test() public returns (uint x) {
+ x = 2;
+ data.pop;
+ x = 3;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("test()"), encodeArgs(3));
+}
+
+BOOST_AUTO_TEST_CASE(byte_array_pop_isolated)
+{
+ char const* sourceCode = R"(
+ // This tests that the compiler knows the correct size of the function on the stack.
+ contract c {
+ bytes data;
+ function test() public returns (uint x) {
+ x = 2;
+ data.pop;
+ x = 3;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("test()"), encodeArgs(3));
+}
+
BOOST_AUTO_TEST_CASE(external_array_args)
{
char const* sourceCode = R"(
@@ -8585,15 +8619,15 @@ BOOST_AUTO_TEST_CASE(inline_array_return)
{
char const* sourceCode = R"(
contract C {
- uint8[] tester;
+ uint8[] tester;
function f() returns (uint8[5]) {
return ([1,2,3,4,5]);
}
function test() returns (uint8, uint8, uint8, uint8, uint8) {
- tester = f();
+ tester = f();
return (tester[0], tester[1], tester[2], tester[3], tester[4]);
}
-
+
}
)";
compileAndRun(sourceCode, 0, "C");
@@ -8617,13 +8651,13 @@ BOOST_AUTO_TEST_CASE(inline_array_singleton)
BOOST_AUTO_TEST_CASE(inline_long_string_return)
{
char const* sourceCode = R"(
- contract C {
+ contract C {
function f() returns (string) {
return (["somethingShort", "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"][1]);
}
}
)";
-
+
string strLong = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
compileAndRun(sourceCode, 0, "C");
ABI_CHECK(callContractFunction("f()"), encodeDyn(strLong));
@@ -11431,26 +11465,11 @@ BOOST_AUTO_TEST_CASE(keccak256_assembly)
=: ret
}
}
- function h() pure returns (bytes32 ret) {
- assembly {
- ret := sha3(0, 0)
- }
- }
- function i() pure returns (bytes32 ret) {
- assembly {
- 0
- 0
- sha3
- =: ret
- }
- }
}
)";
compileAndRun(sourceCode, 0, "C");
ABI_CHECK(callContractFunction("f()"), fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
ABI_CHECK(callContractFunction("g()"), fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
- ABI_CHECK(callContractFunction("h()"), fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
- ABI_CHECK(callContractFunction("i()"), fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
}
BOOST_AUTO_TEST_CASE(multi_modifiers)