]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Merge commit '8fc4e6c397e1ce64bec6f9fed148950821cc79e7' into HEAD
authorThomas Schwinge <tschwinge@baylibre.com>
Tue, 19 Mar 2024 15:45:47 +0000 (16:45 +0100)
committerThomas Schwinge <tschwinge@baylibre.com>
Tue, 19 Mar 2024 15:46:40 +0000 (16:46 +0100)
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)

1  2 
gcc/rust/resolve/rust-ast-resolve-expr.cc

index d42e7fee4af40ed6ab472f617ab10f6c1b77d4fb,4dfc0833d9141089de5e2404a0e36225722b088c..1bb3fc601539f55e1b71752593a4bc02eca24b9b
@@@ -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