From: Arthur Cohen <[email protected]>
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.
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/741271b04615db9ed50caa40173f60e35a107999
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/5008
gcc/rust/backend/rust-compile-intrinsic.cc | 1 +
gcc/rust/backend/rust-intrinsic-handlers.cc | 20 +++++++++++++++++++
gcc/rust/backend/rust-intrinsic-handlers.h | 2 ++
.../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(+)
create mode 100644 gcc/testsuite/rust/compile/breakpoint.rs
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 131ad42dd..5cdee95aa 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 58f3f345e..034d28044 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 d0aad88ee..68fdec129 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 728b5fdd0..9914a2928 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 e154f60b5..e748616eb 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 000000000..d3286e1d9
--- /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();
+}
base-commit: 8204ba7c099852a9e03a5ab705f7e96b5a7cac2f
--
2.55.0