diff --git a/Changelog.md b/Changelog.md index c31aced2a..a1248868f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ ### 0.5.0 (unreleased) +Language Features: + * General: Support ``pop()`` for storage arrays. Breaking Changes: * Disallow conversions between bytesX and uintY of different size. diff --git a/docs/types.rst b/docs/types.rst index 794a70de0..b3631f747 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -682,7 +682,7 @@ possible: It is planned to remove this restriction in the future but currently creates some complications because of how arrays are passed in the ABI. -.. index:: ! array;length, length, push, !array;push +.. index:: ! array;length, length, push, pop, !array;push, !array;pop Members ^^^^^^^ @@ -693,6 +693,8 @@ Members ``.length`` member. This does not happen automatically when attempting to access elements outside the current length. The size of memory arrays is fixed (but dynamic, i.e. it can depend on runtime parameters) once they are created. **push**: Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``push`` that can be used to append an element at the end of the array. The function returns the new length. +**pop**: + Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``pop`` that can be used to remove an element from the end of the array. .. warning:: It is not yet possible to use arrays of arrays in external functions. diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index d78e64a92..6bb9a9612 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -840,7 +840,7 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const let length := and(div(slot_value, 2), 0x1f) if iszero(length) { invalid() } - // Zero-out the suffix inlcluding the least significant byte. + // Zero-out the suffix including the least significant byte. let mask := sub(exp(0x100, sub(33, length)), 1) length := sub(length, 1) slot_value := or(and(not(mask), slot_value), mul(length, 2)) diff --git a/libsolidity/codegen/ArrayUtils.h b/libsolidity/codegen/ArrayUtils.h index 84d591d7e..daf50bf52 100644 --- a/libsolidity/codegen/ArrayUtils.h +++ b/libsolidity/codegen/ArrayUtils.h @@ -73,7 +73,7 @@ public: /// Stack pre: reference (excludes byte offset) /// Stack post: new_length void incrementDynamicArraySize(ArrayType const& _type) const; - /// Decrements the size of a dynamic array by one if length is nonzero. Returns otherwise. + /// Decrements the size of a dynamic array by one if length is nonzero. Causes an invalid instruction otherwise. /// Clears the removed data element. In case of a byte array, this might move the data. /// Stack pre: reference /// Stack post: diff --git a/test/libsolidity/syntaxTests/array/array_pop.sol b/test/libsolidity/syntaxTests/array/array_pop.sol new file mode 100644 index 000000000..3804f911f --- /dev/null +++ b/test/libsolidity/syntaxTests/array/array_pop.sol @@ -0,0 +1,7 @@ +contract C { + uint[] data; + function test() public { + data.pop(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/array/array_pop_arg.sol b/test/libsolidity/syntaxTests/array/array_pop_arg.sol new file mode 100644 index 000000000..bb7803e28 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/array_pop_arg.sol @@ -0,0 +1,8 @@ +contract C { + uint[] data; + function test() public { + data.pop(5); + } +} +// ---- +// TypeError: (65-76): Wrong argument count for function call: 1 arguments given but expected 0. diff --git a/test/libsolidity/syntaxTests/array/bytes_pop.sol b/test/libsolidity/syntaxTests/array/bytes_pop.sol new file mode 100644 index 000000000..cd5aa0eb6 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/bytes_pop.sol @@ -0,0 +1,7 @@ +contract C { + bytes data; + function test() public { + data.pop(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/array/dynamic_memory_array_pop.sol b/test/libsolidity/syntaxTests/array/dynamic_memory_array_pop.sol new file mode 100644 index 000000000..5a79afc93 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/dynamic_memory_array_pop.sol @@ -0,0 +1,8 @@ +contract C { + function test() public { + uint[] memory data; + data.pop(); + } +} +// ---- +// TypeError: (74-82): Member "pop" is not available in uint256[] memory outside of storage. diff --git a/test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol b/test/libsolidity/syntaxTests/array/length/array_length_cannot_be_constant_function_parameter.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol rename to test/libsolidity/syntaxTests/array/length/array_length_cannot_be_constant_function_parameter.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol b/test/libsolidity/syntaxTests/array/length/can_be_constant_in_function.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol rename to test/libsolidity/syntaxTests/array/length/can_be_constant_in_function.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol b/test/libsolidity/syntaxTests/array/length/can_be_constant_in_struct.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol rename to test/libsolidity/syntaxTests/array/length/can_be_constant_in_struct.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol b/test/libsolidity/syntaxTests/array/length/can_be_recursive_constant.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol rename to test/libsolidity/syntaxTests/array/length/can_be_recursive_constant.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol b/test/libsolidity/syntaxTests/array/length/cannot_be_function.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol rename to test/libsolidity/syntaxTests/array/length/cannot_be_function.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol b/test/libsolidity/syntaxTests/array/length/cannot_be_function_call.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol rename to test/libsolidity/syntaxTests/array/length/cannot_be_function_call.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol b/test/libsolidity/syntaxTests/array/length/complex_cyclic_constant.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol rename to test/libsolidity/syntaxTests/array/length/complex_cyclic_constant.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol b/test/libsolidity/syntaxTests/array/length/const_cannot_be_fractional.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol rename to test/libsolidity/syntaxTests/array/length/const_cannot_be_fractional.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/constant_var.sol b/test/libsolidity/syntaxTests/array/length/constant_var.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/constant_var.sol rename to test/libsolidity/syntaxTests/array/length/constant_var.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol b/test/libsolidity/syntaxTests/array/length/cyclic_constant.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol rename to test/libsolidity/syntaxTests/array/length/cyclic_constant.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/inline_array.sol b/test/libsolidity/syntaxTests/array/length/inline_array.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/inline_array.sol rename to test/libsolidity/syntaxTests/array/length/inline_array.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_1.sol b/test/libsolidity/syntaxTests/array/length/invalid_expression_1.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/invalid_expression_1.sol rename to test/libsolidity/syntaxTests/array/length/invalid_expression_1.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol b/test/libsolidity/syntaxTests/array/length/invalid_expression_2.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol rename to test/libsolidity/syntaxTests/array/length/invalid_expression_2.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol b/test/libsolidity/syntaxTests/array/length/invalid_expression_3.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol rename to test/libsolidity/syntaxTests/array/length/invalid_expression_3.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol b/test/libsolidity/syntaxTests/array/length/invalid_expression_4.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol rename to test/libsolidity/syntaxTests/array/length/invalid_expression_4.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol b/test/libsolidity/syntaxTests/array/length/invalid_expression_5.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol rename to test/libsolidity/syntaxTests/array/length/invalid_expression_5.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol b/test/libsolidity/syntaxTests/array/length/non_integer_constant_var.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol rename to test/libsolidity/syntaxTests/array/length/non_integer_constant_var.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol b/test/libsolidity/syntaxTests/array/length/not_convertible_to_integer.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol rename to test/libsolidity/syntaxTests/array/length/not_convertible_to_integer.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/parentheses.sol b/test/libsolidity/syntaxTests/array/length/parentheses.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/parentheses.sol rename to test/libsolidity/syntaxTests/array/length/parentheses.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/pure_functions.sol b/test/libsolidity/syntaxTests/array/length/pure_functions.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/pure_functions.sol rename to test/libsolidity/syntaxTests/array/length/pure_functions.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/too_large.sol b/test/libsolidity/syntaxTests/array/length/too_large.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/too_large.sol rename to test/libsolidity/syntaxTests/array/length/too_large.sol diff --git a/test/libsolidity/syntaxTests/arrayLength/tuples.sol b/test/libsolidity/syntaxTests/array/length/tuples.sol similarity index 100% rename from test/libsolidity/syntaxTests/arrayLength/tuples.sol rename to test/libsolidity/syntaxTests/array/length/tuples.sol diff --git a/test/libsolidity/syntaxTests/array/no_array_pop.sol b/test/libsolidity/syntaxTests/array/no_array_pop.sol new file mode 100644 index 000000000..44e54ad2f --- /dev/null +++ b/test/libsolidity/syntaxTests/array/no_array_pop.sol @@ -0,0 +1,8 @@ +contract C { + uint data; + function test() public { + data.pop(); + } +} +// ---- +// TypeError: (63-71): Member "pop" not found or not visible after argument-dependent lookup in uint256 diff --git a/test/libsolidity/syntaxTests/array/static_storage_array_pop.sol b/test/libsolidity/syntaxTests/array/static_storage_array_pop.sol new file mode 100644 index 000000000..0af171ad5 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/static_storage_array_pop.sol @@ -0,0 +1,8 @@ +contract C { + uint[3] data; + function test() public { + data.pop(); + } +} +// ---- +// TypeError: (66-74): Member "pop" not found or not visible after argument-dependent lookup in uint256[3] storage ref diff --git a/test/libsolidity/syntaxTests/array/string_pop.sol b/test/libsolidity/syntaxTests/array/string_pop.sol new file mode 100644 index 000000000..2a46d0c3e --- /dev/null +++ b/test/libsolidity/syntaxTests/array/string_pop.sol @@ -0,0 +1,8 @@ +contract C { + string data; + function test() public { + data.pop(); + } +} +// ---- +// TypeError: (65-73): Member "pop" not found or not visible after argument-dependent lookup in string storage ref