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

Function Contracts: Support for defining and checking requires and ensures clauses #2655

Merged
merged 41 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
32b37f3
Everything needed for requires/ensures checking
JustusAdam Aug 3, 2023
a2535d7
Formatting
JustusAdam Aug 3, 2023
624f406
The only clippy suggestion 🙌🏻
JustusAdam Aug 3, 2023
5a4ad83
Adjust test case
JustusAdam Aug 3, 2023
a272350
Seriously?
JustusAdam Aug 3, 2023
f0a011b
A check for mutable pointers
JustusAdam Aug 3, 2023
1429564
Whoops
JustusAdam Aug 3, 2023
1dd96dc
Last minute pivot in check function implementation
JustusAdam Aug 4, 2023
78739d8
Postcondition injection on every return
JustusAdam Aug 4, 2023
81cd5c8
Whoops
JustusAdam Aug 4, 2023
e07eec9
Documentation and emit block in injector
JustusAdam Aug 4, 2023
9b2d9a0
Incorporate more sysroot comments.
JustusAdam Aug 4, 2023
01dfbc0
More comments addressed
JustusAdam Aug 4, 2023
16b9cc5
Whitespace
JustusAdam Aug 4, 2023
5ee744c
Reverting proc macro refactoring
JustusAdam Aug 9, 2023
665b271
Merge remote-tracking branch 'fork/main' into simple-contacts-checking
JustusAdam Aug 10, 2023
fe71b62
Apply suggestions from code review
JustusAdam Aug 10, 2023
387280f
Reformatting tests after celina's feeback
JustusAdam Aug 10, 2023
a8f0929
Rename harnesses
JustusAdam Aug 10, 2023
ac73461
Remove enum map dependency
JustusAdam Aug 10, 2023
e558226
Lots of docuemntation expansion and a few fixes
JustusAdam Aug 10, 2023
ba84599
Yes I didn't need this
JustusAdam Aug 10, 2023
c8b137c
Update library/kani/src/lib.rs
JustusAdam Aug 16, 2023
d53a5a8
Add documentation for attribute enum and remove unused attribute
JustusAdam Aug 16, 2023
b81c45a
Adding requested changes
JustusAdam Aug 16, 2023
6aa6b22
Remove unused compiler flag
JustusAdam Aug 16, 2023
4c475b6
Expand test case
JustusAdam Aug 16, 2023
71711a0
An unused collect
JustusAdam Aug 16, 2023
98ccfa5
Split pointer prohibition tests
JustusAdam Aug 21, 2023
1a331a2
Merge branch 'main' into simple-contacts-checking
JustusAdam Aug 21, 2023
98db699
Merge remote-tracking branch 'fork/main' into simple-contacts-checking
JustusAdam Aug 21, 2023
1938aa5
Format?
JustusAdam Aug 21, 2023
36b0dee
Seriously?
JustusAdam Aug 22, 2023
107b582
Comply with lifetime variables in fun sigs
JustusAdam Aug 23, 2023
c6a4a0e
Only complain for active contract attributes
JustusAdam Aug 23, 2023
e1fadd4
Addressing more comments
JustusAdam Aug 25, 2023
a0b00a2
I always forget to run thi script instead of `cargo fmt`
JustusAdam Aug 26, 2023
5447973
Apply suggestions from code review
JustusAdam Sep 6, 2023
e424b26
Suggestions from code review
JustusAdam Sep 6, 2023
702571b
Merge remote-tracking branch 'fork/main' into simple-contacts-checking
JustusAdam Sep 6, 2023
b5499f6
Merge remote-tracking branch 'fork/main' into simple-contacts-checking
JustusAdam Sep 7, 2023
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
21 changes: 21 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,26 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"

[[package]]
name = "enum-map"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9705d8de4776df900a4a0b2384f8b0ab42f775e93b083b42f8ce71bdc32a47e3"
dependencies = [
"enum-map-derive",
]

[[package]]
name = "enum-map-derive"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccb14d927583dd5c2eac0f2cf264fc4762aefe1ae14c47a8a20fc1939d3a5fc0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.27",
]

[[package]]
name = "equivalent"
version = "1.0.1"
Expand Down Expand Up @@ -495,6 +515,7 @@ version = "0.33.0"
dependencies = [
"clap",
"cprover_bindings",
"enum-map",
"home",
"itertools",
"kani_metadata",
Expand Down
1 change: 1 addition & 0 deletions kani-compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ strum_macros = "0.24.0"
shell-words = "1.0.0"
tracing = {version = "0.1", features = ["max_level_trace", "release_max_level_debug"]}
tracing-subscriber = {version = "0.3.8", features = ["env-filter", "json", "fmt"]}
enum-map = "2.6"

# Future proofing: enable backend dependencies using feature.
[features]
Expand Down
38 changes: 38 additions & 0 deletions kani-compiler/src/codegen_cprover_gotoc/overrides/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,43 @@ impl<'tcx> GotocHook<'tcx> for MemCmp {
}
}

/// A builtin that is essentially a C-style dereference operation, creating an
/// unsafe challow copy. Importantly either this copy or the original needs to
JustusAdam marked this conversation as resolved.
Show resolved Hide resolved
/// be `mem::forget`en or a double-free will occur.
///
/// Takes in a `&T` reference and returns a `T` (like clone would but without
/// cloning). Breaks ownership rules and is only used in the context of function
/// contracts where we can structurally guarantee the use is safe.
struct UntrackedDeref;

impl<'tcx> GotocHook<'tcx> for UntrackedDeref {
fn hook_applies(&self, tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
matches_function(tcx, instance, "KaniUntrackedDeref")
}

fn handle(
&self,
tcx: &mut GotocCtx<'tcx>,
_instance: Instance<'tcx>,
mut fargs: Vec<Expr>,
assign_to: Place<'tcx>,
_target: Option<BasicBlock>,
span: Option<Span>,
) -> Stmt {
assert_eq!(fargs.len(), 1);
JustusAdam marked this conversation as resolved.
Show resolved Hide resolved
let loc = tcx.codegen_span_option(span);
Stmt::block(
vec![Stmt::assign(
unwrap_or_return_codegen_unimplemented_stmt!(tcx, tcx.codegen_place(&assign_to))
.goto_expr,
fargs.pop().unwrap().dereference(),
loc,
)],
loc,
)
}
}

pub fn fn_hooks<'tcx>() -> GotocHooks<'tcx> {
GotocHooks {
hooks: vec![
Expand All @@ -335,6 +372,7 @@ pub fn fn_hooks<'tcx>() -> GotocHooks<'tcx> {
Rc::new(Nondet),
Rc::new(RustAlloc),
Rc::new(MemCmp),
Rc::new(UntrackedDeref),
],
}
}
Expand Down
5 changes: 4 additions & 1 deletion kani-compiler/src/kani_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ impl Callbacks for KaniCompiler {
queries.unstable_features = features.cloned().collect::<Vec<_>>();
}

queries.function_contracts_enabled =
queries.unstable_features.iter().any(|s| s == "function-contracts");

if matches.get_flag(parser::ENABLE_STUBBING)
&& queries.reachability_analysis == ReachabilityType::Harnesses
{
Expand All @@ -419,7 +422,7 @@ impl Callbacks for KaniCompiler {
) -> Compilation {
if self.stage.is_init() {
self.stage = rustc_queries.global_ctxt().unwrap().enter(|tcx| {
check_crate_items(tcx, self.queries.lock().unwrap().ignore_global_asm);
check_crate_items(tcx, &self.queries.lock().unwrap());
self.process_harnesses(tcx)
});
}
Expand Down
Loading
Loading