aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-08-09 13:48:52 +0000
committerGitHub <noreply@github.com>2022-08-09 13:48:52 +0000
commit17b625cbd612f05359c3199a3253f42e4cf25120 (patch)
tree36d03056fb9747a4394c56f78c29e13f1d6df82b /gcc
parent8749b66879f3ef78182d7712e5da981cc55f747a (diff)
parent4ffd884a69396d828049d4a14d17e6d3f6c8d61f (diff)
downloadgcc-17b625cbd612f05359c3199a3253f42e4cf25120.zip
gcc-17b625cbd612f05359c3199a3253f42e4cf25120.tar.gz
gcc-17b625cbd612f05359c3199a3253f42e4cf25120.tar.bz2
Merge #1444
1444: Handle `rustc_const_{un}stable` properly for intrinsics r=CohenArthur a=CohenArthur 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. Closes #1440 Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.cc51
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.h7
-rw-r--r--gcc/testsuite/rust/compile/const-issue1440.rs76
-rw-r--r--gcc/testsuite/rust/compile/issue-1031.rs1
-rw-r--r--gcc/testsuite/rust/compile/issue-1289.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-1075.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-1432.rs6
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1120.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1133.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1232.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1436.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/slice-magic.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/slice-magic2.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/str-layout1.rs1
14 files changed, 147 insertions, 3 deletions
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index bb6ae10..ad0a2cf 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -37,6 +37,21 @@ ConstChecker::go (HIR::Crate &crate)
item->accept_vis (*this);
}
+bool
+ConstChecker::is_const_extern_fn (HIR::ExternalFunctionItem &fn)
+{
+ // 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 std::any_of (
+ fn.get_outer_attrs ().begin (), fn.get_outer_attrs ().end (),
+ [] (const AST::Attribute &attr) {
+ // `starts_with` in C++11...
+ return attr.get_path ().as_string ().rfind ("rustc_const_", 0) == 0;
+ });
+}
+
void
ConstChecker::visit (IdentifierExpr &ident_expr)
{}
@@ -235,11 +250,38 @@ 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);
+ if (!is_const_extern_fn (*fn))
+ 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 +564,9 @@ ConstChecker::visit (Function &function)
if (const_fn)
const_context.enter (function.get_mappings ().get_hirid ());
+ for (auto &param : function.get_function_params ())
+ param.get_type ()->accept_vis (*this);
+
function.get_definition ()->accept_vis (*this);
if (const_fn)
diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h
index a474fc8..608ea3e 100644
--- a/gcc/rust/checks/errors/rust-const-checker.h
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -33,6 +33,13 @@ public:
void go (HIR::Crate &crate);
+ /**
+ * Check if an item is a const extern item or not
+ * TODO: Move this to a const compilation context class or an attribute
+ * checking class
+ */
+ static bool is_const_extern_fn (HIR::ExternalFunctionItem &fn);
+
private:
/**
* Check that only const functions are called in const contexts
diff --git a/gcc/testsuite/rust/compile/const-issue1440.rs b/gcc/testsuite/rust/compile/const-issue1440.rs
new file mode 100644
index 0000000..9b974b9
--- /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 6727f34..939f0f9 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 8634f1d..343aaab 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 3bd6321..f346d9a 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 2a238e1..a3fa2c3 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 ecbc6b2..740cf7c 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 19d6690..fd3d7b6 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 983ea41..63d7681 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 32da34e..327de26 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 bac8a78..f9762b2 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 5a89f2e..d6cbe21 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 be89184..80bdc2a 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;
}
}