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 &param : 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).