You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix remaining cases in #1163, and systematically early-return when an error is detected
Closes#1163
The three remaining cases were lack of backtracking after refusing to parse `: name *` with the helpful error about the Cpp1-style pointer declaration being invalid
But also more generally: Several recent ICE/ASAN bug reports, including the first two in #1163, have been because of trying to continue lexing/parsing for a bit after an error was identified, so I also went through to systematically ensure every time we record an error we (a) early-return and (b) don't do next() since there should be no point... (a) is the main improvement, (b) is just hygiene but probably has no effect. This change only changes the output of two regression test cases, and both are improvements.
" - see also cpp2util.h > \"Convenience names for integer types\""
753
753
);
754
+
755
+
return;
754
756
}
755
757
756
758
tokens.push_back(last_token);
@@ -1002,6 +1004,7 @@ auto lex_line(
1002
1004
"invalid universal character name - \\u without { must"
1003
1005
" be followed by 4 hexadecimal digits"
1004
1006
);
1007
+
return0;
1005
1008
}
1006
1009
1007
1010
elseif (
@@ -1022,15 +1025,16 @@ auto lex_line(
1022
1025
1023
1026
if (peek(j + offset) == '}') {
1024
1027
++j;
1028
+
return j;
1025
1029
}
1026
1030
else {
1027
1031
errors.emplace_back(
1028
1032
source_position(lineno, i + offset),
1029
1033
"invalid universal character name - \\u{ must"
1030
1034
" be followed by hexadecimal digits and a closing }"
1031
1035
);
1036
+
return0;
1032
1037
}
1033
-
return j;
1034
1038
}
1035
1039
1036
1040
elseif (
@@ -1052,7 +1056,9 @@ auto lex_line(
1052
1056
"invalid universal character name - \\U must"
1053
1057
" be followed by 8 hexadecimal digits"
1054
1058
);
1059
+
return0;
1055
1060
}
1061
+
1056
1062
return0;
1057
1063
};
1058
1064
@@ -1535,6 +1541,7 @@ auto lex_line(
1535
1541
"invalid new-line in raw string delimiter \"" + line.substr(i, 3)
1536
1542
+ "\" - stray 'R' in program \""
1537
1543
);
1544
+
return {};
1538
1545
}
1539
1546
} else {
1540
1547
store(1, lexeme::Dollar);
@@ -1579,6 +1586,7 @@ auto lex_line(
1579
1586
source_position(lineno, i),
1580
1587
"binary literal cannot be empty (0B must be followed by binary digits)"
1581
1588
);
1589
+
return {};
1582
1590
}
1583
1591
}
1584
1592
elseif (peek1 == 'x' || peek1 == 'X') {
@@ -1592,6 +1600,7 @@ auto lex_line(
1592
1600
source_position(lineno, i),
1593
1601
"hexadecimal literal cannot be empty (0X must be followed by hexadecimal digits)"
1594
1602
);
1603
+
return {};
1595
1604
}
1596
1605
}
1597
1606
}
@@ -1658,6 +1667,7 @@ auto lex_line(
1658
1667
source_position(lineno, i),
1659
1668
"a floating point literal must have at least one digit after the decimal point (can be '.0')"
1660
1669
);
1670
+
return {};
1661
1671
}
1662
1672
while (is_separator_or(is_digit,peek(j))) {
1663
1673
++j;
@@ -1725,6 +1735,7 @@ auto lex_line(
1725
1735
"invalid new-line in raw string delimiter \"" + line.substr(i, j)
1726
1736
+ "\" - stray 'R' in program \""
1727
1737
);
1738
+
return {};
1728
1739
}
1729
1740
}
1730
1741
else {
@@ -1783,6 +1794,7 @@ auto lex_line(
1783
1794
"character literal '" + line.substr(i+1, j-1)
1784
1795
+ "' is missing its closing '"
1785
1796
);
1797
+
return {};
1786
1798
}
1787
1799
store(j+1, lexeme::CharacterLiteral);
1788
1800
}
@@ -1791,6 +1803,7 @@ auto lex_line(
1791
1803
source_position(lineno, i),
1792
1804
"character literal is empty"
1793
1805
);
1806
+
return {};
1794
1807
}
1795
1808
}
1796
1809
@@ -1816,18 +1829,21 @@ auto lex_line(
1816
1829
source_position(lineno, i),
1817
1830
"'const_cast' is not supported in Cpp2 - the current C++ best practice is to never cast away const, and that is const_cast's only effective use"
1818
1831
);
1832
+
return {};
1819
1833
}
1820
1834
if (tokens.back() == "static_cast") {
1821
1835
errors.emplace_back(
1822
1836
source_position(lineno, i),
1823
1837
"'static_cast<T>(val)' is not supported in Cpp2 - use 'val as T' for safe conversions instead, or if necessary cpp2::unsafe_narrow<T>(val) for a possibly-lossy narrowing conversion"
1824
1838
);
1839
+
return {};
1825
1840
}
1826
1841
if (tokens.back() == "dynamic_cast") {
1827
1842
errors.emplace_back(
1828
1843
source_position(lineno, i),
1829
1844
"'dynamic_cast<Derived*>(pBase)' is not supported in Cpp2 - use 'pBase as *Derived' for safe dynamic conversions instead"
1830
1845
);
1846
+
return {};
1831
1847
}
1832
1848
}
1833
1849
@@ -1854,12 +1870,14 @@ auto lex_line(
1854
1870
source_position(lineno, i),
1855
1871
"'NULL' is not supported in Cpp2 - for a local pointer variable, leave it uninitialized instead, and set it to a non-null value when you have one"
1856
1872
);
1873
+
return {};
1857
1874
}
1858
1875
if (tokens.back() == "delete") {
1859
1876
errors.emplace_back(
1860
1877
source_position(lineno, i),
1861
1878
"'delete' and owning raw pointers are not supported in Cpp2 - use unique.new<T> or shared.new<T> instead in that order (or, in the future, gc.new<T>, but that is not yet implemented)"
0 commit comments