Skip to content

Commit 3b544b3

Browse files
committed
Fix more fuzz crashes.
1 parent ff4134e commit 3b544b3

9 files changed

+58
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#else
2+
#else
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print: <T: type> (inout out: std::ostream=args: T) requires true = {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
main: () = {
2+
e: unsigned char
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mixed-bugfix-for-double-poundelse.cpp2...
2+
mixed-bugfix-for-double-poundelse.cpp2(2,1): error: #else does not match a prior #if
3+
mixed-bugfix-for-double-poundelse.cpp2(3,1): error: #else does not match a prior #if
4+
mixed-bugfix-for-double-poundelse.cpp2(3,1): error: #else already encountered for this #if
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pure2-bugfix-for-bad-parameter.cpp2...
2+
pure2-bugfix-for-bad-parameter.cpp2(1,50): error: parameter must be initialized with an expression (at ')')
3+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
pure2-bugfix-for-naked-unsigned-char.cpp2...
2+
pure2-bugfix-for-naked-unsigned-char.cpp2(2,8): error: 'unsigned char' - did you mean 'u8' (usually best) or 'cpp2::_uchar'?
3+
pure2-bugfix-for-naked-unsigned-char.cpp2(2,8): error: 'unsigned char' is an old-style C/C++ multi-word keyword type
4+
- most such types should be used only for interoperability with older code
5+
- using those when you need them is fine, but name them with these short names instead:
6+
short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, _schar, _uchar
7+
- see also cpp2util.h > "Convenience names for integer types"
8+

source/io.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,11 @@ class braces_tracker
362362
else { --else_net_braces; }
363363
}
364364

365-
auto found_preprocessor_else() -> void {
366-
assert (!found_else);
365+
auto found_preprocessor_else_was_there_another() -> bool {
366+
if (found_else)
367+
return true;
367368
found_else = true;
369+
return false;
368370
}
369371

370372
// If the "if" and "else" branches opened/closed the same net number
@@ -469,7 +471,14 @@ class braces_tracker
469471
);
470472
}
471473

472-
preprocessor.back().found_preprocessor_else();
474+
if (preprocessor.back().found_preprocessor_else_was_there_another()) {
475+
// If this is the second or subsequent #else, it doesn't match
476+
// the prior #if, so report an error
477+
errors.emplace_back(
478+
lineno,
479+
"#else already encountered for this #if"
480+
);
481+
};
473482
}
474483

475484
// Exiting an #endif

source/lex.h

+12-9
Original file line numberDiff line numberDiff line change
@@ -713,13 +713,18 @@ auto lex_line(
713713
tokens.pop_back();
714714
++num_merged_tokens;
715715
}
716-
717-
tokens.push_back({
718-
&generated_text.back()[0],
719-
std::ssize(generated_text.back()),
720-
pos,
721-
lexeme::Keyword
722-
});
716+
717+
// It's an error to have more than one of these, but we require that
718+
// the number of tokens has not gone down. So just push back as many
719+
// tokens as we merged. This will ensure that the token count remains
720+
// the same.
721+
for (auto i = 0; i < num_merged_tokens; i++)
722+
tokens.push_back({
723+
&generated_text.back()[0],
724+
std::ssize(generated_text.back()),
725+
pos,
726+
lexeme::Keyword
727+
});
723728

724729
if (num_merged_tokens > 1)
725730
{
@@ -750,8 +755,6 @@ auto lex_line(
750755
" short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, _schar, _uchar\n"
751756
" - see also cpp2util.h > \"Convenience names for integer types\""
752757
);
753-
754-
return;
755758
}
756759

757760
tokens.push_back(last_token);

source/parse.h

+12
Original file line numberDiff line numberDiff line change
@@ -8684,6 +8684,18 @@ class parser
86848684
}
86858685
}
86868686

8687+
if (
8688+
!is_returns
8689+
&& n->declaration->initializer
8690+
&& !n->declaration->initializer->is_expression()
8691+
)
8692+
{
8693+
// If the initializer is not an expression statement (like a function call),
8694+
// then it can't be used as a parameter.
8695+
error("parameter must be initialized with an expression");
8696+
return {};
8697+
}
8698+
86878699
return n;
86888700
}
86898701

0 commit comments

Comments
 (0)