From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 08DBD3857BA7; Tue, 9 Aug 2022 20:39:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 08DBD3857BA7 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] attr: Handle `rustc_const_{un}stable` properly X-Act-Checkin: gcc X-Git-Author: Arthur Cohen X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: 7beea479c5a1e7e415223f3fbd4e16c20c3214ec X-Git-Newrev: 084f959076c10d54bdb5c80cad10a0aac5756ea4 Message-Id: <20220809203905.08DBD3857BA7@sourceware.org> Date: Tue, 9 Aug 2022 20:39:05 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Aug 2022 20:39:05 -0000 https://gcc.gnu.org/g:084f959076c10d54bdb5c80cad10a0aac5756ea4 commit 084f959076c10d54bdb5c80cad10a0aac5756ea4 Author: Arthur Cohen 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 (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 (maybe_fn); + if (!fn->get_qualifiers ().is_const ()) + is_error = true; + } + + if (maybe_extern_item) + { + { + auto fn = static_cast (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 % 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(a: T, b: T) -> T; + pub fn rotate_left(a: T, b: T) -> T; + pub fn rotate_right(a: T, b: T) -> T; + pub fn offset(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; + pub fn size_of() -> 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 { + // { 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 { + // { 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(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(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(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(a: T, b: T) -> T; + #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] pub fn rotate_left(a: T, b: T) -> T; + #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] pub fn rotate_right(a: T, b: T) -> T; + #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] pub fn offset(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; + #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] fn size_of() -> 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(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(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(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(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(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(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; } }