https://gcc.gnu.org/g:89f93aeeec6a92eb64817c7bc4997d2047ab56fd
commit r17-5713-g89f93aeeec6a92eb64817c7bc4997d2047ab56fd Author: Arthur Cohen <[email protected]> Date: Thu Oct 22 01:30:11 2026 +0200 gccrs: intrinsics: Add basic implementation for breakpoint This currently traps with ud2 on x86 instead of int3, as there is no equivalent to the llvm.debugtrap OP in GCC. gcc/rust/ChangeLog: * backend/rust-compile-intrinsic.cc: Register the handler. * backend/rust-intrinsic-handlers.cc (breakpoint): Define it. * backend/rust-intrinsic-handlers.h (breakpoint): Declare it. * typecheck/rust-hir-type-check-intrinsic.cc: Add tychk entry for breakpoint. * util/rust-intrinsic-values.h: Add new value for breakpoint. gcc/testsuite/ChangeLog: * rust/compile/breakpoint.rs: New test. Diff: --- gcc/rust/backend/rust-compile-intrinsic.cc | 1 + gcc/rust/backend/rust-intrinsic-handlers.cc | 20 ++++++++++++++++++++ gcc/rust/backend/rust-intrinsic-handlers.h | 2 ++ gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc | 3 +++ gcc/rust/util/rust-intrinsic-values.h | 2 ++ gcc/testsuite/rust/compile/breakpoint.rs | 15 +++++++++++++++ 6 files changed, 43 insertions(+) diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 131ad42dd455..5cdee95aad81 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -91,6 +91,7 @@ static const std::map<std::string, Intrinsic::CompileFn> intrinsics = { handlers::fop_fast (ArithmeticOrLogicalOperator::MODULUS)}, {IValue::FLOAT_TO_INT_UNCHECKED, handlers::float_to_int_unchecked}, {IValue::EXACT_DIV, handlers::exact_div_handler}, + {IValue::BREAKPOINT, handlers::breakpoint}, {IValue::ASSERT_ZERO_VALID, handlers::type_assert (TyAssert::ZeroValid)}, {IValue::ASSERT_INHABITED, handlers::type_assert (TyAssert::Inhabited)}, {IValue::ASSERT_UNINIT_VALID, handlers::type_assert (TyAssert::UninitValid)}, diff --git a/gcc/rust/backend/rust-intrinsic-handlers.cc b/gcc/rust/backend/rust-intrinsic-handlers.cc index 58f3f345ea3b..034d28044c60 100644 --- a/gcc/rust/backend/rust-intrinsic-handlers.cc +++ b/gcc/rust/backend/rust-intrinsic-handlers.cc @@ -1896,6 +1896,26 @@ float_to_int_unchecked (IntrinsicCtx &ctx) ctx.add_statement (return_statement); } +void +breakpoint (IntrinsicCtx &ctx) +{ + // For now, we don't have access to an equivalent of LLVM's debugtrap inst. We + // work around the problem by emitting a regular trap and we hope that the + // user's debugger can catch it :) Ideally, this would emit an `int3` on x86 + // rather than a `ud2` + + auto trap = BuiltinsContext::get ().lookup_simple_builtin ("__builtin_trap"); + rust_assert (trap); + + tree trap_call = build_call_expr_loc (ctx.loc, *trap, 0); + + ctx.add_statement (trap_call); + + TREE_READONLY (ctx.fn) = 0; + TREE_USED (ctx.fn) = 1; + TREE_SIDE_EFFECTS (ctx.fn) = 1; +} + } // namespace handlers } // namespace Compile } // namespace Rust diff --git a/gcc/rust/backend/rust-intrinsic-handlers.h b/gcc/rust/backend/rust-intrinsic-handlers.h index d0aad88ee6ab..68fdec129d2c 100644 --- a/gcc/rust/backend/rust-intrinsic-handlers.h +++ b/gcc/rust/backend/rust-intrinsic-handlers.h @@ -208,6 +208,8 @@ Intrinsic::CompileFn fop_fast (ArithmeticOrLogicalOperator op); */ Intrinsic::CompileFn type_assert (TyAssert assert); +void breakpoint (IntrinsicCtx &ctx); + } // namespace handlers } // namespace Compile diff --git a/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc b/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc index 728b5fdd0904..9914a2928498 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc @@ -312,6 +312,9 @@ const std::unordered_map<std::string, IntrinsicRules> {IValue::WRITE_BYTES, {1, {IRT::MutPtrFirstGeneric, IRT::U8, IRT::Usize}, IRT::Unit}}, + // fn breakpoint() + {IValue::BREAKPOINT, {0, {}, IRT::Unit}}, + // pub fn assert_zero_valid<T>(); {IValue::ASSERT_ZERO_VALID, {1, {}, IRT::Unit}}, // fn assert_inhabited<T>(); diff --git a/gcc/rust/util/rust-intrinsic-values.h b/gcc/rust/util/rust-intrinsic-values.h index e154f60b5e4b..e748616eba5c 100644 --- a/gcc/rust/util/rust-intrinsic-values.h +++ b/gcc/rust/util/rust-intrinsic-values.h @@ -175,6 +175,8 @@ public: static constexpr auto &ARITH_OFFSET = "arith_offset"; static constexpr auto &WRITE_BYTES = "write_bytes"; + static constexpr auto &BREAKPOINT = "breakpoint"; + static constexpr auto &ASSERT_ZERO_VALID = "assert_zero_valid"; static constexpr auto &ASSERT_INHABITED = "assert_inhabited"; static constexpr auto &ASSERT_UNINIT_VALID = "assert_uninit_valid"; diff --git a/gcc/testsuite/rust/compile/breakpoint.rs b/gcc/testsuite/rust/compile/breakpoint.rs new file mode 100644 index 000000000000..d3286e1d9384 --- /dev/null +++ b/gcc/testsuite/rust/compile/breakpoint.rs @@ -0,0 +1,15 @@ +#![feature(no_core)] +#![feature(intrinsics)] +#![no_core] + +extern "rust-intrinsic" { + fn breakpoint(); +} + +fn foo() { + unsafe { breakpoint() }; +} + +fn main() { + foo(); +}
