aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsolidity/parsing/ParserBase.cpp78
-rw-r--r--libsolidity/parsing/Scanner.h7
-rw-r--r--libsolidity/parsing/Token.cpp9
-rw-r--r--libsolidity/parsing/Token.h15
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp12
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()
}