diff options
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 11 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 9 | ||||
-rw-r--r-- | test/libsolidity/SolidityParser.cpp | 26 |
3 files changed, 28 insertions, 18 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f2113d2f..9718bf75 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -779,7 +779,6 @@ bool TypeChecker::visit(Assignment const& _assignment) bool TypeChecker::visit(TupleExpression const& _tuple) { - vector<ASTPointer<Expression>> const& components = _tuple.components(); solAssert(!_tuple.isInlineArray(), "Tuple type not properly declared"); TypePointers types; @@ -793,10 +792,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple) } else types.push_back(TypePointer()); - if (_tuple.isInlineArray()) - _tuple.annotation().type = make_shared<ArrayType>(DataLocation::Storage, _tuple.annotation().type, types.size()); - else - _tuple.annotation().type = make_shared<TupleType>(types); + _tuple.annotation().type = make_shared<TupleType>(types); // If some of the components are not LValues, the error is reported above. _tuple.annotation().isLValue = true; } @@ -806,10 +802,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple) { // Outside of an lvalue-context, the only situation where a component can be empty is (x,). if (!components[i] && !(i == 1 && components.size() == 2)) - _tuple.isInlineArray() ? - fatalTypeError(_tuple.location(), "Array component cannot have empty cells.") - : - fatalTypeError(_tuple.location(), "Tuple component cannot be empty."); + fatalTypeError(_tuple.location(), "Tuple component cannot be empty."); else if (components[i]) { components[i]->accept(*this); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index cb5968e9..e7391dff 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1043,9 +1043,10 @@ ASTPointer<Expression> Parser::parsePrimaryExpression() m_scanner->next(); vector<ASTPointer<Expression>> components; Token::Value oppositeToken = (token == Token::LParen ? Token::RParen : Token::RBrack); - bool isArray = (token == Token::LParen ? false : true); - - if (m_scanner->currentToken() != Token::RParen) + bool isArray = (token == Token::RBrace ? true : false); + if (isArray && (m_scanner->currentToken() == Token::Comma)) + fatalParserError("Expected value in array cell after '[' ."); + if (m_scanner->currentToken() != oppositeToken) while (true) { if (m_scanner->currentToken() != Token::Comma && m_scanner->currentToken() != oppositeToken) @@ -1055,6 +1056,8 @@ ASTPointer<Expression> Parser::parsePrimaryExpression() if (m_scanner->currentToken() == oppositeToken) break; else if (m_scanner->currentToken() == Token::Comma) + if (isArray && (m_scanner->peekNextToken() == (Token::Comma || oppositeToken))) + fatalParserError("Expected value in array cell after ',' ."); m_scanner->next(); } nodeFactory.markEndPosition(); diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index d8c1a3e6..b1af54e0 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -1051,16 +1051,30 @@ BOOST_AUTO_TEST_CASE(inline_array_declaration) { char const* text = R"( contract c { - uint[] a; - function f() returns (uint, uint) { - a = [1,2,3]; - return (a[3], [3,4][0]); - } - } + uint[] a; + function f() returns (uint, uint) { + a = [1,2,3]; + return (a[3], [3,4][0]); + } + } )"; BOOST_CHECK(successParse(text)); } +BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check) +{ + char const* text = R"( + contract c { + uint[] a; + function f() returns (uint, uint) { + a = [,2,3]; + return (a[3], [3,4][0]); + } + } + )"; + BOOST_CHECK(!successParse(text)); +} + BOOST_AUTO_TEST_SUITE_END() } |