diff options
-rw-r--r-- | libsolidity/parsing/ParserBase.cpp | 78 | ||||
-rw-r--r-- | libsolidity/parsing/Scanner.h | 7 | ||||
-rw-r--r-- | libsolidity/parsing/Token.cpp | 9 | ||||
-rw-r--r-- | libsolidity/parsing/Token.h | 15 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 12 |
5 files changed, 92 insertions, 29 deletions
diff --git a/libsolidity/parsing/ParserBase.cpp b/libsolidity/parsing/ParserBase.cpp index 64e42841..71085a4d 100644 --- a/libsolidity/parsing/ParserBase.cpp +++ b/libsolidity/parsing/ParserBase.cpp @@ -44,14 +44,29 @@ int ParserBase::endPosition() const void ParserBase::expectToken(Token::Value _value) { - if (m_scanner->currentToken() != _value) - fatalParserError( - string("Expected token ") + - string(Token::name(_value)) + - string(" got '") + - string(Token::name(m_scanner->currentToken())) + - string("'") - ); + Token::Value tok = m_scanner->currentToken(); + if (tok != _value) + { + if (Token::isElementaryTypeName(tok)) //for the sake of accuracy in reporting + { + ElementaryTypeNameToken elemTypeName = m_scanner->currentElementaryTypeNameToken(); + fatalParserError( + string("Expected token ") + + string(Token::name(_value)) + + string(" got '") + + elemTypeName.toString() + + string("'") + ); + } + else + fatalParserError( + string("Expected token ") + + string(Token::name(_value)) + + string(" got '") + + string(Token::name(m_scanner->currentToken())) + + string("'") + ); + } m_scanner->next(); } @@ -59,23 +74,48 @@ Token::Value ParserBase::expectAssignmentOperator() { Token::Value op = m_scanner->currentToken(); if (!Token::isAssignmentOp(op)) - fatalParserError( - string("Expected assignment operator, got '") + - string(Token::name(m_scanner->currentToken())) + - string("'") - ); + { + if (Token::isElementaryTypeName(op)) //for the sake of accuracy in reporting + { + ElementaryTypeNameToken elemTypeName = m_scanner->currentElementaryTypeNameToken(); + fatalParserError( + string("Expected assignment operator, got '") + + elemTypeName.toString() + + string("'") + ); + } + else + fatalParserError( + string("Expected assignment operator, got '") + + string(Token::name(m_scanner->currentToken())) + + string("'") + ); + } m_scanner->next(); return op; } ASTPointer<ASTString> ParserBase::expectIdentifierToken() { - if (m_scanner->currentToken() != Token::Identifier) - fatalParserError( - string("Expected identifier, got '") + - string(Token::name(m_scanner->currentToken())) + - string("'") - ); + Token::Value id = m_scanner->currentToken(); + if (id != Token::Identifier) + { + if (Token::isElementaryTypeName(id)) //for the sake of accuracy in reporting + { + ElementaryTypeNameToken elemTypeName = m_scanner->currentElementaryTypeNameToken(); + fatalParserError( + string("Expected identifier, got '") + + elemTypeName.toString() + + string("'") + ); + } + else + fatalParserError( + string("Expected identifier, got '") + + string(Token::name(id)) + + string("'") + ); + } return getLiteralAndAdvance(); } diff --git a/libsolidity/parsing/Scanner.h b/libsolidity/parsing/Scanner.h index cffcec8e..ac9f18e8 100644 --- a/libsolidity/parsing/Scanner.h +++ b/libsolidity/parsing/Scanner.h @@ -119,6 +119,13 @@ public: { return m_currentToken.token; } + ElementaryTypeNameToken currentElementaryTypeNameToken() + { + unsigned firstSize; + unsigned secondSize; + std::tie(firstSize, secondSize) = m_currentToken.extendedTokenInfo; + return ElementaryTypeNameToken(m_currentToken.token, firstSize, secondSize); + } SourceLocation currentLocation() const { return m_currentToken.location; } std::string const& currentLiteral() const { return m_currentToken.literal; } diff --git a/libsolidity/parsing/Token.cpp b/libsolidity/parsing/Token.cpp index 3812a83f..c73368e5 100644 --- a/libsolidity/parsing/Token.cpp +++ b/libsolidity/parsing/Token.cpp @@ -155,16 +155,17 @@ tuple<Token::Value, unsigned int, unsigned int> Token::fromIdentifierOrKeyword(s ) { int n = parseSize(positionX + 1, _literal.end()); if ( - 0 < m && m < 256 && - 0 < n && n < 256 && + 0 <= m && m <= 256 && + 0 <= n && n <= 256 && + m + n > 0 && m + n <= 256 && m % 8 == 0 && n % 8 == 0 ) { if (keyword == Token::UFixed) - return make_tuple(Token::UFixed, m, n); + return make_tuple(Token::UFixedMxN, m, n); else - return make_tuple(Token::Fixed, m, n); + return make_tuple(Token::FixedMxN, m, n); } } } diff --git a/libsolidity/parsing/Token.h b/libsolidity/parsing/Token.h index 31646f8d..76c274bb 100644 --- a/libsolidity/parsing/Token.h +++ b/libsolidity/parsing/Token.h @@ -190,18 +190,18 @@ namespace solidity K(After, "after", 0) \ /* type keywords*/ \ K(Int, "int", 0) \ - T(IntM, "intM", 0) \ K(UInt, "uint", 0) \ - T(UIntM, "uintM", 0) \ K(Bytes, "bytes", 0) \ - T(BytesM, "bytesM", 0) \ K(Byte, "byte", 0) \ K(String, "string", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ K(Fixed, "fixed", 0) \ - T(FixedMxN, "fixedMxN", 0) \ K(UFixed, "ufixed", 0) \ + T(IntM, "intM", 0) \ + T(UIntM, "uintM", 0) \ + T(BytesM, "bytesM", 0) \ + T(FixedMxN, "fixedMxN", 0) \ T(UFixedMxN, "ufixedMxN", 0) \ T(TypesEnd, NULL, 0) /* used as type enum end marker */ \ \ @@ -334,8 +334,11 @@ public: std::string name = Token::toString(m_token); if (tokenValue || (firstNumber() == 0 && secondNumber() == 0)) return name; - //need to set it up this way for fixed types construction in future - return name.substr(0, name.size() - 1) + std::to_string(m_firstNumber); + solAssert(name.size() >= 3, "Token name size should be greater than 3. Should not reach here."); + if (m_token == Token::FixedMxN || m_token == Token::UFixedMxN) + return name.substr(0, name.size() - 3) + std::to_string(m_firstNumber) + "x" + std::to_string(m_secondNumber); + else + return name.substr(0, name.size() - 1) + std::to_string(m_firstNumber); } private: diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 3d0cc2cd..684731e8 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -3258,6 +3258,18 @@ BOOST_AUTO_TEST_CASE(library_functions_do_not_have_value) BOOST_CHECK(!success(text)); } +BOOST_AUTO_TEST_CASE(invalid_fixed_type_long) +{ + char const* text = R"( + contract test { + function f() { + fixed8x888888888888888888888888888888888888888888888888888 b; + } + } + )"; + BOOST_CHECK(!success(text)); +} + BOOST_AUTO_TEST_SUITE_END() } |