From f7b3c386717de7be810c70e8a83ecd182a56f1e9 Mon Sep 17 00:00:00 2001 From: Alistair Bell Date: Sat, 29 Mar 2025 08:06:55 -0400 Subject: [PATCH 1/8] Three more fuzz crashes. --- include/cpp2util.h | 3 ++- .../pure2-bugfix-for-assert-capture.cpp2 | 3 +++ .../pure2-bugfix-for-bad-decltype.cpp2 | 4 ++++ regression-tests/pure2-bugfix-for-namespace.cpp2 | 9 +++++++++ .../pure2-bugfix-for-assert-capture.cpp2.output | 4 ++++ .../pure2-bugfix-for-bad-decltype.cpp2.output | 6 ++++++ .../pure2-bugfix-for-namespace.cpp2.output | 3 +++ source/parse.h | 15 +++++++++++++-- 8 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 regression-tests/pure2-bugfix-for-assert-capture.cpp2 create mode 100644 regression-tests/pure2-bugfix-for-bad-decltype.cpp2 create mode 100644 regression-tests/pure2-bugfix-for-namespace.cpp2 create mode 100644 regression-tests/test-results/pure2-bugfix-for-assert-capture.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-bad-decltype.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-namespace.cpp2.output diff --git a/include/cpp2util.h b/include/cpp2util.h index 783138b0b..a5f7e0aab 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -561,7 +561,8 @@ class contract_group { std::cerr << ": " << msg; } std::cerr << "\n"; - std::terminate(); + // Get outta here but don't raise a signal + std::exit(1); } auto inline cpp2_default = contract_group( diff --git a/regression-tests/pure2-bugfix-for-assert-capture.cpp2 b/regression-tests/pure2-bugfix-for-assert-capture.cpp2 new file mode 100644 index 000000000..c35b2d24f --- /dev/null +++ b/regression-tests/pure2-bugfix-for-assert-capture.cpp2 @@ -0,0 +1,3 @@ +crash_10: (foo: i32) = { + assert( 10LL as i32 == foo$); +} diff --git a/regression-tests/pure2-bugfix-for-bad-decltype.cpp2 b/regression-tests/pure2-bugfix-for-bad-decltype.cpp2 new file mode 100644 index 000000000..2b860c447 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-bad-decltype.cpp2 @@ -0,0 +1,4 @@ +crash_89: () = { + f := new(0); + _ = f is decltype.f); +} diff --git a/regression-tests/pure2-bugfix-for-namespace.cpp2 b/regression-tests/pure2-bugfix-for-namespace.cpp2 new file mode 100644 index 000000000..ef4efc8f4 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-namespace.cpp2 @@ -0,0 +1,9 @@ +crash_96: @print type = { + namespace_alias: namespace = type_alias: type == array; +} + +crash_96a: @print type = { + test: () = { + namespace_alias: namespace = type_alias: type == array; + } +} diff --git a/regression-tests/test-results/pure2-bugfix-for-assert-capture.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-assert-capture.cpp2.output new file mode 100644 index 000000000..edf453fa8 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-assert-capture.cpp2.output @@ -0,0 +1,4 @@ +pure2-bugfix-for-assert-capture.cpp2... +pure2-bugfix-for-assert-capture.cpp2(2,29): error: $ (capture) cannot appear here - it must appear in an anonymous expression function, a postcondition, or an interpolated string literal (at '$') +pure2-bugfix-for-assert-capture.cpp2(2,23): error: expected ')' at the end of the contract (at '==') + diff --git a/regression-tests/test-results/pure2-bugfix-for-bad-decltype.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-bad-decltype.cpp2.output new file mode 100644 index 000000000..0685b6d73 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-bad-decltype.cpp2.output @@ -0,0 +1,6 @@ +pure2-bugfix-for-bad-decltype.cpp2... +pure2-bugfix-for-bad-decltype.cpp2(3,14): error: 'decltype' must be followed by a single parenthesized expression +pure2-bugfix-for-bad-decltype.cpp2(3,24): error: 'is' must be followed by a type-id or an expression +pure2-bugfix-for-bad-decltype.cpp2(3,14): error: 'decltype' must be followed by a single parenthesized expression +pure2-bugfix-for-bad-decltype.cpp2(3,24): error: 'is' must be followed by a type-id or an expression + diff --git a/regression-tests/test-results/pure2-bugfix-for-namespace.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-namespace.cpp2.output new file mode 100644 index 000000000..8e6b13daa --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-namespace.cpp2.output @@ -0,0 +1,3 @@ +pure2-bugfix-for-namespace.cpp2... +pure2-bugfix-for-namespace.cpp2(2,22): error: types cannot contain namespaces (at 'namespace') + diff --git a/source/parse.h b/source/parse.h index 9c80447bf..a59a9d164 100644 --- a/source/parse.h +++ b/source/parse.h @@ -5956,7 +5956,7 @@ auto pretty_print_visualize( + initializer; } else if (n.is_namespace()) { - auto& t = std::get(n.type); + auto& t = std::get(n.type); assert(t); ret += "namespace = " + initializer; @@ -7253,6 +7253,7 @@ class parser if (auto id = postfix_expression(); id && id->ops.size() == 1 + && id->ops[0].expr_list && id->ops[0].expr_list->expressions.size() == 1 && id->ops[0].expr_list->open_paren->type() == lexeme::LeftParen ) @@ -8805,7 +8806,6 @@ class parser -> std::unique_ptr { auto n = std::make_unique(curr().position()); - auto guard = capture_groups_stack_guard(this, &n->captures); if ( curr() != "pre" @@ -8816,6 +8816,13 @@ class parser return {}; } n->kind = &curr(); + + auto guard = + curr() == "post" + ? std::make_unique(this, &n->captures) + : std::unique_ptr() + ; + next(); // Check if there's a @@ -9292,6 +9299,10 @@ class parser // Or a namespace else if (curr() == "namespace") { + if (n->parent_is_type()) { + error("types cannot contain namespaces"); + return {}; + } n->type = std::make_unique( &curr() ); assert (n->type.index() == declaration_node::a_namespace); next(); From 2407a224111170ffc016ae58fe3d678dd236f5d7 Mon Sep 17 00:00:00 2001 From: Alistair Bell Date: Sat, 29 Mar 2025 09:44:38 -0400 Subject: [PATCH 2/8] Add regression test for crash 10. --- regression-tests/pure2-bugfix-for-bad-capture.cpp2 | 3 +++ .../test-results/pure2-bugfix-for-bad-capture.cpp2.output | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 regression-tests/pure2-bugfix-for-bad-capture.cpp2 create mode 100644 regression-tests/test-results/pure2-bugfix-for-bad-capture.cpp2.output diff --git a/regression-tests/pure2-bugfix-for-bad-capture.cpp2 b/regression-tests/pure2-bugfix-for-bad-capture.cpp2 new file mode 100644 index 000000000..c35b2d24f --- /dev/null +++ b/regression-tests/pure2-bugfix-for-bad-capture.cpp2 @@ -0,0 +1,3 @@ +crash_10: (foo: i32) = { + assert( 10LL as i32 == foo$); +} diff --git a/regression-tests/test-results/pure2-bugfix-for-bad-capture.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-bad-capture.cpp2.output new file mode 100644 index 000000000..cc4c11f84 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-bad-capture.cpp2.output @@ -0,0 +1,4 @@ +pure2-bugfix-for-bad-capture.cpp2... +pure2-bugfix-for-bad-capture.cpp2(2,29): error: $ (capture) cannot appear here - it must appear in an anonymous expression function, a postcondition, or an interpolated string literal (at '$') +pure2-bugfix-for-bad-capture.cpp2(2,23): error: expected ')' at the end of the contract (at '==') + From 9440687822f2621289f2e843265a7baf292b8821 Mon Sep 17 00:00:00 2001 From: Alistair Bell Date: Sat, 29 Mar 2025 11:37:08 -0400 Subject: [PATCH 3/8] Error instead of crash if users write silly things in aliases. --- regression-tests/pure2-bugfix-for-invalid-alias.cpp2 | 3 +++ .../pure2-bugfix-for-invalid-alias.cpp2.output | 3 +++ source/parse.h | 9 ++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 regression-tests/pure2-bugfix-for-invalid-alias.cpp2 create mode 100644 regression-tests/test-results/pure2-bugfix-for-invalid-alias.cpp2.output diff --git a/regression-tests/pure2-bugfix-for-invalid-alias.cpp2 b/regression-tests/pure2-bugfix-for-invalid-alias.cpp2 new file mode 100644 index 000000000..352efff49 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-invalid-alias.cpp2 @@ -0,0 +1,3 @@ +outer: type = { + x: requires true == 42; +} diff --git a/regression-tests/test-results/pure2-bugfix-for-invalid-alias.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-invalid-alias.cpp2.output new file mode 100644 index 000000000..96f281bf0 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-invalid-alias.cpp2.output @@ -0,0 +1,3 @@ +pure2-bugfix-for-invalid-alias.cpp2... +pure2-bugfix-for-invalid-alias.cpp2(2,25): error: invalid alias declaration - expected 'type', 'namespace', or a type-id after ':' + diff --git a/source/parse.h b/source/parse.h index a59a9d164..7150f1946 100644 --- a/source/parse.h +++ b/source/parse.h @@ -9835,10 +9835,13 @@ class parser a->initializer = std::move(e); } - // Anything else shouldn't be possible + // Anything else is illegal else { - assert(false && "ICE: should be unreachable - invalid alias declaration"); - return {}; + errors.emplace_back( + curr().position(), + "invalid alias declaration - expected 'type', 'namespace', or a type-id after ':'" + ); + return {}; } // And the final ceremonial semicolon From 5d3e3246f0e5b1f2e617f5617d88a7cf3bd8dc0e Mon Sep 17 00:00:00 2001 From: Alistair Bell Date: Sat, 29 Mar 2025 18:28:44 -0400 Subject: [PATCH 4/8] Fix assertion on comments near end of file. --- .../pure2-bugfix-for-late-comments.cpp2 | 11 +++++ .../pure2-bugfix-for-late-comments.cpp | 47 +++++++++++++++++++ ...pure2-bugfix-for-late-comments.cpp2.output | 2 + source/to_cpp1.h | 12 +++-- 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 regression-tests/pure2-bugfix-for-late-comments.cpp2 create mode 100644 regression-tests/test-results/pure2-bugfix-for-late-comments.cpp create mode 100644 regression-tests/test-results/pure2-bugfix-for-late-comments.cpp2.output diff --git a/regression-tests/pure2-bugfix-for-late-comments.cpp2 b/regression-tests/pure2-bugfix-for-late-comments.cpp2 new file mode 100644 index 000000000..97235edde --- /dev/null +++ b/regression-tests/pure2-bugfix-for-late-comments.cpp2 @@ -0,0 +1,11 @@ + +main: () -> int = { + x := crash_m0(); + _ = x; +} + +crash_m0: type = { + operator-: (this, _) -> int = 0;/* Comment starts here +And continues here +*/ +} diff --git a/regression-tests/test-results/pure2-bugfix-for-late-comments.cpp b/regression-tests/test-results/pure2-bugfix-for-late-comments.cpp new file mode 100644 index 000000000..2bc53bab1 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-late-comments.cpp @@ -0,0 +1,47 @@ + +#define CPP2_IMPORT_STD Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-bugfix-for-late-comments.cpp2" + +#line 7 "pure2-bugfix-for-late-comments.cpp2" +class crash_m0; + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-bugfix-for-late-comments.cpp2" + +#line 2 "pure2-bugfix-for-late-comments.cpp2" +[[nodiscard]] auto main() -> int; + +#line 7 "pure2-bugfix-for-late-comments.cpp2" +class crash_m0 { + public: [[nodiscard]] auto operator-([[maybe_unused]] auto const& unnamed_param_2) const& -> int; + public: crash_m0() = default; + public: crash_m0(crash_m0 const&) = delete; /* No 'that' constructor, suppress copy */ + public: auto operator=(crash_m0 const&) -> void = delete; + + +#line 11 "pure2-bugfix-for-late-comments.cpp2" +}; + + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-bugfix-for-late-comments.cpp2" + +#line 2 "pure2-bugfix-for-late-comments.cpp2" +[[nodiscard]] auto main() -> int{ + auto x {crash_m0()}; + static_cast(cpp2::move(x)); +} + +#line 8 "pure2-bugfix-for-late-comments.cpp2" + [[nodiscard]] auto crash_m0::operator-([[maybe_unused]] auto const& unnamed_param_2) const& -> int { return 0; }/* Comment starts here +And continues here +*/ diff --git a/regression-tests/test-results/pure2-bugfix-for-late-comments.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-late-comments.cpp2.output new file mode 100644 index 000000000..a44b6fa85 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-late-comments.cpp2.output @@ -0,0 +1,2 @@ +pure2-bugfix-for-late-comments.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/source/to_cpp1.h b/source/to_cpp1.h index a6c08f60f..cff6a92dd 100644 --- a/source/to_cpp1.h +++ b/source/to_cpp1.h @@ -432,7 +432,7 @@ class positional_printer c.dbg_was_printed = true; } - auto flush_comments( source_position pos ) + auto flush_comments( source_position pos, bool print_remaining_comments = false ) -> void { if (!pcomments) { @@ -444,7 +444,7 @@ class positional_printer // Add unprinted comments and blank lines as needed to catch up vertically // - while (curr_pos.lineno < pos.lineno) + while (print_remaining_comments ? (next_comment < std::ssize(comments)) : (curr_pos.lineno < pos.lineno)) { // If a comment goes on this line, print it if ( @@ -468,7 +468,8 @@ class positional_printer ) { print_comment( comments[next_comment] ); - assert(curr_pos.lineno <= pos.lineno); // we shouldn't have overshot + if (!print_remaining_comments) + assert(curr_pos.lineno <= pos.lineno); // we shouldn't have overshot } ++next_comment; @@ -479,6 +480,9 @@ class positional_printer print("\n"); } } + // And catch up. + while (curr_pos.lineno < pos.lineno) + print("\n"); } auto print_unprinted_comments() @@ -589,7 +593,7 @@ class positional_printer && psource->has_cpp2() ) { - flush_comments( {curr_pos.lineno+1, 1} ); + flush_comments( {curr_pos.lineno+1, 1}, print_remaining_comments ); if (print_remaining_comments) { print_unprinted_comments(); From ff4134ef627afbf599b3b0043b4d352379f9fc38 Mon Sep 17 00:00:00 2001 From: Alistair Bell Date: Sat, 29 Mar 2025 18:31:38 -0400 Subject: [PATCH 5/8] Disallow declarations of parents after functions. --- ...fix-for-functions-before-superclasses.cpp2 | 8 ++++++++ ...-functions-before-superclasses.cpp2.output | 3 +++ source/sema.h | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 regression-tests/pure2-bugfix-for-functions-before-superclasses.cpp2 create mode 100644 regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses.cpp2.output diff --git a/regression-tests/pure2-bugfix-for-functions-before-superclasses.cpp2 b/regression-tests/pure2-bugfix-for-functions-before-superclasses.cpp2 new file mode 100644 index 000000000..e368600ba --- /dev/null +++ b/regression-tests/pure2-bugfix-for-functions-before-superclasses.cpp2 @@ -0,0 +1,8 @@ +crash_m0b: type = { +} + +crash_m0c: type = { + name: i32; + get_name: (this) -> i32 = { return name; } + this: crash_m0b; +} diff --git a/regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses.cpp2.output new file mode 100644 index 000000000..833bce07e --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses.cpp2.output @@ -0,0 +1,3 @@ +pure2-bugfix-for-functions-before-superclasses.cpp2... +pure2-bugfix-for-functions-before-superclasses.cpp2(7,3): error: a type cannot declare a parent after defining a function + diff --git a/source/sema.h b/source/sema.h index 424261a69..e615c0949 100644 --- a/source/sema.h +++ b/source/sema.h @@ -2037,6 +2037,7 @@ class sema if (n.is_type()) { auto compound_stmt = n.initializer->get_if(); assert (compound_stmt); + bool seen_function = false; for (auto& stmt : compound_stmt->statements) { if ( !stmt->is_declaration() @@ -2049,6 +2050,24 @@ class sema ); return false; } + auto stmt_decl = stmt->get_if(); + // If this is a declaration, check if it's a function + if (stmt_decl && stmt_decl->is_function()) + seen_function = true; + + // If this is called 'this', then make sure we haven't seen any functions + if ( + stmt_decl + && stmt_decl->has_name("this") + && seen_function + ) + { + handle_error( + stmt->position(), + "a type cannot declare a parent after defining a function" + ); + return false; + } } } From 3b544b3ab6da960717dd9f412b555a9f9981fe20 Mon Sep 17 00:00:00 2001 From: Alistair Bell Date: Sun, 30 Mar 2025 19:29:11 -0400 Subject: [PATCH 6/8] Fix more fuzz crashes. --- .../mixed-bugfix-for-double-poundelse.cpp2 | 2 ++ .../pure2-bugfix-for-bad-parameter.cpp2 | 1 + .../pure2-bugfix-for-naked-unsigned-char.cpp2 | 3 +++ ...ed-bugfix-for-double-poundelse.cpp2.output | 5 +++++ ...pure2-bugfix-for-bad-parameter.cpp2.output | 3 +++ ...bugfix-for-naked-unsigned-char.cpp2.output | 8 +++++++ source/io.h | 15 ++++++++++--- source/lex.h | 21 +++++++++++-------- source/parse.h | 12 +++++++++++ 9 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 regression-tests/mixed-bugfix-for-double-poundelse.cpp2 create mode 100644 regression-tests/pure2-bugfix-for-bad-parameter.cpp2 create mode 100644 regression-tests/pure2-bugfix-for-naked-unsigned-char.cpp2 create mode 100644 regression-tests/test-results/mixed-bugfix-for-double-poundelse.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-bad-parameter.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char.cpp2.output diff --git a/regression-tests/mixed-bugfix-for-double-poundelse.cpp2 b/regression-tests/mixed-bugfix-for-double-poundelse.cpp2 new file mode 100644 index 000000000..5d825c172 --- /dev/null +++ b/regression-tests/mixed-bugfix-for-double-poundelse.cpp2 @@ -0,0 +1,2 @@ +#else +#else diff --git a/regression-tests/pure2-bugfix-for-bad-parameter.cpp2 b/regression-tests/pure2-bugfix-for-bad-parameter.cpp2 new file mode 100644 index 000000000..68198c544 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-bad-parameter.cpp2 @@ -0,0 +1 @@ +print: (inout out: std::ostream=args: T) requires true = {} diff --git a/regression-tests/pure2-bugfix-for-naked-unsigned-char.cpp2 b/regression-tests/pure2-bugfix-for-naked-unsigned-char.cpp2 new file mode 100644 index 000000000..1458076d2 --- /dev/null +++ b/regression-tests/pure2-bugfix-for-naked-unsigned-char.cpp2 @@ -0,0 +1,3 @@ +main: () = { + e: unsigned char +} diff --git a/regression-tests/test-results/mixed-bugfix-for-double-poundelse.cpp2.output b/regression-tests/test-results/mixed-bugfix-for-double-poundelse.cpp2.output new file mode 100644 index 000000000..bebfaa7ce --- /dev/null +++ b/regression-tests/test-results/mixed-bugfix-for-double-poundelse.cpp2.output @@ -0,0 +1,5 @@ +mixed-bugfix-for-double-poundelse.cpp2... +mixed-bugfix-for-double-poundelse.cpp2(2,1): error: #else does not match a prior #if +mixed-bugfix-for-double-poundelse.cpp2(3,1): error: #else does not match a prior #if +mixed-bugfix-for-double-poundelse.cpp2(3,1): error: #else already encountered for this #if + diff --git a/regression-tests/test-results/pure2-bugfix-for-bad-parameter.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-bad-parameter.cpp2.output new file mode 100644 index 000000000..d435bd7b6 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-bad-parameter.cpp2.output @@ -0,0 +1,3 @@ +pure2-bugfix-for-bad-parameter.cpp2... +pure2-bugfix-for-bad-parameter.cpp2(1,50): error: parameter must be initialized with an expression (at ')') + diff --git a/regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char.cpp2.output new file mode 100644 index 000000000..01b912d76 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char.cpp2.output @@ -0,0 +1,8 @@ +pure2-bugfix-for-naked-unsigned-char.cpp2... +pure2-bugfix-for-naked-unsigned-char.cpp2(2,8): error: 'unsigned char' - did you mean 'u8' (usually best) or 'cpp2::_uchar'? +pure2-bugfix-for-naked-unsigned-char.cpp2(2,8): error: 'unsigned char' is an old-style C/C++ multi-word keyword type + - most such types should be used only for interoperability with older code + - using those when you need them is fine, but name them with these short names instead: + short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, _schar, _uchar + - see also cpp2util.h > "Convenience names for integer types" + diff --git a/source/io.h b/source/io.h index f950c52a9..ba7106942 100644 --- a/source/io.h +++ b/source/io.h @@ -362,9 +362,11 @@ class braces_tracker else { --else_net_braces; } } - auto found_preprocessor_else() -> void { - assert (!found_else); + auto found_preprocessor_else_was_there_another() -> bool { + if (found_else) + return true; found_else = true; + return false; } // If the "if" and "else" branches opened/closed the same net number @@ -469,7 +471,14 @@ class braces_tracker ); } - preprocessor.back().found_preprocessor_else(); + if (preprocessor.back().found_preprocessor_else_was_there_another()) { + // If this is the second or subsequent #else, it doesn't match + // the prior #if, so report an error + errors.emplace_back( + lineno, + "#else already encountered for this #if" + ); + }; } // Exiting an #endif diff --git a/source/lex.h b/source/lex.h index 8dce93406..8bd5acffa 100644 --- a/source/lex.h +++ b/source/lex.h @@ -713,13 +713,18 @@ auto lex_line( tokens.pop_back(); ++num_merged_tokens; } - - tokens.push_back({ - &generated_text.back()[0], - std::ssize(generated_text.back()), - pos, - lexeme::Keyword - }); + + // It's an error to have more than one of these, but we require that + // the number of tokens has not gone down. So just push back as many + // tokens as we merged. This will ensure that the token count remains + // the same. + for (auto i = 0; i < num_merged_tokens; i++) + tokens.push_back({ + &generated_text.back()[0], + std::ssize(generated_text.back()), + pos, + lexeme::Keyword + }); if (num_merged_tokens > 1) { @@ -750,8 +755,6 @@ auto lex_line( " short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, _schar, _uchar\n" " - see also cpp2util.h > \"Convenience names for integer types\"" ); - - return; } tokens.push_back(last_token); diff --git a/source/parse.h b/source/parse.h index 7150f1946..7987af007 100644 --- a/source/parse.h +++ b/source/parse.h @@ -8684,6 +8684,18 @@ class parser } } + if ( + !is_returns + && n->declaration->initializer + && !n->declaration->initializer->is_expression() + ) + { + // If the initializer is not an expression statement (like a function call), + // then it can't be used as a parameter. + error("parameter must be initialized with an expression"); + return {}; + } + return n; } From 032cb733629caaca987a540d5bd2ce582dd88730 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Mon, 28 Apr 2025 18:45:13 -1000 Subject: [PATCH 7/8] Rename error test cases to `*-error.cpp2` --- ...d-bugfix-for-double-pound-else-error.cpp2} | 0 ...ure2-bugfix-for-assert-capture-error.cpp2} | 0 ...> pure2-bugfix-for-bad-capture-error.cpp2} | 0 ... pure2-bugfix-for-bad-decltype-error.cpp2} | 0 ...pure2-bugfix-for-bad-parameter-error.cpp2} | 0 ...-functions-before-superclasses-error.cpp2} | 0 ...pure2-bugfix-for-invalid-alias-error.cpp2} | 0 ...bugfix-for-naked-unsigned-char-error.cpp2} | 0 ... => pure2-bugfix-for-namespace-error.cpp2} | 0 .../pure2-expected-is-as.cpp.output | 38 +++++++++---------- ...ix-for-double-pound-else-error.cpp2.output | 5 +++ ...ed-bugfix-for-double-poundelse.cpp2.output | 5 --- .../pure2-bugfix-for-late-comments.cpp.output | 1 + ...ugfix-for-assert-capture-error.cpp2.output | 4 ++ ...ure2-bugfix-for-assert-capture.cpp2.output | 4 -- ...2-bugfix-for-bad-capture-error.cpp2.output | 4 ++ .../pure2-bugfix-for-bad-capture.cpp2.output | 4 -- ...-bugfix-for-bad-decltype-error.cpp2.output | 6 +++ .../pure2-bugfix-for-bad-decltype.cpp2.output | 6 --- ...bugfix-for-bad-parameter-error.cpp2.output | 3 ++ ...pure2-bugfix-for-bad-parameter.cpp2.output | 3 -- ...ions-before-superclasses-error.cpp2.output | 3 ++ ...-functions-before-superclasses.cpp2.output | 3 -- ...bugfix-for-invalid-alias-error.cpp2.output | 3 ++ ...pure2-bugfix-for-invalid-alias.cpp2.output | 3 -- ...for-naked-unsigned-char-error.cpp2.output} | 6 +-- ...re2-bugfix-for-namespace-error.cpp2.output | 3 ++ .../pure2-bugfix-for-namespace.cpp2.output | 3 -- 28 files changed, 54 insertions(+), 53 deletions(-) rename regression-tests/{mixed-bugfix-for-double-poundelse.cpp2 => mixed-bugfix-for-double-pound-else-error.cpp2} (100%) rename regression-tests/{pure2-bugfix-for-assert-capture.cpp2 => pure2-bugfix-for-assert-capture-error.cpp2} (100%) rename regression-tests/{pure2-bugfix-for-bad-capture.cpp2 => pure2-bugfix-for-bad-capture-error.cpp2} (100%) rename regression-tests/{pure2-bugfix-for-bad-decltype.cpp2 => pure2-bugfix-for-bad-decltype-error.cpp2} (100%) rename regression-tests/{pure2-bugfix-for-bad-parameter.cpp2 => pure2-bugfix-for-bad-parameter-error.cpp2} (100%) rename regression-tests/{pure2-bugfix-for-functions-before-superclasses.cpp2 => pure2-bugfix-for-functions-before-superclasses-error.cpp2} (100%) rename regression-tests/{pure2-bugfix-for-invalid-alias.cpp2 => pure2-bugfix-for-invalid-alias-error.cpp2} (100%) rename regression-tests/{pure2-bugfix-for-naked-unsigned-char.cpp2 => pure2-bugfix-for-naked-unsigned-char-error.cpp2} (100%) rename regression-tests/{pure2-bugfix-for-namespace.cpp2 => pure2-bugfix-for-namespace-error.cpp2} (100%) create mode 100644 regression-tests/test-results/mixed-bugfix-for-double-pound-else-error.cpp2.output delete mode 100644 regression-tests/test-results/mixed-bugfix-for-double-poundelse.cpp2.output create mode 100644 regression-tests/test-results/msvc-2022-c++latest/pure2-bugfix-for-late-comments.cpp.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-assert-capture-error.cpp2.output delete mode 100644 regression-tests/test-results/pure2-bugfix-for-assert-capture.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-bad-capture-error.cpp2.output delete mode 100644 regression-tests/test-results/pure2-bugfix-for-bad-capture.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-bad-decltype-error.cpp2.output delete mode 100644 regression-tests/test-results/pure2-bugfix-for-bad-decltype.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-bad-parameter-error.cpp2.output delete mode 100644 regression-tests/test-results/pure2-bugfix-for-bad-parameter.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses-error.cpp2.output delete mode 100644 regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses.cpp2.output create mode 100644 regression-tests/test-results/pure2-bugfix-for-invalid-alias-error.cpp2.output delete mode 100644 regression-tests/test-results/pure2-bugfix-for-invalid-alias.cpp2.output rename regression-tests/test-results/{pure2-bugfix-for-naked-unsigned-char.cpp2.output => pure2-bugfix-for-naked-unsigned-char-error.cpp2.output} (52%) create mode 100644 regression-tests/test-results/pure2-bugfix-for-namespace-error.cpp2.output delete mode 100644 regression-tests/test-results/pure2-bugfix-for-namespace.cpp2.output diff --git a/regression-tests/mixed-bugfix-for-double-poundelse.cpp2 b/regression-tests/mixed-bugfix-for-double-pound-else-error.cpp2 similarity index 100% rename from regression-tests/mixed-bugfix-for-double-poundelse.cpp2 rename to regression-tests/mixed-bugfix-for-double-pound-else-error.cpp2 diff --git a/regression-tests/pure2-bugfix-for-assert-capture.cpp2 b/regression-tests/pure2-bugfix-for-assert-capture-error.cpp2 similarity index 100% rename from regression-tests/pure2-bugfix-for-assert-capture.cpp2 rename to regression-tests/pure2-bugfix-for-assert-capture-error.cpp2 diff --git a/regression-tests/pure2-bugfix-for-bad-capture.cpp2 b/regression-tests/pure2-bugfix-for-bad-capture-error.cpp2 similarity index 100% rename from regression-tests/pure2-bugfix-for-bad-capture.cpp2 rename to regression-tests/pure2-bugfix-for-bad-capture-error.cpp2 diff --git a/regression-tests/pure2-bugfix-for-bad-decltype.cpp2 b/regression-tests/pure2-bugfix-for-bad-decltype-error.cpp2 similarity index 100% rename from regression-tests/pure2-bugfix-for-bad-decltype.cpp2 rename to regression-tests/pure2-bugfix-for-bad-decltype-error.cpp2 diff --git a/regression-tests/pure2-bugfix-for-bad-parameter.cpp2 b/regression-tests/pure2-bugfix-for-bad-parameter-error.cpp2 similarity index 100% rename from regression-tests/pure2-bugfix-for-bad-parameter.cpp2 rename to regression-tests/pure2-bugfix-for-bad-parameter-error.cpp2 diff --git a/regression-tests/pure2-bugfix-for-functions-before-superclasses.cpp2 b/regression-tests/pure2-bugfix-for-functions-before-superclasses-error.cpp2 similarity index 100% rename from regression-tests/pure2-bugfix-for-functions-before-superclasses.cpp2 rename to regression-tests/pure2-bugfix-for-functions-before-superclasses-error.cpp2 diff --git a/regression-tests/pure2-bugfix-for-invalid-alias.cpp2 b/regression-tests/pure2-bugfix-for-invalid-alias-error.cpp2 similarity index 100% rename from regression-tests/pure2-bugfix-for-invalid-alias.cpp2 rename to regression-tests/pure2-bugfix-for-invalid-alias-error.cpp2 diff --git a/regression-tests/pure2-bugfix-for-naked-unsigned-char.cpp2 b/regression-tests/pure2-bugfix-for-naked-unsigned-char-error.cpp2 similarity index 100% rename from regression-tests/pure2-bugfix-for-naked-unsigned-char.cpp2 rename to regression-tests/pure2-bugfix-for-naked-unsigned-char-error.cpp2 diff --git a/regression-tests/pure2-bugfix-for-namespace.cpp2 b/regression-tests/pure2-bugfix-for-namespace-error.cpp2 similarity index 100% rename from regression-tests/pure2-bugfix-for-namespace.cpp2 rename to regression-tests/pure2-bugfix-for-namespace-error.cpp2 diff --git a/regression-tests/test-results/clang-12-c++20/pure2-expected-is-as.cpp.output b/regression-tests/test-results/clang-12-c++20/pure2-expected-is-as.cpp.output index 3097b419d..231ad619d 100644 --- a/regression-tests/test-results/clang-12-c++20/pure2-expected-is-as.cpp.output +++ b/regression-tests/test-results/clang-12-c++20/pure2-expected-is-as.cpp.output @@ -80,56 +80,56 @@ In file included from pure2-expected-is-as.cpp:7: ../../../include/cpp2util.h:469:72: error: invalid application of 'sizeof' to a function type (std::is_floating_point_v && std::is_floating_point_v && sizeof(From) > sizeof(To)) || // NOLINT(misc-redundant-expression) ^~~~~~~~~~~~ -../../../include/cpp2util.h:2923:19: note: in instantiation of variable template specialization 'cpp2::impl::is_narrowing_v' requested here +../../../include/cpp2util.h:2924:19: note: in instantiation of variable template specialization 'cpp2::impl::is_narrowing_v' requested here if constexpr (is_narrowing_v) { ^ pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_' requested here auto val1 {cpp2::impl::as_(ex1)}; ^ In file included from pure2-expected-is-as.cpp:7: -../../../include/cpp2util.h:2943:12: error: no matching function for call to 'as' +../../../include/cpp2util.h:2944:12: error: no matching function for call to 'as' return as(CPP2_FORWARD(x)); ^~~~~ pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_' requested here auto val1 {cpp2::impl::as_(ex1)}; ^ -../../../include/cpp2util.h:1901:16: note: candidate template ignored: constraints not satisfied [with C = int, x:auto = double (&)(double) noexcept] +../../../include/cpp2util.h:1902:16: note: candidate template ignored: constraints not satisfied [with C = int, x:auto = double (&)(double) noexcept] constexpr auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) ^ -../../../include/cpp2util.h:1907:18: note: because 'std::is_scalar_v >' evaluated to false +../../../include/cpp2util.h:1908:18: note: because 'std::is_scalar_v >' evaluated to false (std::is_scalar_v && !std::is_enum_v) ^ -../../../include/cpp2util.h:1908:17: note: and 'std::is_floating_point_v >' evaluated to false +../../../include/cpp2util.h:1909:17: note: and 'std::is_floating_point_v >' evaluated to false || std::is_floating_point_v ^ -../../../include/cpp2util.h:1909:17: note: and 'std::is_base_of_v >' evaluated to false +../../../include/cpp2util.h:1910:17: note: and 'std::is_base_of_v >' evaluated to false || std::is_base_of_v ^ -../../../include/cpp2util.h:1910:17: note: and 'std::is_base_of_v, int>' evaluated to false +../../../include/cpp2util.h:1911:17: note: and 'std::is_base_of_v, int>' evaluated to false || std::is_base_of_v ^ -../../../include/cpp2util.h:1911:30: note: and 'C({std::forward(x)})' would be invalid: cannot initialize a value of type 'int' with an lvalue of type 'double (double) noexcept' +../../../include/cpp2util.h:1912:30: note: and 'C({std::forward(x)})' would be invalid: cannot initialize a value of type 'int' with an lvalue of type 'double (double) noexcept' || requires { C{CPP2_FORWARD(x)}; } ^ ../../../include/cpp2util.h:327:37: note: expanded from macro 'CPP2_FORWARD' #define CPP2_FORWARD(x) std::forward(x) ^ -../../../include/cpp2util.h:2040:6: note: candidate template ignored: constraints not satisfied [with C = int, X = double (&)(double) noexcept] +../../../include/cpp2util.h:2041:6: note: candidate template ignored: constraints not satisfied [with C = int, X = double (&)(double) noexcept] auto as(X&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto) ^ -../../../include/cpp2util.h:2039:23: note: because 'specialization_of_template' evaluated to false +../../../include/cpp2util.h:2040:23: note: because 'specialization_of_template' evaluated to false template< typename C, specialization_of_template X > ^ -../../../include/cpp2util.h:891:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' +../../../include/cpp2util.h:892:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' { specialization_of_template_helper(std::forward(x)) } -> std::same_as; ^ -../../../include/cpp2util.h:2087:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] +../../../include/cpp2util.h:2088:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] constexpr auto as( X && x ) -> decltype(auto) { ^ -../../../include/cpp2util.h:2086:22: note: because 'same_type_as' evaluated to false +../../../include/cpp2util.h:2087:22: note: because 'same_type_as' evaluated to false template X> ^ -../../../include/cpp2util.h:921:29: note: because 'std::same_as, std::remove_cvref_t >' evaluated to false +../../../include/cpp2util.h:922:29: note: because 'std::same_as, std::remove_cvref_t >' evaluated to false concept same_type_as = std::same_as, std::remove_cvref_t>; ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/concepts:63:19: note: because '__detail::__same_as' evaluated to false @@ -138,19 +138,19 @@ concept same_type_as = std::same_as, std::remove_cvref_t< /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/concepts:57:27: note: because 'std::is_same_v' evaluated to false concept __same_as = std::is_same_v<_Tp, _Up>; ^ -../../../include/cpp2util.h:2130:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] +../../../include/cpp2util.h:2131:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept] constexpr auto as( X&& x ) -> decltype(auto) { ^ -../../../include/cpp2util.h:2129:22: note: because 'specialization_of_template' evaluated to false +../../../include/cpp2util.h:2130:22: note: because 'specialization_of_template' evaluated to false template X> ^ -../../../include/cpp2util.h:891:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' +../../../include/cpp2util.h:892:7: note: because 'specialization_of_template_helper(std::forward(x))' would be invalid: no matching function for call to 'specialization_of_template_helper' { specialization_of_template_helper(std::forward(x)) } -> std::same_as; ^ -../../../include/cpp2util.h:1876:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided +../../../include/cpp2util.h:1877:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided constexpr auto as() -> auto ^ -../../../include/cpp2util.h:1887:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided +../../../include/cpp2util.h:1888:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided constexpr auto as() -> auto ^ pure2-expected-is-as.cpp2:39:37: error: use of undeclared identifier 'ex1' diff --git a/regression-tests/test-results/mixed-bugfix-for-double-pound-else-error.cpp2.output b/regression-tests/test-results/mixed-bugfix-for-double-pound-else-error.cpp2.output new file mode 100644 index 000000000..43daeb69f --- /dev/null +++ b/regression-tests/test-results/mixed-bugfix-for-double-pound-else-error.cpp2.output @@ -0,0 +1,5 @@ +mixed-bugfix-for-double-pound-else-error.cpp2... +mixed-bugfix-for-double-pound-else-error.cpp2(2,1): error: #else does not match a prior #if +mixed-bugfix-for-double-pound-else-error.cpp2(3,1): error: #else does not match a prior #if +mixed-bugfix-for-double-pound-else-error.cpp2(3,1): error: #else already encountered for this #if + diff --git a/regression-tests/test-results/mixed-bugfix-for-double-poundelse.cpp2.output b/regression-tests/test-results/mixed-bugfix-for-double-poundelse.cpp2.output deleted file mode 100644 index bebfaa7ce..000000000 --- a/regression-tests/test-results/mixed-bugfix-for-double-poundelse.cpp2.output +++ /dev/null @@ -1,5 +0,0 @@ -mixed-bugfix-for-double-poundelse.cpp2... -mixed-bugfix-for-double-poundelse.cpp2(2,1): error: #else does not match a prior #if -mixed-bugfix-for-double-poundelse.cpp2(3,1): error: #else does not match a prior #if -mixed-bugfix-for-double-poundelse.cpp2(3,1): error: #else already encountered for this #if - diff --git a/regression-tests/test-results/msvc-2022-c++latest/pure2-bugfix-for-late-comments.cpp.output b/regression-tests/test-results/msvc-2022-c++latest/pure2-bugfix-for-late-comments.cpp.output new file mode 100644 index 000000000..f6608912d --- /dev/null +++ b/regression-tests/test-results/msvc-2022-c++latest/pure2-bugfix-for-late-comments.cpp.output @@ -0,0 +1 @@ +pure2-bugfix-for-late-comments.cpp diff --git a/regression-tests/test-results/pure2-bugfix-for-assert-capture-error.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-assert-capture-error.cpp2.output new file mode 100644 index 000000000..cf29d86b6 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-assert-capture-error.cpp2.output @@ -0,0 +1,4 @@ +pure2-bugfix-for-assert-capture-error.cpp2... +pure2-bugfix-for-assert-capture-error.cpp2(2,29): error: $ (capture) cannot appear here - it must appear in an anonymous expression function, a postcondition, or an interpolated string literal (at '$') +pure2-bugfix-for-assert-capture-error.cpp2(2,23): error: expected ')' at the end of the contract (at '==') + diff --git a/regression-tests/test-results/pure2-bugfix-for-assert-capture.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-assert-capture.cpp2.output deleted file mode 100644 index edf453fa8..000000000 --- a/regression-tests/test-results/pure2-bugfix-for-assert-capture.cpp2.output +++ /dev/null @@ -1,4 +0,0 @@ -pure2-bugfix-for-assert-capture.cpp2... -pure2-bugfix-for-assert-capture.cpp2(2,29): error: $ (capture) cannot appear here - it must appear in an anonymous expression function, a postcondition, or an interpolated string literal (at '$') -pure2-bugfix-for-assert-capture.cpp2(2,23): error: expected ')' at the end of the contract (at '==') - diff --git a/regression-tests/test-results/pure2-bugfix-for-bad-capture-error.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-bad-capture-error.cpp2.output new file mode 100644 index 000000000..5ba08c536 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-bad-capture-error.cpp2.output @@ -0,0 +1,4 @@ +pure2-bugfix-for-bad-capture-error.cpp2... +pure2-bugfix-for-bad-capture-error.cpp2(2,29): error: $ (capture) cannot appear here - it must appear in an anonymous expression function, a postcondition, or an interpolated string literal (at '$') +pure2-bugfix-for-bad-capture-error.cpp2(2,23): error: expected ')' at the end of the contract (at '==') + diff --git a/regression-tests/test-results/pure2-bugfix-for-bad-capture.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-bad-capture.cpp2.output deleted file mode 100644 index cc4c11f84..000000000 --- a/regression-tests/test-results/pure2-bugfix-for-bad-capture.cpp2.output +++ /dev/null @@ -1,4 +0,0 @@ -pure2-bugfix-for-bad-capture.cpp2... -pure2-bugfix-for-bad-capture.cpp2(2,29): error: $ (capture) cannot appear here - it must appear in an anonymous expression function, a postcondition, or an interpolated string literal (at '$') -pure2-bugfix-for-bad-capture.cpp2(2,23): error: expected ')' at the end of the contract (at '==') - diff --git a/regression-tests/test-results/pure2-bugfix-for-bad-decltype-error.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-bad-decltype-error.cpp2.output new file mode 100644 index 000000000..57a22f00b --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-bad-decltype-error.cpp2.output @@ -0,0 +1,6 @@ +pure2-bugfix-for-bad-decltype-error.cpp2... +pure2-bugfix-for-bad-decltype-error.cpp2(3,14): error: 'decltype' must be followed by a single parenthesized expression +pure2-bugfix-for-bad-decltype-error.cpp2(3,24): error: 'is' must be followed by a type-id or an expression +pure2-bugfix-for-bad-decltype-error.cpp2(3,14): error: 'decltype' must be followed by a single parenthesized expression +pure2-bugfix-for-bad-decltype-error.cpp2(3,24): error: 'is' must be followed by a type-id or an expression + diff --git a/regression-tests/test-results/pure2-bugfix-for-bad-decltype.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-bad-decltype.cpp2.output deleted file mode 100644 index 0685b6d73..000000000 --- a/regression-tests/test-results/pure2-bugfix-for-bad-decltype.cpp2.output +++ /dev/null @@ -1,6 +0,0 @@ -pure2-bugfix-for-bad-decltype.cpp2... -pure2-bugfix-for-bad-decltype.cpp2(3,14): error: 'decltype' must be followed by a single parenthesized expression -pure2-bugfix-for-bad-decltype.cpp2(3,24): error: 'is' must be followed by a type-id or an expression -pure2-bugfix-for-bad-decltype.cpp2(3,14): error: 'decltype' must be followed by a single parenthesized expression -pure2-bugfix-for-bad-decltype.cpp2(3,24): error: 'is' must be followed by a type-id or an expression - diff --git a/regression-tests/test-results/pure2-bugfix-for-bad-parameter-error.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-bad-parameter-error.cpp2.output new file mode 100644 index 000000000..d52f98037 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-bad-parameter-error.cpp2.output @@ -0,0 +1,3 @@ +pure2-bugfix-for-bad-parameter-error.cpp2... +pure2-bugfix-for-bad-parameter-error.cpp2(1,50): error: parameter must be initialized with an expression (at ')') + diff --git a/regression-tests/test-results/pure2-bugfix-for-bad-parameter.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-bad-parameter.cpp2.output deleted file mode 100644 index d435bd7b6..000000000 --- a/regression-tests/test-results/pure2-bugfix-for-bad-parameter.cpp2.output +++ /dev/null @@ -1,3 +0,0 @@ -pure2-bugfix-for-bad-parameter.cpp2... -pure2-bugfix-for-bad-parameter.cpp2(1,50): error: parameter must be initialized with an expression (at ')') - diff --git a/regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses-error.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses-error.cpp2.output new file mode 100644 index 000000000..d423e88ce --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses-error.cpp2.output @@ -0,0 +1,3 @@ +pure2-bugfix-for-functions-before-superclasses-error.cpp2... +pure2-bugfix-for-functions-before-superclasses-error.cpp2(7,3): error: a type cannot declare a parent after defining a function + diff --git a/regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses.cpp2.output deleted file mode 100644 index 833bce07e..000000000 --- a/regression-tests/test-results/pure2-bugfix-for-functions-before-superclasses.cpp2.output +++ /dev/null @@ -1,3 +0,0 @@ -pure2-bugfix-for-functions-before-superclasses.cpp2... -pure2-bugfix-for-functions-before-superclasses.cpp2(7,3): error: a type cannot declare a parent after defining a function - diff --git a/regression-tests/test-results/pure2-bugfix-for-invalid-alias-error.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-invalid-alias-error.cpp2.output new file mode 100644 index 000000000..b3dc73e2e --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-invalid-alias-error.cpp2.output @@ -0,0 +1,3 @@ +pure2-bugfix-for-invalid-alias-error.cpp2... +pure2-bugfix-for-invalid-alias-error.cpp2(2,25): error: invalid alias declaration - expected 'type', 'namespace', or a type-id after ':' + diff --git a/regression-tests/test-results/pure2-bugfix-for-invalid-alias.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-invalid-alias.cpp2.output deleted file mode 100644 index 96f281bf0..000000000 --- a/regression-tests/test-results/pure2-bugfix-for-invalid-alias.cpp2.output +++ /dev/null @@ -1,3 +0,0 @@ -pure2-bugfix-for-invalid-alias.cpp2... -pure2-bugfix-for-invalid-alias.cpp2(2,25): error: invalid alias declaration - expected 'type', 'namespace', or a type-id after ':' - diff --git a/regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char-error.cpp2.output similarity index 52% rename from regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char.cpp2.output rename to regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char-error.cpp2.output index 01b912d76..c1b5aceac 100644 --- a/regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char.cpp2.output +++ b/regression-tests/test-results/pure2-bugfix-for-naked-unsigned-char-error.cpp2.output @@ -1,6 +1,6 @@ -pure2-bugfix-for-naked-unsigned-char.cpp2... -pure2-bugfix-for-naked-unsigned-char.cpp2(2,8): error: 'unsigned char' - did you mean 'u8' (usually best) or 'cpp2::_uchar'? -pure2-bugfix-for-naked-unsigned-char.cpp2(2,8): error: 'unsigned char' is an old-style C/C++ multi-word keyword type +pure2-bugfix-for-naked-unsigned-char-error.cpp2... +pure2-bugfix-for-naked-unsigned-char-error.cpp2(2,8): error: 'unsigned char' - did you mean 'u8' (usually best) or 'cpp2::_uchar'? +pure2-bugfix-for-naked-unsigned-char-error.cpp2(2,8): error: 'unsigned char' is an old-style C/C++ multi-word keyword type - most such types should be used only for interoperability with older code - using those when you need them is fine, but name them with these short names instead: short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, _schar, _uchar diff --git a/regression-tests/test-results/pure2-bugfix-for-namespace-error.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-namespace-error.cpp2.output new file mode 100644 index 000000000..0c5ed2526 --- /dev/null +++ b/regression-tests/test-results/pure2-bugfix-for-namespace-error.cpp2.output @@ -0,0 +1,3 @@ +pure2-bugfix-for-namespace-error.cpp2... +pure2-bugfix-for-namespace-error.cpp2(2,22): error: types cannot contain namespaces (at 'namespace') + diff --git a/regression-tests/test-results/pure2-bugfix-for-namespace.cpp2.output b/regression-tests/test-results/pure2-bugfix-for-namespace.cpp2.output deleted file mode 100644 index 8e6b13daa..000000000 --- a/regression-tests/test-results/pure2-bugfix-for-namespace.cpp2.output +++ /dev/null @@ -1,3 +0,0 @@ -pure2-bugfix-for-namespace.cpp2... -pure2-bugfix-for-namespace.cpp2(2,22): error: types cannot contain namespaces (at 'namespace') - From 466292aa8a7d0ff3ac5cff14cdfc4b605da05131 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Mon, 28 Apr 2025 19:45:31 -1000 Subject: [PATCH 8/8] Minor tidying to fit house style `exit(1)` -> `exit(EXIT_FAILURE)` Branch and loop bodies are always enclosed in `{` `}` even when they contain a single line --- include/cpp2util.h | 3 +-- source/io.h | 3 ++- source/lex.h | 3 ++- source/parse.h | 2 +- source/sema.h | 3 ++- source/to_cpp1.h | 6 ++++-- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/cpp2util.h b/include/cpp2util.h index a5f7e0aab..a058bb5d9 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -561,8 +561,7 @@ class contract_group { std::cerr << ": " << msg; } std::cerr << "\n"; - // Get outta here but don't raise a signal - std::exit(1); + std::exit(EXIT_FAILURE); } auto inline cpp2_default = contract_group( diff --git a/source/io.h b/source/io.h index ba7106942..23caf2b82 100644 --- a/source/io.h +++ b/source/io.h @@ -363,8 +363,9 @@ class braces_tracker } auto found_preprocessor_else_was_there_another() -> bool { - if (found_else) + if (found_else) { return true; + } found_else = true; return false; } diff --git a/source/lex.h b/source/lex.h index 8bd5acffa..892b1b84a 100644 --- a/source/lex.h +++ b/source/lex.h @@ -718,13 +718,14 @@ auto lex_line( // the number of tokens has not gone down. So just push back as many // tokens as we merged. This will ensure that the token count remains // the same. - for (auto i = 0; i < num_merged_tokens; i++) + for (auto i = 0; i < num_merged_tokens; i++) { tokens.push_back({ &generated_text.back()[0], std::ssize(generated_text.back()), pos, lexeme::Keyword }); + } if (num_merged_tokens > 1) { diff --git a/source/parse.h b/source/parse.h index 7987af007..42566cd7c 100644 --- a/source/parse.h +++ b/source/parse.h @@ -9853,7 +9853,7 @@ class parser curr().position(), "invalid alias declaration - expected 'type', 'namespace', or a type-id after ':'" ); - return {}; + return {}; } // And the final ceremonial semicolon diff --git a/source/sema.h b/source/sema.h index e615c0949..207e28e72 100644 --- a/source/sema.h +++ b/source/sema.h @@ -2052,8 +2052,9 @@ class sema } auto stmt_decl = stmt->get_if(); // If this is a declaration, check if it's a function - if (stmt_decl && stmt_decl->is_function()) + if (stmt_decl && stmt_decl->is_function()) { seen_function = true; + } // If this is called 'this', then make sure we haven't seen any functions if ( diff --git a/source/to_cpp1.h b/source/to_cpp1.h index cff6a92dd..6bc03f855 100644 --- a/source/to_cpp1.h +++ b/source/to_cpp1.h @@ -468,8 +468,9 @@ class positional_printer ) { print_comment( comments[next_comment] ); - if (!print_remaining_comments) + if (!print_remaining_comments) { assert(curr_pos.lineno <= pos.lineno); // we shouldn't have overshot + } } ++next_comment; @@ -481,8 +482,9 @@ class positional_printer } } // And catch up. - while (curr_pos.lineno < pos.lineno) + while (curr_pos.lineno < pos.lineno) { print("\n"); + } } auto print_unprinted_comments()