From 3a17274691210191a6a407e7314a3070af87233c Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 31 Mar 2022 20:36:45 -0500 Subject: [PATCH] Improve error message for static array with size too large --- libsolidity/analysis/DeclarationTypeChecker.cpp | 8 +++++++- .../array/length/bytes32_too_large.sol | 2 +- .../array/length/bytes32_too_large_multidim.sol | 2 +- .../array/length/literal_conversion.sol | 16 ++++++++++++++++ .../syntaxTests/array/length/too_large.sol | 5 ++++- .../array/length/uint_too_large_multidim.sol | 2 +- 6 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 test/libsolidity/syntaxTests/array/length/literal_conversion.sol diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index 4fb210435..54a7354e2 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -297,7 +297,7 @@ void DeclarationTypeChecker::endVisit(ArrayTypeName const& _typeName) else if (optional value = ConstantEvaluator::evaluate(m_errorReporter, *length)) lengthValue = value->value; - if (!lengthValue || lengthValue > TypeProvider::uint256()->max()) + if (!lengthValue) m_errorReporter.typeError( 5462_error, length->location(), @@ -309,6 +309,12 @@ void DeclarationTypeChecker::endVisit(ArrayTypeName const& _typeName) m_errorReporter.typeError(3208_error, length->location(), "Array with fractional length specified."); else if (*lengthValue < 0) m_errorReporter.typeError(3658_error, length->location(), "Array with negative length specified."); + else if (lengthValue > TypeProvider::uint256()->max()) + m_errorReporter.typeError( + 1847_error, + length->location(), + "Array length too large, maximum is 2**256 - 1." + ); _typeName.annotation().type = TypeProvider::array( DataLocation::Storage, diff --git a/test/libsolidity/syntaxTests/array/length/bytes32_too_large.sol b/test/libsolidity/syntaxTests/array/length/bytes32_too_large.sol index 37f194899..8ab641984 100644 --- a/test/libsolidity/syntaxTests/array/length/bytes32_too_large.sol +++ b/test/libsolidity/syntaxTests/array/length/bytes32_too_large.sol @@ -2,4 +2,4 @@ contract C { bytes32[8**90] ids; } // ---- -// TypeError 5462: (25-30): Invalid array length, expected integer literal or constant expression. +// TypeError 1847: (25-30): Array length too large, maximum is 2**256 - 1. diff --git a/test/libsolidity/syntaxTests/array/length/bytes32_too_large_multidim.sol b/test/libsolidity/syntaxTests/array/length/bytes32_too_large_multidim.sol index 1a4e7f64c..8a7eeb4d5 100644 --- a/test/libsolidity/syntaxTests/array/length/bytes32_too_large_multidim.sol +++ b/test/libsolidity/syntaxTests/array/length/bytes32_too_large_multidim.sol @@ -2,4 +2,4 @@ contract C { bytes32[8**90][500] ids; } // ---- -// TypeError 5462: (25-30): Invalid array length, expected integer literal or constant expression. +// TypeError 1847: (25-30): Array length too large, maximum is 2**256 - 1. diff --git a/test/libsolidity/syntaxTests/array/length/literal_conversion.sol b/test/libsolidity/syntaxTests/array/length/literal_conversion.sol new file mode 100644 index 000000000..cf769f337 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/length/literal_conversion.sol @@ -0,0 +1,16 @@ +contract C { + uint[uint(1)] valid_size_invalid_expr1; + uint[uint(2**256-1)] valid_size_invalid_expr2; + uint[uint(2**256)] invalid_size_invalid_expr3; + + uint[int(1)] valid_size_invalid_expr4; + uint[int(2**256-1)] valid_size_invalid_expr5; + uint[int(2**256)] invalid_size_invalid_expr6; +} +// ---- +// TypeError 5462: (22-29): Invalid array length, expected integer literal or constant expression. +// TypeError 5462: (66-80): Invalid array length, expected integer literal or constant expression. +// TypeError 5462: (117-129): Invalid array length, expected integer literal or constant expression. +// TypeError 5462: (169-175): Invalid array length, expected integer literal or constant expression. +// TypeError 5462: (212-225): Invalid array length, expected integer literal or constant expression. +// TypeError 5462: (262-273): Invalid array length, expected integer literal or constant expression. diff --git a/test/libsolidity/syntaxTests/array/length/too_large.sol b/test/libsolidity/syntaxTests/array/length/too_large.sol index 687e80303..7d59fd86c 100644 --- a/test/libsolidity/syntaxTests/array/length/too_large.sol +++ b/test/libsolidity/syntaxTests/array/length/too_large.sol @@ -1,5 +1,8 @@ contract C { uint[8**90] ids; + uint[2**256-1] okay; + uint[2**256] tooLarge; } // ---- -// TypeError 5462: (22-27): Invalid array length, expected integer literal or constant expression. +// TypeError 1847: (22-27): Array length too large, maximum is 2**256 - 1. +// TypeError 1847: (68-74): Array length too large, maximum is 2**256 - 1. diff --git a/test/libsolidity/syntaxTests/array/length/uint_too_large_multidim.sol b/test/libsolidity/syntaxTests/array/length/uint_too_large_multidim.sol index 6ea3eda50..f3e249f83 100644 --- a/test/libsolidity/syntaxTests/array/length/uint_too_large_multidim.sol +++ b/test/libsolidity/syntaxTests/array/length/uint_too_large_multidim.sol @@ -2,4 +2,4 @@ contract C { uint[8**90][500] ids; } // ---- -// TypeError 5462: (22-27): Invalid array length, expected integer literal or constant expression. +// TypeError 1847: (22-27): Array length too large, maximum is 2**256 - 1.