https://gcc.gnu.org/g:531db510f9e1fa34133bf98af56106c5c22dd3e7
commit r15-8098-g531db510f9e1fa34133bf98af56106c5c22dd3e7 Author: Jakub Dupak <d...@jakubdupak.com> Date: Wed Apr 24 13:47:20 2024 +0200 gccrs: borrowck: Testsuite 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. Diff: --- gcc/testsuite/rust/borrowck/borrowck.exp | 35 ++++++++ .../rust/borrowck/position_dependant_outlives.rs | 11 +++ gcc/testsuite/rust/borrowck/reference.rs | 99 ++++++++++++++++++++++ gcc/testsuite/rust/borrowck/return_ref_to_local.rs | 6 ++ gcc/testsuite/rust/borrowck/subset.rs | 27 ++++++ gcc/testsuite/rust/borrowck/test_move.rs | 16 ++++ .../rust/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 ++ gcc/testsuite/rust/borrowck/use_while_mut_fr.rs | 8 ++ .../rust/borrowck/well_formed_function_inputs.rs | 16 ++++ 12 files changed, 359 insertions(+) diff --git a/gcc/testsuite/rust/borrowck/borrowck.exp b/gcc/testsuite/rust/borrowck/borrowck.exp new file mode 100644 index 000000000000..6e96a7d11d87 --- /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 000000000000..7856934a6b36 --- /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 000000000000..b825a9686b75 --- /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 000000000000..994dc5d358ba --- /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 000000000000..d7c00ca966c1 --- /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 000000000000..2b5e0c37bb51 --- /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 000000000000..1349752356ac --- /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 000000000000..e1e8e2025cf1 --- /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 000000000000..a604bea3d91c --- /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 000000000000..57ed25521a9a --- /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 000000000000..736aac0279df --- /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 000000000000..6815f44fc696 --- /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