Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added more tests for Drop #1285

Merged
merged 19 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c1c71df
Temp commit to suppress aarch64 (m1)issues. Do not commit to master.
YoshikiTakashima Jun 14, 2022
2894176
Added enum drop only 1 test. TODO: Add to regressions.
YoshikiTakashima Jun 14, 2022
e7b9e30
Merge branch 'main' of github.com:model-checking/kani into yoshi-drop…
YoshikiTakashima Jun 15, 2022
aa3170a
Errata: Redundant asert, unused trait, and incorrect comment.
YoshikiTakashima Jun 15, 2022
766b785
Made selective drop be the inner type inside enum.
YoshikiTakashima Jun 15, 2022
5de7ff5
Merge branch 'main' of github.com:model-checking/kani into yoshi-drop…
YoshikiTakashima Jun 16, 2022
fda6565
Add test for drop of objects that are moved into closures.
YoshikiTakashima Jun 16, 2022
beaf2d8
Added tests dropping after ownership move: channel and RC+Refcell.
YoshikiTakashima Jun 16, 2022
0dc3b89
Undid M1 mac aarch hack
YoshikiTakashima Jun 16, 2022
bca58b6
Added comment for why test case is fixme.
YoshikiTakashima Jun 16, 2022
5317bfa
fixed is/are typo
YoshikiTakashima Jun 16, 2022
6057cd1
Use kani::any() instead of input.
YoshikiTakashima Jun 16, 2022
5c57e17
Added link to issue.
YoshikiTakashima Jun 16, 2022
0f35141
Changed to inner comment.
YoshikiTakashima Jun 16, 2022
75cc1c7
Changed to inner comment. Forgot 3 other files.
YoshikiTakashima Jun 16, 2022
5f5203b
Added assertion to check for update.
YoshikiTakashima Jun 16, 2022
53e5177
Moved all drop-related ests to tests/kani/Drop
YoshikiTakashima Jun 16, 2022
e7996f1
Added test case for forgotten memory.
YoshikiTakashima Jun 16, 2022
1892f3a
Merge branch 'main' into yoshi-drop-tests
YoshikiTakashima Jun 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions tests/kani/Drop/drop_after_move_closure_call.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! This test checks that structs moved into Box<Fn> are dropped when
//! the function is dropped.
static mut CELL: i32 = 0;

struct DropIncrementCELLByOne {}

impl DropIncrementCELLByOne {
fn do_nothing(&self) {}
}

impl Drop for DropIncrementCELLByOne {
fn drop(&mut self) {
unsafe {
CELL += 1;
}
}
}

#[kani::proof]
fn main() {
{
let object_to_drop = DropIncrementCELLByOne {};
let fun: Box<dyn FnOnce() -> ()> = Box::new(move || {
object_to_drop.do_nothing();
});

fun();
}
assert_eq!(unsafe { CELL }, 1, "Drop should be called when move fn is used");

{
let object_to_drop = DropIncrementCELLByOne {};
let _fun: Box<dyn FnOnce() -> ()> = Box::new(move || {
object_to_drop.do_nothing();
});
}
assert_eq!(unsafe { CELL }, 2, "Drop should still be called when move fn is not used");
}
54 changes: 54 additions & 0 deletions tests/kani/Drop/drop_after_mutating_refcell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! This test checks whether dropping after mutating with
//! Rc<Refcell<>> is handled correctly.
//
// Note: If you were to use Rc<RefCell<dyn CELLValueInFuture>>, then
// kani will fail with an unsupported feature error. This is because
// RefCell uses UnsafeCell inside, and that is not entirely supported
// as of kani 0.4.0.

use std::cell::RefCell;
use std::rc::Rc;

static mut CELL: i32 = 0;

trait CELLValueInFuture {
fn set_inner_value(&mut self, new_value: i32);
fn get_inner_value(&self) -> i32;
}

