-
Notifications
You must be signed in to change notification settings - Fork 109
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
have to be declared separately elsewhere move the foreign_mods test from parse to cargo_verify; add a C source file that is compiled a linked to it add a parse fail test having #[extern_spec] instead of
- Loading branch information
Showing
15 changed files
with
129 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 16 additions & 28 deletions
44
prusti-contracts/prusti-specs/src/extern_spec_rewriter/foreign_mods.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,25 @@ | ||
//! Process external specifications in Rust foreign modules marked with | ||
//! the #[extern_spec] attribute. | ||
use super::common::generate_extern_spec_foreign_function_stub; | ||
use crate::{ | ||
extract_prusti_attributes, generate_spec_and_assertions, specifications::untyped::AnyFnItem, | ||
ExternSpecKind, | ||
}; | ||
use super::functions::rewrite_stub; | ||
use proc_macro2::TokenStream; | ||
use quote::{quote, ToTokens}; | ||
use quote::ToTokens; | ||
use syn::spanned::Spanned; | ||
|
||
pub fn rewrite_extern_spec(item_foreign_mod: &mut syn::ItemForeignMod) -> syn::Result<TokenStream> { | ||
let mut specs = vec![]; | ||
for item in item_foreign_mod.items.iter_mut() { | ||
if let syn::ForeignItem::Fn(item_fn) = item { | ||
specs.extend(rewrite_fn(item_fn)?); | ||
pub fn rewrite_extern_spec( | ||
item_foreign_mod: &syn::ItemForeignMod, | ||
path: &syn::Path, | ||
) -> syn::Result<TokenStream> { | ||
let mut res = TokenStream::new(); | ||
for item in item_foreign_mod.items.iter() { | ||
match item { | ||
syn::ForeignItem::Fn(item_fn) => { | ||
let tokens = rewrite_stub(&item_fn.to_token_stream(), path, true); | ||
res.extend(tokens); | ||
} | ||
// eventually: handle specs for foreign variables (statics) | ||
_ => return Err(syn::Error::new(item.span(), "unexpected item")), | ||
} | ||
// eventually: handle specs for foreign variables | ||
} | ||
|
||
let mut res = TokenStream::new(); | ||
res.extend(specs.iter().map(syn::Item::to_token_stream)); | ||
res.extend(quote!(#item_foreign_mod)); | ||
Ok(res) | ||
} | ||
|
||
fn rewrite_fn(item_fn: &mut syn::ForeignItemFn) -> Result<Vec<syn::Item>, syn::Error> { | ||
let stub_fn: syn::ForeignItemFn = | ||
generate_extern_spec_foreign_function_stub(item_fn, ExternSpecKind::Method); | ||
let mut stub_fn = AnyFnItem::ForeignFn(stub_fn); | ||
let prusti_attributes = extract_prusti_attributes(&mut stub_fn); | ||
let (spec_items, generated_attributes) = | ||
generate_spec_and_assertions(prusti_attributes, &stub_fn)?; | ||
stub_fn.attrs_mut().extend(generated_attributes); | ||
*item_fn = stub_fn.expect_foreign_item_fn(); | ||
Ok(spec_items) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "foreign_mods" | ||
version = "0.1.0" | ||
edition = "2021" | ||
build = "build.rs" | ||
|
||
[dependencies] | ||
prusti-contracts = { path = "prusti-contracts/prusti-contracts" } # The test suite will prepare a symbolic link for this | ||
|
||
[build-dependencies] | ||
cc = "1.0" | ||
|
||
# Declare that this crate is not part of a workspace | ||
[workspace] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
fn main() { | ||
cc::Build::new() | ||
.file("src/clib.c") | ||
.compile("clib"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include <stdint.h> | ||
|
||
int32_t max(int32_t a, int32_t b) { | ||
return a > b ? a : b; | ||
} | ||
|
||
void unannotated(void) { | ||
} | ||
|
||
int32_t abs(int32_t a) { | ||
return a >= 0 ? a : -a; | ||
} |
10 changes: 9 additions & 1 deletion
10
...ts/parse/pass/extern-spec/foreign_mods.rs → ...sts/cargo_verify/foreign_mods/src/main.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use prusti_contracts::*; | ||
|
||
fn identity(a: i32) -> i32 { | ||
a | ||
} | ||
|
||
#[extern_spec] // should be #[extern_spec(crate)] in this case | ||
#[ensures(a == 0 ==> result == 0)] | ||
fn identity(a: i32) -> i32; //~ ERROR: cannot find crate `identity` in the list of imported crates | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters