From: Jakub Dupak <[email protected]>
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.
---
gcc/testsuite/rust/borrowck/borrowck.exp | 35 +++++++
.../borrowck/position_dependant_outlives.rs | 11 +++
gcc/testsuite/rust/borrowck/reference.rs | 99 +++++++++++++++++++
.../rust/borrowck/return_ref_to_local.rs | 6 ++
gcc/testsuite/rust/borrowck/subset.rs | 27 +++++
gcc/testsuite/rust/borrowck/test_move.rs | 16 +++
.../borrowck/test_move_behind_reference.rs | 27 +++++
.../rust/borrowck/test_move_conditional.rs | 28 ++++++
gcc/testsuite/rust/borrowck/tmp.rs | 79 +++++++++++++++
gcc/testsuite/rust/borrowck/use_while_mut.rs | 7 ++
.../rust/borrowck/use_while_mut_fr.rs | 8 ++
.../borrowck/well_formed_function_inputs.rs | 16 +++
12 files changed, 359 insertions(+)
create mode 100644 gcc/testsuite/rust/borrowck/borrowck.exp
create mode 100644 gcc/testsuite/rust/borrowck/position_dependant_outlives.rs
create mode 100644 gcc/testsuite/rust/borrowck/reference.rs
create mode 100644 gcc/testsuite/rust/borrowck/return_ref_to_local.rs
create mode 100644 gcc/testsuite/rust/borrowck/subset.rs
create mode 100644 gcc/testsuite/rust/borrowck/test_move.rs
create mode 100644 gcc/testsuite/rust/borrowck/test_move_behind_reference.rs
create mode 100644 gcc/testsuite/rust/borrowck/test_move_conditional.rs
create mode 100644 gcc/testsuite/rust/borrowck/tmp.rs
create mode 100644 gcc/testsuite/rust/borrowck/use_while_mut.rs
create mode 100644 gcc/testsuite/rust/borrowck/use_while_mut_fr.rs
create mode 100644 gcc/testsuite/rust/borrowck/well_formed_function_inputs.rs
diff --git a/gcc/testsuite/rust/borrowck/borrowck.exp
b/gcc/testsuite/rust/borrowck/borrowck.exp
new file mode 100644
index 00000000000..6e96a7d11d8
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/borrowck.exp
@@ -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
index 00000000000..7856934a6b3
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/position_dependant_outlives.rs
@@ -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
index 00000000000..b825a9686b7
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/reference.rs
@@ -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
index 00000000000..994dc5d358b
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/return_ref_to_local.rs
@@ -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
index 00000000000..d7c00ca966c
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/subset.rs
@@ -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
index 00000000000..2b5e0c37bb5
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/test_move.rs
@@ -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
index 00000000000..1349752356a
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/test_move_behind_reference.rs
@@ -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
index 00000000000..e1e8e2025cf
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/test_move_conditional.rs
@@ -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
index 00000000000..a604bea3d91
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/tmp.rs
@@ -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
index 00000000000..57ed25521a9
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/use_while_mut.rs
@@ -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
index 00000000000..736aac0279d
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/use_while_mut_fr.rs
@@ -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
index 00000000000..6815f44fc69
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/well_formed_function_inputs.rs
@@ -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
--
2.45.2