aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/parsing/Scanner.cpp8
-rw-r--r--test/libsolidity/SolidityScanner.cpp20
-rw-r--r--test/libsolidity/syntaxTests/parsing/trailing_dot1.sol7
-rw-r--r--test/libsolidity/syntaxTests/parsing/trailing_dot2.sol7
-rw-r--r--test/libsolidity/syntaxTests/parsing/trailing_dot3.sol4
6 files changed, 46 insertions, 1 deletions
diff --git a/Changelog.md b/Changelog.md
index 13e3f676..c1077926 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -9,6 +9,7 @@ Breaking Changes:
* General: New keywords: ``calldata``
* General: ``continue`` in a ``do...while`` loop jumps to the condition (it used to jump to the loop body). Warning: this may silently change the semantics of existing code.
* Type Checker: Disallow arithmetic operations for Boolean variables.
+ * Disallow trailing dots that are not followed by a number.
Language Features:
* General: Allow appending ``calldata`` keyword to types, to explicitly specify data location for arguments of external functions.
diff --git a/libsolidity/parsing/Scanner.cpp b/libsolidity/parsing/Scanner.cpp
index 6541f6c2..801d2cc4 100644
--- a/libsolidity/parsing/Scanner.cpp
+++ b/libsolidity/parsing/Scanner.cpp
@@ -768,8 +768,14 @@ Token::Value Scanner::scanNumber(char _charSeen)
scanDecimalDigits(); // optional
if (m_char == '.')
{
+ // A '.' has to be followed by a number.
+ if (m_source.isPastEndOfInput() || !isDecimalDigit(m_source.get(1)))
+ {
+ literal.complete();
+ return Token::Number;
+ }
addLiteralCharAndAdvance();
- scanDecimalDigits(); // optional
+ scanDecimalDigits();
}
}
}
diff --git a/test/libsolidity/SolidityScanner.cpp b/test/libsolidity/SolidityScanner.cpp
index 020bce7f..f455c5eb 100644
--- a/test/libsolidity/SolidityScanner.cpp
+++ b/test/libsolidity/SolidityScanner.cpp
@@ -127,6 +127,26 @@ BOOST_AUTO_TEST_CASE(scientific_notation)
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
}
+BOOST_AUTO_TEST_CASE(trailing_dot)
+{
+ Scanner scanner(CharStream("2.5"));
+ BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
+ scanner.reset(CharStream("2.5e10"), "");
+ BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
+ scanner.reset(CharStream(".5"), "");
+ BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
+ scanner.reset(CharStream(".5e10"), "");
+ BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
+ scanner.reset(CharStream("2."), "");
+ BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Number);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::Period);
+ BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
+}
+
BOOST_AUTO_TEST_CASE(negative_numbers)
{
Scanner scanner(CharStream("var x = -.2 + -0x78 + -7.3 + 8.9 + 2e-2;"));
diff --git a/test/libsolidity/syntaxTests/parsing/trailing_dot1.sol b/test/libsolidity/syntaxTests/parsing/trailing_dot1.sol
new file mode 100644
index 00000000..7f26242c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/trailing_dot1.sol
@@ -0,0 +1,7 @@
+contract test {
+ uint256 a = 2.2e10;
+ uint256 b = .5E10;
+ uint256 c = 4.e-2;
+}
+// ----
+// TypeError: (70-73): Member "e" not found or not visible after argument-dependent lookup in int_const 4
diff --git a/test/libsolidity/syntaxTests/parsing/trailing_dot2.sol b/test/libsolidity/syntaxTests/parsing/trailing_dot2.sol
new file mode 100644
index 00000000..38a7ab2d
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/trailing_dot2.sol
@@ -0,0 +1,7 @@
+contract test {
+ uint256 a = 2.2e10;
+ uint256 b = .5E10;
+ uint256 c = 2 + 2.;
+}
+// ----
+// ParserError: (76-77): Expected identifier but got ';'
diff --git a/test/libsolidity/syntaxTests/parsing/trailing_dot3.sol b/test/libsolidity/syntaxTests/parsing/trailing_dot3.sol
new file mode 100644
index 00000000..6a126cb3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/trailing_dot3.sol
@@ -0,0 +1,4 @@
+contract test {
+ uint a = 2.
+// ----
+// ParserError: (29-29): Expected identifier but got end of source