Merge pull request #7161 from ethereum/permit-zerolength-dyn-array-dimensions

Dynamically sized array dimensions can be zero sized
This commit is contained in:
Bhargava Shastry 2019-08-02 12:34:10 +02:00 committed by GitHub
commit 967ee944a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 12 deletions

View File

@ -328,13 +328,10 @@ void ProtoConverter::visit(StructType const&)
std::string ProtoConverter::arrayDimInfoAsString(ArrayDimensionInfo const& _x) std::string ProtoConverter::arrayDimInfoAsString(ArrayDimensionInfo const& _x)
{ {
unsigned arrLength = getArrayLengthFromFuzz(_x.length()); return Whiskers(R"([<?isStatic><length></isStatic>])")
if (_x.is_static()) ("isStatic", _x.is_static())
return Whiskers(R"([<length>])") ("length", std::to_string(getStaticArrayLengthFromFuzz(_x.length())))
("length", std::to_string(arrLength))
.render(); .render();
else
return R"([])";
} }
void ProtoConverter::arrayDimensionsAsStringVector( void ProtoConverter::arrayDimensionsAsStringVector(
@ -398,7 +395,7 @@ ProtoConverter::DataType ProtoConverter::getDataTypeByBaseType(ArrayType const&
// Adds a resize operation for a given dimension of type `_type` and expression referenced // Adds a resize operation for a given dimension of type `_type` and expression referenced
// by `_var`. `_isStatic` is true for statically sized dimensions, false otherwise. // by `_var`. `_isStatic` is true for statically sized dimensions, false otherwise.
// `_arrayLen` is equal to length of statically sized array dimension. For dynamically // `_arrayLen` is equal to length of statically sized array dimension. For dynamically
// sized dimension, we use `getArrayLengthFromFuzz()` and a monotonically increasing // sized dimension, we use `getDynArrayLengthFromFuzz()` and a monotonically increasing
// counter to obtain actual length. Function returns dimension length. // counter to obtain actual length. Function returns dimension length.
unsigned ProtoConverter::resizeDimension( unsigned ProtoConverter::resizeDimension(
bool _isStatic, bool _isStatic,
@ -413,7 +410,7 @@ unsigned ProtoConverter::resizeDimension(
length = _arrayLen; length = _arrayLen;
else else
{ {
length = getArrayLengthFromFuzz(_arrayLen, getNextCounter()); length = getDynArrayLengthFromFuzz(_arrayLen, getNextCounter());
// If local var, new T(l); // If local var, new T(l);
// Else, l; // Else, l;

View File

@ -334,14 +334,28 @@ private:
return toHex(maskUnsignedInt(_counter, _numMaskNibbles), HexPrefix::Add); return toHex(maskUnsignedInt(_counter, _numMaskNibbles), HexPrefix::Add);
} }
static unsigned getArrayLengthFromFuzz(unsigned _fuzz, unsigned _counter = 0) /// Dynamically sized arrays can have a length of at least zero
/// and at most s_maxArrayLength.
static unsigned getDynArrayLengthFromFuzz(unsigned _fuzz, unsigned _counter)
{ {
return ((_fuzz + _counter) % s_maxArrayLength) + 1; // Increment modulo value by one in order to meet upper bound
return (_fuzz + _counter) % (s_maxArrayLength + 1);
}
/// Statically sized arrays must have a length of at least one
/// and at most s_maxArrayLength.
static unsigned getStaticArrayLengthFromFuzz(unsigned _fuzz)
{
return _fuzz % s_maxArrayLength + 1;
} }
static std::pair<bool, unsigned> arrayDimInfoAsPair(ArrayDimensionInfo const& _x) static std::pair<bool, unsigned> arrayDimInfoAsPair(ArrayDimensionInfo const& _x)
{ {
return std::make_pair(_x.is_static(), getArrayLengthFromFuzz(_x.length())); return (
_x.is_static() ?
std::make_pair(true, getStaticArrayLengthFromFuzz(_x.length())) :
std::make_pair(false, getDynArrayLengthFromFuzz(_x.length(), 0))
);
} }
/// Contains the test program /// Contains the test program
@ -360,7 +374,7 @@ private:
unsigned m_varCounter; unsigned m_varCounter;
/// Monotonically increasing return value for error reporting /// Monotonically increasing return value for error reporting
unsigned m_returnValue; unsigned m_returnValue;
static unsigned constexpr s_maxArrayLength = 2; static unsigned constexpr s_maxArrayLength = 4;
static unsigned constexpr s_maxArrayDimensions = 10; static unsigned constexpr s_maxArrayDimensions = 10;
/// Prefixes for declared and parameterized variable names /// Prefixes for declared and parameterized variable names
static auto constexpr s_varNamePrefix = "x_"; static auto constexpr s_varNamePrefix = "x_";