aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsolidity/analysis/TypeChecker.cpp11
-rw-r--r--libsolidity/parsing/Parser.cpp9
-rw-r--r--test/libsolidity/SolidityParser.cpp26
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()
}