diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-08-09 13:48:52 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-09 13:48:52 +0000 |
commit | 17b625cbd612f05359c3199a3253f42e4cf25120 (patch) | |
tree | 36d03056fb9747a4394c56f78c29e13f1d6df82b /gcc | |
parent | 8749b66879f3ef78182d7712e5da981cc55f747a (diff) | |
parent | 4ffd884a69396d828049d4a14d17e6d3f6c8d61f (diff) | |
download | gcc-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.cc | 51 | ||||
-rw-r--r-- | gcc/rust/checks/errors/rust-const-checker.h | 7 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/const-issue1440.rs | 76 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-1031.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-1289.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/issue-1075.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/issue-1432.rs | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-1120.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-1133.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-1232.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-1436.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/slice-magic.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/slice-magic2.rs | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/str-layout1.rs | 1 |
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 ¶m : 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; } } |