public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] attr: Handle `rustc_const_{un}stable` properly
@ 2022-08-09 20:39 Thomas Schwinge
0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-08-09 20:39 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:084f959076c10d54bdb5c80cad10a0aac5756ea4
commit 084f959076c10d54bdb5c80cad10a0aac5756ea4
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date: Mon Aug 8 08:48:26 2022 +0200
attr: Handle `rustc_const_{un}stable` properly
Since extern functions cannot be marked as const (they take no
qualifiers) but some intrinsics are const, while still being `extern
"rust-intrinsic", we need to be able to handle the
`#[rustc_const_stable]` and `#[rustc_const_unstable]` attribute.
Technically, this simply indicates that a certain intrinsic is constant
and can be used in const contexts, such as `size_of` or `offset`.
We also need to mark all const intrinsics with `rustc_const_stable` in
the testsuite.
Diff:
---
gcc/rust/checks/errors/rust-const-checker.cc | 46 ++++++++++++-
gcc/testsuite/rust/compile/const-issue1440.rs | 76 ++++++++++++++++++++++
gcc/testsuite/rust/compile/issue-1031.rs | 1 +
gcc/testsuite/rust/compile/issue-1289.rs | 1 +
gcc/testsuite/rust/compile/torture/issue-1075.rs | 1 +
gcc/testsuite/rust/compile/torture/issue-1432.rs | 6 ++
gcc/testsuite/rust/execute/torture/issue-1120.rs | 1 +
gcc/testsuite/rust/execute/torture/issue-1133.rs | 1 +
gcc/testsuite/rust/execute/torture/issue-1232.rs | 1 +
gcc/testsuite/rust/execute/torture/issue-1436.rs | 1 +
gcc/testsuite/rust/execute/torture/slice-magic.rs | 1 +
gcc/testsuite/rust/execute/torture/slice-magic2.rs | 1 +
gcc/testsuite/rust/execute/torture/str-layout1.rs | 1 +
13 files changed, 135 insertions(+), 3 deletions(-)
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index bb6ae1052e1..bd4c7f19906 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -235,11 +235,48 @@ ConstChecker::check_function_call (HirId fn_id, Location locus)
return;
auto maybe_fn = mappings.lookup_hir_item (fn_id);
- if (!maybe_fn || maybe_fn->get_item_kind () != Item::ItemKind::Function)
+ if (maybe_fn && maybe_fn->get_item_kind () != Item::ItemKind::Function)
return;
- auto fn = static_cast<Function *> (maybe_fn);
- if (!fn->get_qualifiers ().is_const ())
+ // There are const extern functions (intrinsics)
+ // TODO: Should we check the ABI is only "rust intrinsics"? Is that handled
+ // elsewhere?
+ HirId parent_block;
+ auto maybe_extern_item
+ = mappings.lookup_hir_extern_item (fn_id, &parent_block);
+ if (maybe_extern_item
+ && maybe_extern_item->get_extern_kind ()
+ != ExternalItem::ExternKind::Function)
+ return;
+
+ auto is_error = false;
+ if (maybe_fn)
+ {
+ auto fn = static_cast<Function *> (maybe_fn);
+ if (!fn->get_qualifiers ().is_const ())
+ is_error = true;
+ }
+
+ if (maybe_extern_item)
+ {
+ {
+ auto fn = static_cast<ExternalFunctionItem *> (maybe_extern_item);
+ auto is_const_extern = std::any_of (
+ fn->get_outer_attrs ().begin (), fn->get_outer_attrs ().end (),
+ [] (const AST::Attribute &attr) {
+ // `starts_with` in C++11...
+ // FIXME: Is it really how we want to handle `rustc_const_stable`
+ // and `rustc_const_unstable`?
+ // TODO: Add these attributes to the attribute check and handle
+ // `stable` and `unstable` as well
+ return attr.get_path ().as_string ().rfind ("rustc_const_", 0) == 0;
+ });
+ if (!is_const_extern)
+ is_error = true;
+ }
+ }
+
+ if (is_error)
rust_error_at (locus, "only functions marked as %<const%> are allowed to "
"be called from constant contexts");
}
@@ -522,6 +559,9 @@ ConstChecker::visit (Function &function)
if (const_fn)
const_context.enter (function.get_mappings ().get_hirid ());
+ for (auto ¶m : function.get_function_params ())
+ param.get_type ()->accept_vis (*this);
+
function.get_definition ()->accept_vis (*this);
if (const_fn)
diff --git a/gcc/testsuite/rust/compile/const-issue1440.rs b/gcc/testsuite/rust/compile/const-issue1440.rs
new file mode 100644
index 00000000000..9b974b96bbb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const-issue1440.rs
@@ -0,0 +1,76 @@
+// { dg-additional-options "-w" }
+
+mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn wrapping_add<T>(a: T, b: T) -> T;
+ pub fn rotate_left<T>(a: T, b: T) -> T;
+ pub fn rotate_right<T>(a: T, b: T) -> T;
+ pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
+ }
+}
+
+mod mem {
+ extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
+ pub fn transmute<T, U>(_: T) -> U;
+ pub fn size_of<T>() -> usize;
+ }
+}
+
+macro_rules! impl_uint {
+ ($($ty:ident = $lang:literal),*) => {
+ $(
+ impl $ty {
+ pub fn wrapping_add(self, rhs: Self) -> Self {
+ // intrinsics::wrapping_add(self, rhs)
+ self + rhs
+ }
+
+ pub fn rotate_left(self, n: u32) -> Self {
+ unsafe {
+ intrinsics::rotate_left(self, n as Self)
+ }
+ }
+
+ pub fn rotate_right(self, n: u32) -> Self {
+ unsafe {
+ intrinsics::rotate_right(self, n as Self)
+ }
+ }
+
+ pub fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ }
+
+ pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ // { dg-error "only functions marked as .const. are allowed to be called from constant contexts" "" { target *-*-* } .-1 }
+ Self::from_le(Self::from_ne_bytes(bytes))
+ }
+
+ pub const fn from_le(x: Self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ x
+ }
+ }
+
+ pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+ // { dg-error "only functions marked as .const. are allowed to be called from constant contexts" "" { target *-*-* } .-1 }
+ unsafe { mem::transmute(bytes) }
+ }
+ }
+ )*
+ }
+}
+
+impl_uint!(
+ u8 = "u8",
+ u16 = "u16",
+ u32 = "u32",
+ u64 = "u64",
+ u128 = "u128",
+ usize = "usize"
+);
diff --git a/gcc/testsuite/rust/compile/issue-1031.rs b/gcc/testsuite/rust/compile/issue-1031.rs
index 6727f34336f..939f0f981e0 100644
--- a/gcc/testsuite/rust/compile/issue-1031.rs
+++ b/gcc/testsuite/rust/compile/issue-1031.rs
@@ -1,4 +1,5 @@
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
}
diff --git a/gcc/testsuite/rust/compile/issue-1289.rs b/gcc/testsuite/rust/compile/issue-1289.rs
index 8634f1d7e4e..343aaab078b 100644
--- a/gcc/testsuite/rust/compile/issue-1289.rs
+++ b/gcc/testsuite/rust/compile/issue-1289.rs
@@ -4,6 +4,7 @@ extern "C" {
mod intrinsics {
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
}
}
diff --git a/gcc/testsuite/rust/compile/torture/issue-1075.rs b/gcc/testsuite/rust/compile/torture/issue-1075.rs
index 3bd6321a940..f346d9a572a 100644
--- a/gcc/testsuite/rust/compile/torture/issue-1075.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-1075.rs
@@ -1,5 +1,6 @@
// { dg-additional-options "-w" }
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
}
diff --git a/gcc/testsuite/rust/compile/torture/issue-1432.rs b/gcc/testsuite/rust/compile/torture/issue-1432.rs
index 2a238e14744..a3fa2c36be7 100644
--- a/gcc/testsuite/rust/compile/torture/issue-1432.rs
+++ b/gcc/testsuite/rust/compile/torture/issue-1432.rs
@@ -1,16 +1,22 @@
// { dg-additional-options "-w" }
mod intrinsics {
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
pub fn wrapping_add<T>(a: T, b: T) -> T;
+ #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
pub fn rotate_left<T>(a: T, b: T) -> T;
+ #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
pub fn rotate_right<T>(a: T, b: T) -> T;
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
}
}
mod mem {
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
fn transmute<T, U>(_: T) -> U;
+ #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
fn size_of<T>() -> usize;
}
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1120.rs b/gcc/testsuite/rust/execute/torture/issue-1120.rs
index ecbc6b2017f..740cf7cfa93 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1120.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1120.rs
@@ -1,5 +1,6 @@
// { dg-additional-options "-w" }
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1133.rs b/gcc/testsuite/rust/execute/torture/issue-1133.rs
index 19d66904d15..fd3d7b6d72a 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1133.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1133.rs
@@ -1,5 +1,6 @@
// { dg-additional-options "-w" }
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1232.rs b/gcc/testsuite/rust/execute/torture/issue-1232.rs
index 983ea41d7d8..63d7681dc29 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1232.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1232.rs
@@ -1,6 +1,7 @@
// { dg-additional-options "-w" }
// { dg-output "slice_access=3\n" }
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
fn offset<T>(dst: *const T, offset: isize) -> *const T;
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1436.rs b/gcc/testsuite/rust/execute/torture/issue-1436.rs
index 32da34e105a..327de26fb47 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1436.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1436.rs
@@ -2,6 +2,7 @@
// { dg-output "" }
mod intrinsics {
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn offset<T>(ptr: *const T, count: isize) -> *const T;
}
}
diff --git a/gcc/testsuite/rust/execute/torture/slice-magic.rs b/gcc/testsuite/rust/execute/torture/slice-magic.rs
index bac8a7803e6..f9762b22fa6 100644
--- a/gcc/testsuite/rust/execute/torture/slice-magic.rs
+++ b/gcc/testsuite/rust/execute/torture/slice-magic.rs
@@ -1,5 +1,6 @@
// { dg-additional-options "-w" }
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
}
diff --git a/gcc/testsuite/rust/execute/torture/slice-magic2.rs b/gcc/testsuite/rust/execute/torture/slice-magic2.rs
index 5a89f2ef3dd..d6cbe21e7ec 100644
--- a/gcc/testsuite/rust/execute/torture/slice-magic2.rs
+++ b/gcc/testsuite/rust/execute/torture/slice-magic2.rs
@@ -1,5 +1,6 @@
// { dg-additional-options "-w" }
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
}
diff --git a/gcc/testsuite/rust/execute/torture/str-layout1.rs b/gcc/testsuite/rust/execute/torture/str-layout1.rs
index be89184ed38..80bdc2a9c9f 100644
--- a/gcc/testsuite/rust/execute/torture/str-layout1.rs
+++ b/gcc/testsuite/rust/execute/torture/str-layout1.rs
@@ -2,6 +2,7 @@
// { dg-output "t1sz=5 t2sz=10" }
mod mem {
extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
fn transmute<T, U>(_: T) -> U;
}
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-08-09 20:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-09 20:39 [gcc/devel/rust/master] attr: Handle `rustc_const_{un}stable` properly Thomas Schwinge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).