https://gcc.gnu.org/g:136c428abb4be874a3302e80a513301f298d3c70
commit 136c428abb4be874a3302e80a513301f298d3c70 Merge: d374f52a692c 8fc4e6c397e1 Author: Thomas Schwinge <tschwi...@baylibre.com> Date: Tue Mar 19 16:45:47 2024 +0100 Merge commit '8fc4e6c397e1ce64bec6f9fed148950821cc79e7' into HEAD Accordingly also adjust #2086 "break rust 💥" code, to avoid: [...]/source-gcc/gcc/rust/resolve/rust-ast-resolve-expr.cc: In member function ‘virtual void Rust::Resolver::ResolveExpr::visit(Rust::AST::IdentifierExpr&)’: [...]/source-gcc/gcc/rust/resolve/rust-ast-resolve-expr.cc:164:42: error: invalid conversion from ‘void (*)(diagnostic_context*, diagnostic_info*, diagnostic_t)’ to ‘diagnostic_finalizer_fn’ {aka ‘void (*)(diagnostic_context*, con iagnostic_info*, diagnostic_t)’} [-fpermissive] 164 | diagnostic_finalizer (global_dc) = funny_ice_finalizer; | ^~~~~~~~~~~~~~~~~~~ | | | void (*)(diagnostic_context*, diagnostic_info*, diagnostic_t) Diff: gcc/c-family/c-opts.cc | 2 +- gcc/cp/cp-tree.h | 2 +- gcc/cp/error.cc | 12 +++-- gcc/diagnostic-format-json.cc | 20 ++++---- gcc/diagnostic-format-sarif.cc | 57 +++++++++++----------- gcc/diagnostic.cc | 17 ++++--- gcc/diagnostic.h | 17 ++++--- gcc/fortran/error.cc | 4 +- gcc/jit/dummy-frontend.cc | 7 +-- gcc/jit/jit-playback.cc | 4 +- gcc/jit/jit-playback.h | 2 +- gcc/langhooks-def.h | 3 +- gcc/langhooks.cc | 2 +- gcc/langhooks.h | 2 +- gcc/rust/resolve/rust-ast-resolve-expr.cc | 4 +- .../plugin/show_template_tree_color_plugin.c | 2 +- .../gcc.dg/plugin/diagnostic_group_plugin.c | 2 +- .../plugin/diagnostic_plugin_test_show_locus.c | 2 +- .../gcc.dg/plugin/location_overflow_plugin.c | 4 +- gcc/tree-diagnostic.cc | 6 +-- gcc/tree-diagnostic.h | 4 +- libcc1/context.cc | 2 +- 22 files changed, 92 insertions(+), 85 deletions(-) diff --cc gcc/rust/resolve/rust-ast-resolve-expr.cc index d42e7fee4af4,4dfc0833d914..1bb3fc601539 --- a/gcc/rust/resolve/rust-ast-resolve-expr.cc +++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc @@@ -97,47 -98,11 +97,47 @@@ ResolveExpr::visit (AST::MethodCallExp void ResolveExpr::visit (AST::AssignmentExpr &expr) { - ResolveExpr::go (expr.get_left_expr ().get (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_right_expr ().get (), prefix, canonical_prefix); + ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); + ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); +} + +/* The "break rust" Easter egg. + + Backstory: once upon a time, there used to be a bug in rustc: it would ICE + during typechecking on a 'break' with an expression outside of a loop. The + issue has been reported [0] and fixed [1], but in recognition of this, as a + special Easter egg, "break rust" was made to intentionally cause an ICE. + + [0]: https://github.com/rust-lang/rust/issues/43162 + [1]: https://github.com/rust-lang/rust/pull/43745 + + This was made in a way that does not break valid programs: namely, it only + happens when the 'break' is outside of a loop (so invalid anyway). + + GCC Rust supports this essential feature as well, but in a slightly + different way. Instead of delaying the error until type checking, we emit + it here in the resolution phase. We, too, only do this to programs that + are already invalid: we only emit our funny ICE if the name "rust" (which + must be immediately inside a break-with-a-value expression) fails to + resolve. Note that "break (rust)" does not trigger our ICE, only using + "break rust" directly does, and only if there's no "rust" in scope. We do + this in the same way regardless of whether the "break" is outside of a loop + or inside one. + + As a GNU extension, we also support "break gcc", much to the same effect, + subject to the same rules. */ + +/* The finalizer for our funny ICE. This prints a custom message instead of + the default bug reporting instructions, as there is no bug to report. */ - // need to verify the assignee - VerifyAsignee::go (expr.get_left_expr ().get ()); +static void ATTRIBUTE_NORETURN - funny_ice_finalizer (diagnostic_context *context, diagnostic_info *diagnostic, - diagnostic_t diag_kind) ++funny_ice_finalizer (diagnostic_context *context, ++ const diagnostic_info *diagnostic, diagnostic_t diag_kind) +{ + gcc_assert (diag_kind == DK_ICE_NOBT); + default_diagnostic_finalizer (context, diagnostic, diag_kind); + fnotice (stderr, "You have broken GCC Rust. This is a feature.\n"); + exit (ICE_EXIT_CODE); } void