]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: borrowck: Testsuite
authorJakub Dupak <dev@jakubdupak.com>
Wed, 24 Apr 2024 11:47:20 +0000 (13:47 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 17 Mar 2025 15:35:22 +0000 (16:35 +0100)
gcc/testsuite/ChangeLog:

* rust/borrowck/borrowck.exp: New test.
* rust/borrowck/position_dependant_outlives.rs: New test.
* rust/borrowck/reference.rs: New test.
* rust/borrowck/return_ref_to_local.rs: New test.
* rust/borrowck/subset.rs: New test.
* rust/borrowck/test_move.rs: New test.
* rust/borrowck/test_move_behind_reference.rs: New test.
* rust/borrowck/test_move_conditional.rs: New test.
* rust/borrowck/tmp.rs: New test.
* rust/borrowck/use_while_mut.rs: New test.
* rust/borrowck/use_while_mut_fr.rs: New test.
* rust/borrowck/well_formed_function_inputs.rs: New test.

12 files changed:
gcc/testsuite/rust/borrowck/borrowck.exp [new file with mode: 0644]
gcc/testsuite/rust/borrowck/position_dependant_outlives.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/reference.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/return_ref_to_local.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/subset.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/test_move.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/test_move_behind_reference.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/test_move_conditional.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/tmp.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/use_while_mut.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/use_while_mut_fr.rs [new file with mode: 0644]
gcc/testsuite/rust/borrowck/well_formed_function_inputs.rs [new file with mode: 0644]

diff --git a/gcc/testsuite/rust/borrowck/borrowck.exp b/gcc/testsuite/rust/borrowck/borrowck.exp
new file mode 100644 (file)
index 0000000..6e96a7d
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (C) 2021-2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Compile tests, no torture testing.
+#
+# These tests raise errors in the front end; torture testing doesn't apply.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "compile"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" ""
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rust/borrowck/position_dependant_outlives.rs b/gcc/testsuite/rust/borrowck/position_dependant_outlives.rs
new file mode 100644 (file)
index 0000000..7856934
--- /dev/null
@@ -0,0 +1,11 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+
+pub fn position_dependent_outlives<'a>(x: &'a mut i32, cond: bool) -> &'a mut i32 {
+    let y = &mut *x;
+    if cond {
+        return y;
+    } else {
+        *x = 0;
+        return x;
+    }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/borrowck/reference.rs b/gcc/testsuite/rust/borrowck/reference.rs
new file mode 100644 (file)
index 0000000..b825a96
--- /dev/null
@@ -0,0 +1,99 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+
+
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Reference<'a> {
+    value: &'a i32,
+}
+
+impl<'a> Reference<'a> {
+    fn new<'a>(value: &'a i32) -> Reference<'a> {
+        Reference { value: value }
+    }
+}
+
+struct ReferenceMut<'a> {
+    value: &'a mut i32,
+}
+
+impl<'a> ReferenceMut<'a> {
+    fn new<'a>(value: &'a mut i32) -> ReferenceMut<'a> {
+        ReferenceMut { value: value }
+    }
+}
+
+fn immutable_borrow_while_immutable_borrowed_struct() {
+    let x = 0;
+    let y = Reference::new(&x);
+    let z = &x;
+    let w = y;
+}
+
+fn immutable_borrow_while_mutable_borrowed_struct() {
+    // { dg-error "Found loan errors in function immutable_borrow_while_mutable_borrowed_struct" "" { target *-*-* } .-1 }
+    let mut x = 0;
+    let y = ReferenceMut::new(&mut x);
+    let z = &x; //~ ERROR
+    let w = y;
+}
+
+fn mutable_borrow_while_immutable_borrowed_struct() {
+    // { dg-error "Found loan errors in function mutable_borrow_while_immutable_borrowed_struct" "" { target *-*-* } .-1 }
+    let x = 0;
+    let y = Reference::new(&x);
+    let z = &mut x; //~ ERROR
+    let w = y;
+}
+
+fn mutable_borrow_while_mutable_borrowed_struct() {
+    // { dg-error "Found loan errors in function mutable_borrow_while_mutable_borrowed_struct" "" { target *-*-* } .-1 }
+    let mut x = 0;
+    let y = ReferenceMut::new(&mut x);
+    let z = &mut x; //~ ERROR
+    let w = y;
+}
+
+fn immutable_reborrow_while_immutable_borrowed_struct() {
+    let x = 0;
+    let y = Reference::new(&x);
+    let z = &*y.value;
+}
+
+fn immutable_reborrow_while_mutable_borrowed_struct() {
+    let mut x = 0;
+    let y = Reference::new(&mut x);
+    let z = &*y.value;
+}
+
+fn mutable_reborrow_while_immutable_borrowed_struct() {
+    // { dg-error "Cannot reborrow immutable borrow as mutable" "" { target *-*-* } .-1 }
+    let x = 0;
+    let y = Reference::new(&x);
+    let z = &mut *y.value; //~ ERROR
+}
+
+fn read_while_mutable_borrowed_struct() {
+    // { dg-error "Found loan errors in function read_while_mutable_borrowed_struct" "" { target *-*-* } .-1 }
+    let mut x = 0;
+    let y = ReferenceMut::new(&mut x);
+    let z = x; //~ ERROR
+    let w = y;
+}
+
+fn write_while_borrowed_struct() {
+    // { dg-error "Found loan errors in function write_while_borrowed_struct" "" { target *-*-* } .-1 }
+    let mut x = 0;
+    let y = Reference::new(&x);
+    x = 1; //~ ERROR
+    let z = y;
+}
+
+fn write_while_immutable_borrowed_struct() {
+    // { dg-error "Found loan errors in function write_while_immutable_borrowed_struct" "" { target *-*-* } .-1 }
+    let x = 0;
+    let y = Reference::new(&x);
+    x = 1; //~ ERROR
+    let z = y;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/borrowck/return_ref_to_local.rs b/gcc/testsuite/rust/borrowck/return_ref_to_local.rs
new file mode 100644 (file)
index 0000000..994dc5d
--- /dev/null
@@ -0,0 +1,6 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+
+pub fn return_ref_to_local() -> &'static i32 { // { dg-error "Found loan errors in function return_ref_to_local" }
+    let x = 0;
+    &x //~ ERROR
+}
diff --git a/gcc/testsuite/rust/borrowck/subset.rs b/gcc/testsuite/rust/borrowck/subset.rs
new file mode 100644 (file)
index 0000000..d7c00ca
--- /dev/null
@@ -0,0 +1,27 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+
+fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
+    // { dg-error "Found subset errors in function missing_subset" "" { target *-*-* } .-1 }
+    y //~ ERROR
+}
+
+fn missing_subset_fixed<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 where 'b: 'a {
+    y
+}
+
+fn complex_cfg_subset<'a, 'b>(b: bool, x: &'a u32, y: &'b u32) -> &'a u32 {
+    // { dg-error "Found subset errors in function complex_cfg_subset" "" { target *-*-* } .-1 }
+    if b {
+        y //~ ERROR
+    } else {
+        x
+    }
+}
+
+fn complex_cfg_subset_fixed<'a, 'b>(b: bool, x: &'a u32, y: &'b u32) -> &'a u32 where 'b: 'a {
+    if b {
+        x
+    } else {
+        y
+    }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/borrowck/test_move.rs b/gcc/testsuite/rust/borrowck/test_move.rs
new file mode 100644 (file)
index 0000000..2b5e0c3
--- /dev/null
@@ -0,0 +1,16 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+fn test_move() { // { dg-error "Found move errors in function test_move" }
+    struct A {
+        i: i32,
+    }
+    let a = A { i: 1 };
+    let b = a;
+    let c = a;
+}
+
+fn test_move_fixed() {
+
+    let a = 1; // a is now primitive and can be copied
+    let b = a;
+    let c = b;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/borrowck/test_move_behind_reference.rs b/gcc/testsuite/rust/borrowck/test_move_behind_reference.rs
new file mode 100644 (file)
index 0000000..1349752
--- /dev/null
@@ -0,0 +1,27 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+fn test_move_behind_reference() {
+    // { dg-error "Cannot move from behind a reference." "" { target *-*-* } .-1 }
+    struct A {
+        i: i32,
+    }
+    struct B {
+        a: A,
+    }
+    let a = A { i: 1 };
+    let b = B { a };
+    let c = &b;
+    let d = c.a;
+}
+
+fn test_move_behind_reference_fixed() {
+    struct A {
+        i: i32,
+    }
+    struct B {
+        a: A,
+    }
+    let a = A { i: 1 };
+    let b = B { a };
+    let c = b;
+    let d = c.a;
+}
diff --git a/gcc/testsuite/rust/borrowck/test_move_conditional.rs b/gcc/testsuite/rust/borrowck/test_move_conditional.rs
new file mode 100644 (file)
index 0000000..e1e8e20
--- /dev/null
@@ -0,0 +1,28 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+
+fn test_move_conditional(b1: bool, b2:bool) { // { dg-error "Found move errors in function test_move" }
+    struct A {
+        i: i32,
+    }
+
+    let a = A { i: 1 };
+    let b = a;
+    if b1 {
+        let b = a;
+    }
+    if b2 {
+        let c = a;
+    }
+}
+
+fn test_move_fixed(b1: bool, b2:bool) {
+
+    let a = 1; // a is now primitive and can be copied
+    let b = a;
+    if b1 {
+        let b = a;
+    }
+    if b2 {
+        let c = a;
+    }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/borrowck/tmp.rs b/gcc/testsuite/rust/borrowck/tmp.rs
new file mode 100644 (file)
index 0000000..a604bea
--- /dev/null
@@ -0,0 +1,79 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+
+#[lang = "sized"]
+pub trait Sized {}
+
+fn immutable_borrow_while_immutable_borrowed() {
+    let x = 0;
+    let y = &x;
+    let z = &x;
+    let w = y;
+}
+
+
+fn immutable_borrow_while_mutable_borrowed() {
+    // { dg-error "Found loan errors in function immutable_borrow_while_mutable_borrowed" "" { target *-*-* } .-1 }
+    let mut x = 0;
+    let y = &mut x;
+    let z = &x; //~ ERROR
+    let w = y;
+}
+
+fn mutable_borrow_while_immutable_borrowed() {
+    // { dg-error "Found loan errors in function mutable_borrow_while_immutable_borrowed" "" { target *-*-* } .-1 }
+    let x = 0;
+    let y = &x;
+    let z = &mut x; //~ ERROR
+    let w = y;
+}
+
+fn mutable_borrow_while_mutable_borrowed() {
+    // { dg-error "Found loan errors in function mutable_borrow_while_mutable_borrowed" "" { target *-*-* } .-1 }
+    let mut x = 0;
+    let y = &mut x;
+    let z = &mut x; //~ ERROR
+    let w = y;
+}
+
+fn immutable_reborrow_while_immutable_borrowed() {
+    let x = 0;
+    let y = &x;
+    let z = &*y;
+}
+
+fn immutable_reborrow_while_mutable_borrowed() {
+    let mut x = 0;
+    let y = &mut x;
+    let z = &*y;
+}
+
+fn mutable_reborrow_while_immutable_borrowed() {
+    // { dg-error "Cannot reborrow immutable borrow as mutable" "" { target *-*-* } .-1 }
+    let x = 0;
+    let y = &x;
+    let z = &mut *y; //~ ERROR
+}
+
+fn read_while_mutable_borrowed() {
+    // { dg-error "Found loan errors in function read_while_mutable_borrowed" "" { target *-*-* } .-1 }
+    let mut x = 0;
+    let y = &mut x;
+    let z = x; //~ ERROR
+    let w = y;
+}
+
+fn write_while_borrowed() {
+    // { dg-error "Found loan errors in function write_while_borrowed" "" { target *-*-* } .-1 }
+    let mut x = 0;
+    let y = &x;
+    x = 1; //~ ERROR
+    let z = y;
+}
+
+fn write_while_immutable_borrowed() {
+    // { dg-error "Found loan errors in function write_while_immutable_borrowed" "" { target *-*-* } .-1 }
+    let x = 0;
+    let y = &x;
+    x = 1; //~ ERROR
+    let z = y;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/borrowck/use_while_mut.rs b/gcc/testsuite/rust/borrowck/use_while_mut.rs
new file mode 100644 (file)
index 0000000..57ed255
--- /dev/null
@@ -0,0 +1,7 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+pub fn use_while_mut() {  // { dg-error "Found loan errors in function use_while_mut" }
+    let mut x = 0;
+    let y = &mut x;
+    let z = x; //~ ERROR
+    let w = y;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/borrowck/use_while_mut_fr.rs b/gcc/testsuite/rust/borrowck/use_while_mut_fr.rs
new file mode 100644 (file)
index 0000000..736aac0
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+
+pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 {  // { dg-error "Found loan errors in function use_while_mut_fr" }
+    let y = &mut *x;
+    let z = x; //~ ERROR
+    y
+}
+
diff --git a/gcc/testsuite/rust/borrowck/well_formed_function_inputs.rs b/gcc/testsuite/rust/borrowck/well_formed_function_inputs.rs
new file mode 100644 (file)
index 0000000..6815f44
--- /dev/null
@@ -0,0 +1,16 @@
+// { dg-additional-options "-frust-compile-until=compilation -frust-borrowcheck" }
+
+fn foo<'a, 'b>(p: &'b &'a mut usize) -> &'b&'a mut usize {
+    p
+}
+
+fn well_formed_function_inputs() { // { dg-error "Found loan errors in function well_formed_function_inputs" }
+    let s = &mut 1;
+    let r = &mut *s;
+    let tmp = foo(&r  );
+    // let arg = &r;
+    // let aarg = &*arg;
+    // let tmp = arg;
+    s; //~ ERROR
+    tmp;
+}
\ No newline at end of file