Skip to content

Commit 797569a

Browse files
committed
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.
1 parent 4b28331 commit 797569a

File tree

7 files changed

+53
-22
lines changed

7 files changed

+53
-22
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
pure2-return-tuple-no-identifier-error.cpp2...
22
pure2-return-tuple-no-identifier-error.cpp2(1,11): error: expected identifier, not 'int'
3-
pure2-return-tuple-no-identifier-error.cpp2(1,16): error: expected identifier, not 'int'
3+
pure2-return-tuple-no-identifier-error.cpp2(1,14): error: missing function return after -> (at ',')
44

Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
pure2-return-tuple-no-type-error.cpp2...
22
pure2-return-tuple-no-type-error.cpp2(1,11): error: return parameter 'a' must have a type
3-
pure2-return-tuple-no-type-error.cpp2(1,14): error: return parameter 'b' must have a type
3+
pure2-return-tuple-no-type-error.cpp2(1,12): error: missing function return after -> (at ',')
44

Diff for: regression-tests/test-results/version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cppfront compiler v0.7.1 Build 9715:1649
2+
cppfront compiler v0.7.1 Build 9716:1345
33
Copyright(c) Herb Sutter All rights reserved
44

55
SPDX-License-Identifier: CC-BY-NC-ND-4.0

Diff for: source/build.info

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"9715:1649"
1+
"9716:1345"

Diff for: source/io.h

+2
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ auto process_cpp2_line(
779779
" after the closing ; or } of a definition, the rest"
780780
" of the line cannot begin a /*...*/ comment")
781781
);
782+
return false;
782783
}
783784
}
784785

@@ -807,6 +808,7 @@ auto process_cpp2_line(
807808
source_position(lineno, unsafe_narrow<colno_t>(ssize(line))),
808809
std::string("line ended before character literal was terminated")
809810
);
811+
return false;
810812
}
811813

812814
return found_end;

Diff for: source/lex.h

+20-1
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,8 @@ auto lex_line(
751751
" short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, _schar, _uchar\n"
752752
" - see also cpp2util.h > \"Convenience names for integer types\""
753753
);
754+
755+
return;
754756
}
755757

756758
tokens.push_back(last_token);
@@ -1002,6 +1004,7 @@ auto lex_line(
10021004
"invalid universal character name - \\u without { must"
10031005
" be followed by 4 hexadecimal digits"
10041006
);
1007+
return 0;
10051008
}
10061009

10071010
else if (
@@ -1022,15 +1025,16 @@ auto lex_line(
10221025

10231026
if (peek(j + offset) == '}') {
10241027
++j;
1028+
return j;
10251029
}
10261030
else {
10271031
errors.emplace_back(
10281032
source_position(lineno, i + offset),
10291033
"invalid universal character name - \\u{ must"
10301034
" be followed by hexadecimal digits and a closing }"
10311035
);
1036+
return 0;
10321037
}
1033-
return j;
10341038
}
10351039

10361040
else if (
@@ -1052,7 +1056,9 @@ auto lex_line(
10521056
"invalid universal character name - \\U must"
10531057
" be followed by 8 hexadecimal digits"
10541058
);
1059+
return 0;
10551060
}
1061+
10561062
return 0;
10571063
};
10581064

@@ -1535,6 +1541,7 @@ auto lex_line(
15351541
"invalid new-line in raw string delimiter \"" + line.substr(i, 3)
15361542
+ "\" - stray 'R' in program \""
15371543
);
1544+
return {};
15381545
}
15391546
} else {
15401547
store(1, lexeme::Dollar);
@@ -1579,6 +1586,7 @@ auto lex_line(
15791586
source_position(lineno, i),
15801587
"binary literal cannot be empty (0B must be followed by binary digits)"
15811588
);
1589+
return {};
15821590
}
15831591
}
15841592
else if (peek1 == 'x' || peek1 == 'X') {
@@ -1592,6 +1600,7 @@ auto lex_line(
15921600
source_position(lineno, i),
15931601
"hexadecimal literal cannot be empty (0X must be followed by hexadecimal digits)"
15941602
);
1603+
return {};
15951604
}
15961605
}
15971606
}
@@ -1658,6 +1667,7 @@ auto lex_line(
16581667
source_position(lineno, i),
16591668
"a floating point literal must have at least one digit after the decimal point (can be '.0')"
16601669
);
1670+
return {};
16611671
}
16621672
while (is_separator_or(is_digit,peek(j))) {
16631673
++j;
@@ -1725,6 +1735,7 @@ auto lex_line(
17251735
"invalid new-line in raw string delimiter \"" + line.substr(i, j)
17261736
+ "\" - stray 'R' in program \""
17271737
);
1738+
return {};
17281739
}
17291740
}
17301741
else {
@@ -1783,6 +1794,7 @@ auto lex_line(
17831794
"character literal '" + line.substr(i+1, j-1)
17841795
+ "' is missing its closing '"
17851796
);
1797+
return {};
17861798
}
17871799
store(j+1, lexeme::CharacterLiteral);
17881800
}
@@ -1791,6 +1803,7 @@ auto lex_line(
17911803
source_position(lineno, i),
17921804
"character literal is empty"
17931805
);
1806+
return {};
17941807
}
17951808
}
17961809

@@ -1816,18 +1829,21 @@ auto lex_line(
18161829
source_position(lineno, i),
18171830
"'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"
18181831
);
1832+
return {};
18191833
}
18201834
if (tokens.back() == "static_cast") {
18211835
errors.emplace_back(
18221836
source_position(lineno, i),
18231837
"'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"
18241838
);
1839+
return {};
18251840
}
18261841
if (tokens.back() == "dynamic_cast") {
18271842
errors.emplace_back(
18281843
source_position(lineno, i),
18291844
"'dynamic_cast<Derived*>(pBase)' is not supported in Cpp2 - use 'pBase as *Derived' for safe dynamic conversions instead"
18301845
);
1846+
return {};
18311847
}
18321848
}
18331849

@@ -1854,12 +1870,14 @@ auto lex_line(
18541870
source_position(lineno, i),
18551871
"'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"
18561872
);
1873+
return {};
18571874
}
18581875
if (tokens.back() == "delete") {
18591876
errors.emplace_back(
18601877
source_position(lineno, i),
18611878
"'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)"
18621879
);
1880+
return {};
18631881
}
18641882
}
18651883
}
@@ -1873,6 +1891,7 @@ auto lex_line(
18731891
false,
18741892
true // a noisy fallback error message
18751893
);
1894+
return {};
18761895
}
18771896
}
18781897
}

0 commit comments

Comments
 (0)