From: Thomas Schwinge Date: Tue, 19 Mar 2024 15:45:47 +0000 (+0100) Subject: Merge commit '8fc4e6c397e1ce64bec6f9fed148950821cc79e7' into HEAD X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=136c428abb4be874a3302e80a513301f298d3c70;p=thirdparty%2Fgcc.git 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) --- 136c428abb4be874a3302e80a513301f298d3c70 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