aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2023-02-04 22:53:48 +0000
committerPhilip Herron <herron.philip@googlemail.com>2023-02-05 00:10:49 +0000
commit6d7a7b22882433d46bf4e4efe8c43343892c91eb (patch)
tree61ffb34ee7ae6c32d2545dd27146fab5a8e44833 /gcc
parent1b0794c172c4e60ee4cd7f2fd3a2426997b1d0a1 (diff)
downloadgcc-6d7a7b22882433d46bf4e4efe8c43343892c91eb.zip
gcc-6d7a7b22882433d46bf4e4efe8c43343892c91eb.tar.gz
gcc-6d7a7b22882433d46bf4e4efe8c43343892c91eb.tar.bz2
gccrs: Add general TypeBounds checks
Existing tests are updated to use libcore copy and clone implementation. Addresses #1725 Signed-off-by: Philip Herron <herron.philip@googlemail.com> gcc/rust/ChangeLog: * typecheck/rust-unify.cc (UnifyRules::go): ensure the bounds are checked gcc/testsuite/ChangeLog: * rust/compile/torture/intrinsics-4.rs: implement Copy trait * rust/compile/torture/intrinsics-5.rs: likewise * rust/execute/torture/atomic_load.rs: likewise * rust/execute/torture/atomic_store.rs: likewise * rust/bounds1.rs: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-unify.cc11
-rw-r--r--gcc/testsuite/rust/bounds1.rs19
-rw-r--r--gcc/testsuite/rust/compile/torture/intrinsics-4.rs63
-rw-r--r--gcc/testsuite/rust/compile/torture/intrinsics-5.rs66
-rw-r--r--gcc/testsuite/rust/execute/torture/atomic_load.rs59
-rw-r--r--gcc/testsuite/rust/execute/torture/atomic_store.rs59
6 files changed, 271 insertions, 6 deletions
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 072f761..415ffcd 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -124,6 +124,17 @@ UnifyRules::go ()
rust_debug ("unify::go ltype={%s} rtype={%s}", ltype->debug_str ().c_str (),
rtype->debug_str ().c_str ());
+ // check bounds
+ if (ltype->num_specified_bounds () > 0)
+ {
+ if (!ltype->bounds_compatible (*rtype, locus, true))
+ {
+ // already emitted an error
+ emit_error = false;
+ return new TyTy::ErrorType (0);
+ }
+ }
+
switch (ltype->get_kind ())
{
case TyTy::INFER:
diff --git a/gcc/testsuite/rust/bounds1.rs b/gcc/testsuite/rust/bounds1.rs
new file mode 100644
index 0000000..6658360
--- /dev/null
+++ b/gcc/testsuite/rust/bounds1.rs
@@ -0,0 +1,19 @@
+mod core {
+ mod ops {
+ #[lang = "add"]
+ pub trait Add<Rhs = Self> {
+ type Output;
+
+ fn add(self, rhs: Rhs) -> Self::Output;
+ }
+ }
+}
+
+pub fn foo<T: core::ops::Add<Output = i32>>(a: T) -> i32 {
+ // { dg-error "bounds not satisfied for f32 .Add. is not satisfied" "" { target *-*-* } .-1 }
+ a + a
+}
+
+pub fn main() {
+ foo(123f32);
+}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-4.rs b/gcc/testsuite/rust/compile/torture/intrinsics-4.rs
index 243d446..4e09f10 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-4.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-4.rs
@@ -1,10 +1,67 @@
-trait Copy {}
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {
+ fn clone(&self) -> Self;
+
+ fn clone_from(&mut self, source: &Self) {
+ *self = source.clone()
+ }
+}
+
+mod impls {
+ use super::Clone;
+
+ macro_rules! impl_clone {
+ ($($t:ty)*) => {
+ $(
+ impl Clone for $t {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ )*
+ }
+ }
+
+ impl_clone! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+#[lang = "copy"]
+pub trait Copy: Clone {
+ // Empty.
+}
+
+mod copy_impls {
+ use super::Copy;
+
+ macro_rules! impl_copy {
+ ($($t:ty)*) => {
+ $(
+ impl Copy for $t {}
+ )*
+ }
+ }
+
+ impl_copy! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
extern "rust-intrinsic" {
pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
pub fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
- // pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
+ pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
}
fn main() {
@@ -15,6 +72,6 @@ fn main() {
atomic_store_seqcst(&mut dst, new_value);
atomic_store_release(&mut dst, new_value);
atomic_store_relaxed(&mut dst, new_value);
- // atomic_store_unordered(&mut dst, new_value);
+ atomic_store_unordered(&mut dst, new_value);
}
}
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-5.rs b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
index 7fd84dc..ffad0bd 100644
--- a/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-5.rs
@@ -1,4 +1,61 @@
-trait Copy {}
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {
+ fn clone(&self) -> Self;
+
+ fn clone_from(&mut self, source: &Self) {
+ *self = source.clone()
+ }
+}
+
+mod impls {
+ use super::Clone;
+
+ macro_rules! impl_clone {
+ ($($t:ty)*) => {
+ $(
+ impl Clone for $t {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ )*
+ }
+ }
+
+ impl_clone! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+#[lang = "copy"]
+pub trait Copy: Clone {
+ // Empty.
+}
+
+mod copy_impls {
+ use super::Copy;
+
+ macro_rules! impl_copy {
+ ($($t:ty)*) => {
+ $(
+ impl Copy for $t {}
+ )*
+ }
+ }
+
+ impl_copy! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
extern "rust-intrinsic" {
pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, value: T);
@@ -24,6 +81,13 @@ impl VeryLargeType {
}
}
+impl Clone for VeryLargeType {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Copy for VeryLargeType {}
+
fn main() {
let mut dst = VeryLargeType::new(0);
let mut b = false;
diff --git a/gcc/testsuite/rust/execute/torture/atomic_load.rs b/gcc/testsuite/rust/execute/torture/atomic_load.rs
index 28ed8ae..6e7383a 100644
--- a/gcc/testsuite/rust/execute/torture/atomic_load.rs
+++ b/gcc/testsuite/rust/execute/torture/atomic_load.rs
@@ -1,4 +1,61 @@
-trait Copy {}
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {
+ fn clone(&self) -> Self;
+
+ fn clone_from(&mut self, source: &Self) {
+ *self = source.clone()
+ }
+}
+
+mod impls {
+ use super::Clone;
+
+ macro_rules! impl_clone {
+ ($($t:ty)*) => {
+ $(
+ impl Clone for $t {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ )*
+ }
+ }
+
+ impl_clone! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+#[lang = "copy"]
+pub trait Copy: Clone {
+ // Empty.
+}
+
+mod copy_impls {
+ use super::Copy;
+
+ macro_rules! impl_copy {
+ ($($t:ty)*) => {
+ $(
+ impl Copy for $t {}
+ )*
+ }
+ }
+
+ impl_copy! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
extern "rust-intrinsic" {
pub fn atomic_load_seqcst<T: Copy>(src: *const T) -> T;
diff --git a/gcc/testsuite/rust/execute/torture/atomic_store.rs b/gcc/testsuite/rust/execute/torture/atomic_store.rs
index 9f248b4..46960a7 100644
--- a/gcc/testsuite/rust/execute/torture/atomic_store.rs
+++ b/gcc/testsuite/rust/execute/torture/atomic_store.rs
@@ -1,4 +1,61 @@
-trait Copy {}
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {
+ fn clone(&self) -> Self;
+
+ fn clone_from(&mut self, source: &Self) {
+ *self = source.clone()
+ }
+}
+
+mod impls {
+ use super::Clone;
+
+ macro_rules! impl_clone {
+ ($($t:ty)*) => {
+ $(
+ impl Clone for $t {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ )*
+ }
+ }
+
+ impl_clone! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
+
+#[lang = "copy"]
+pub trait Copy: Clone {
+ // Empty.
+}
+
+mod copy_impls {
+ use super::Copy;
+
+ macro_rules! impl_copy {
+ ($($t:ty)*) => {
+ $(
+ impl Copy for $t {}
+ )*
+ }
+ }
+
+ impl_copy! {
+ usize u8 u16 u32 u64 // u128
+ isize i8 i16 i32 i64 // i128
+ f32 f64
+ bool char
+ }
+}
extern "rust-intrinsic" {
pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);