struct DropSetCELLToInner {
set_cell_to: i32,
}

impl CELLValueInFuture for DropSetCELLToInner {
fn set_inner_value(&mut self, new_value: i32) {
self.set_cell_to = new_value;
}

fn get_inner_value(&self) -> i32 {
self.set_cell_to
}
}

impl Drop for DropSetCELLToInner {
fn drop(&mut self) {
unsafe {
CELL = self.get_inner_value();
}
}
}

#[kani::proof]
fn main() {
{
let set_to_one = DropSetCELLToInner { set_cell_to: 1 };
YoshikiTakashima marked this conversation as resolved.
Show resolved Hide resolved
let wrapped_drop: Rc<RefCell<DropSetCELLToInner>> = Rc::new(RefCell::new(set_to_one));

wrapped_drop.borrow_mut().set_inner_value(2);
assert_eq!(wrapped_drop.borrow().get_inner_value(), 2, "Value should be updated.");
}
assert_eq!(unsafe { CELL }, 2, "Drop should be called. New value used during drop.");
}
41 changes: 41 additions & 0 deletions tests/kani/Drop/drop_enum_only_one_called.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! Property that dropping enum drops exactly 1 case.
static mut CELL: i32 = 0;

struct IncrementCELLWhenDropped {
increment_by: i32,
}

impl Drop for IncrementCELLWhenDropped {
fn drop(&mut self) {
unsafe {
CELL += self.increment_by;
}
}
}

enum EnumWithTwoIncrements {
Add1(IncrementCELLWhenDropped),
Add2(IncrementCELLWhenDropped),
}

fn get_random_enum_variant() -> EnumWithTwoIncrements {
if kani::any() {
EnumWithTwoIncrements::Add1(IncrementCELLWhenDropped { increment_by: 1 })
} else {
EnumWithTwoIncrements::Add2(IncrementCELLWhenDropped { increment_by: 2 })
}
}

#[kani::proof]
fn main() {
{
let _e1 = get_random_enum_variant();
}
unsafe {
assert!(CELL == 1 || CELL == 2);
}
}
35 changes: 35 additions & 0 deletions tests/kani/Drop/fixme_drop_after_moving_across_channel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! This test checks whether dropping objects passed through
//! std::sync::mpsc::channel is handled.
//
// This test case fails to resolve in a reasonable amount of
YoshikiTakashima marked this conversation as resolved.
Show resolved Hide resolved
// time. Settign kani::unwind(1) is insufficient for verification, but
YoshikiTakashima marked this conversation as resolved.
Show resolved Hide resolved
// kani::unwind(2) takes longer than 10m on a M1 Mac. For details,
// please see: https://github.com/model-checking/kani/issues/1286

use std::sync::mpsc::*;

static mut CELL: i32 = 0;

struct DropSetCELLToOne {}

impl Drop for DropSetCELLToOne {
fn drop(&mut self) {
unsafe {
CELL = 1;
}
}
}

#[kani::unwind(1)]
#[kani::proof]
fn main() {
{
let (send, recv) = channel::<DropSetCELLToOne>();
send.send(DropSetCELLToOne {}).unwrap();
let _to_drop: DropSetCELLToOne = recv.recv().unwrap();
}
assert_eq!(unsafe { CELL }, 1, "Drop should be called");
}
27 changes: 27 additions & 0 deletions tests/kani/Drop/forget_no_drop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! Tests the property that if you let memory leak via
//! std::mem::forget, drop will not be called.
static mut CELL: i32 = 0;

struct IncrementCELLWhenDropped;
impl Drop for IncrementCELLWhenDropped {
fn drop(&mut self) {
unsafe {
CELL = 1;
}
}
}

#[kani::proof]
fn main() {
{
let x1 = IncrementCELLWhenDropped {};
std::mem::forget(x1);
}
unsafe {
assert!(CELL == 0);
}
}
File renamed without changes.