diff --git a/Changelog.md b/Changelog.md index 763312b52..6de017511 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ Bugfixes: * Code generator: Defensively pad allocation of creationCode and runtimeCode to multiples of 32 bytes. * Parser: Disallow empty import statements. * Type Checker: Dissallow mappings with data locations other than 'storage' + * Type Checker: Fix internal error when a struct array index does not fit into a uint256. * Type system: Properly report packed encoded size for arrays and structs (mostly unused until now). diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index b5b7d9152..225735bac 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -2205,15 +2205,22 @@ bool TypeChecker::visit(IndexAccess const& _access) resultType = make_shared(make_shared(DataLocation::Memory, typeType.actualType())); else { - expectType(*index, IntegerType::uint256()); - if (auto length = dynamic_cast(type(*index).get())) - resultType = make_shared(make_shared( - DataLocation::Memory, - typeType.actualType(), - length->literalValue(nullptr) - )); + u256 length = 1; + if (expectType(*index, IntegerType::uint256())) + { + if (auto indexValue = dynamic_cast(type(*index).get())) + length = indexValue->literalValue(nullptr); + else + m_errorReporter.fatalTypeError(index->location(), "Integer constant expected."); + } else - m_errorReporter.fatalTypeError(index->location(), "Integer constant expected."); + solAssert(m_errorReporter.hasErrors(), "Expected errors as expectType returned false"); + + resultType = make_shared(make_shared( + DataLocation::Memory, + typeType.actualType(), + length + )); } break; } diff --git a/test/libsolidity/syntaxTests/indexing/struct_array_noninteger_index.sol b/test/libsolidity/syntaxTests/indexing/struct_array_noninteger_index.sol new file mode 100644 index 000000000..59010709d --- /dev/null +++ b/test/libsolidity/syntaxTests/indexing/struct_array_noninteger_index.sol @@ -0,0 +1,10 @@ +contract test { + struct s { uint a; uint b;} + function f() pure public returns (byte) { + s[75555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555]; + s[7]; + } +} + +// ---- +// TypeError: (101-241): Type int_const 7555...(132 digits omitted)...5555 is not implicitly convertible to expected type uint256.