Skip to content

Commit 649d780

Browse files
authored
Clean up property class and reclassify some checks (rust-lang#1299)
* Clean up property class and mark sanity checks 1. Remove the property classes that weren't being used. 2. Provide a tighter definition for DefaultAssert and reclassify things accordingly. 3. Renamed KaniCheck to SafetyCheck to make it a more meaningful name. * Use strum to convert PropertyClass <-> &str
1 parent 6cfd1b4 commit 649d780

File tree

7 files changed

+68
-66
lines changed

7 files changed

+68
-66
lines changed

Cargo.lock

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,12 @@ dependencies = [
319319
"unicode-segmentation",
320320
]
321321

322+
[[package]]
323+
name = "heck"
324+
version = "0.4.0"
325+
source = "registry+https://github.com/rust-lang/crates.io-index"
326+
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
327+
322328
[[package]]
323329
name = "hermit-abi"
324330
version = "0.1.19"
@@ -397,6 +403,8 @@ dependencies = [
397403
"serde",
398404
"serde_json",
399405
"shell-words",
406+
"strum",
407+
"strum_macros",
400408
"tracing",
401409
"tracing-subscriber",
402410
"tracing-tree",
@@ -864,6 +872,12 @@ dependencies = [
864872
"tracing-tree",
865873
]
866874

875+
[[package]]
876+
name = "rustversion"
877+
version = "1.0.7"
878+
source = "registry+https://github.com/rust-lang/crates.io-index"
879+
checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf"
880+
867881
[[package]]
868882
name = "ryu"
869883
version = "1.0.9"
@@ -984,13 +998,32 @@ version = "0.4.18"
984998
source = "registry+https://github.com/rust-lang/crates.io-index"
985999
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
9861000
dependencies = [
987-
"heck",
1001+
"heck 0.3.3",
9881002
"proc-macro-error",
9891003
"proc-macro2",
9901004
"quote",
9911005
"syn",
9921006
]
9931007

1008+
[[package]]
1009+
name = "strum"
1010+
version = "0.24.1"
1011+
source = "registry+https://github.com/rust-lang/crates.io-index"
1012+
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
1013+
1014+
[[package]]
1015+
name = "strum_macros"
1016+
version = "0.24.0"
1017+
source = "registry+https://github.com/rust-lang/crates.io-index"
1018+
checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef"
1019+
dependencies = [
1020+
"heck 0.4.0",
1021+
"proc-macro2",
1022+
"quote",
1023+
"rustversion",
1024+
"syn",
1025+
]
1026+
9941027
[[package]]
9951028
name = "syn"
9961029
version = "1.0.91"

kani-compiler/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ object = { version = "0.27.0", default-features = false, features = ["std", "rea
2222
rustc-demangle = { version = "0.1.21", optional = true }
2323
serde = { version = "1", optional = true }
2424
serde_json = { version = "1", optional = true }
25+
strum = {version = "0.24.0", optional = true}
26+
strum_macros = {version = "0.24.0", optional = true}
2527
shell-words = "1.0.0"
2628
tracing = {version = "0.1", features = ["max_level_trace", "release_max_level_debug"]}
2729
tracing-subscriber = {version = "0.3.8", features = ["env-filter", "json", "fmt"]}
@@ -30,7 +32,8 @@ tracing-tree = "0.2.0"
3032
# Future proofing: enable backend dependencies using feature.
3133
[features]
3234
default = ['cprover']
33-
cprover = ['ar', 'bitflags', 'cbmc', 'kani_metadata', 'libc', 'num', 'object', 'rustc-demangle', 'serde', 'serde_json']
35+
cprover = ['ar', 'bitflags', 'cbmc', 'kani_metadata', 'libc', 'num', 'object', 'rustc-demangle', 'serde',
36+
'serde_json', "strum", "strum_macros"]
3437

3538
[package.metadata.rust-analyzer]
3639
# This package uses rustc crates.

kani-compiler/src/codegen_cprover_gotoc/codegen/assert.rs

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,27 @@
44
//! This file contains the code that acts as a wrapper to create the new assert and related statements
55
use crate::codegen_cprover_gotoc::GotocCtx;
66
use cbmc::goto_program::{Expr, Location, Stmt};
7+
use std::convert::AsRef;
8+
use strum_macros::{AsRefStr, EnumString};
79

810
/// The Property Class enum stores all viable options for classifying asserts, cover assume and other related statements
9-
#[derive(Debug, Clone)]
10-
#[allow(dead_code)]
11+
#[derive(Debug, Clone, EnumString, AsRefStr)]
12+
#[strum(serialize_all = "snake_case")]
1113
pub enum PropertyClass {
1214
ArithmeticOverflow,
13-
AssertFalse,
1415
Assume,
1516
Cover,
16-
CustomProperty(String),
17-
DefaultAssertion,
17+
/// Assertions and Panic that are not specific to Kani. In a concrete execution, we expect
18+
/// these assertions to be available to the user.
19+
/// E.g.: User assertions, compiler invariant checks
20+
Assertion,
1821
ExactDiv,
1922
ExpectFail,
2023
FiniteCheck,
21-
/// Checks added by Kani compiler to detect UB or unstable behavior.
22-
KaniCheck,
23-
PointerOffset,
24+
/// Checks added by Kani compiler to detect safety conditions violation.
25+
/// E.g., things that trigger UB or unstable behavior.
26+
SafetyCheck,
27+
/// Checks to ensure that Kani's code generation is correct.
2428
SanityCheck,
2529
Unimplemented,
2630
UnsupportedConstruct,
@@ -30,43 +34,7 @@ pub enum PropertyClass {
3034
#[allow(dead_code)]
3135
impl PropertyClass {
3236
pub fn as_str(&self) -> &str {
33-
match self {
34-
PropertyClass::ArithmeticOverflow => "arithmetic_overflow",
35-
PropertyClass::AssertFalse => "assert_false",
36-
PropertyClass::Assume => "assume",
37-
PropertyClass::Cover => "coverage_check",
38-
PropertyClass::CustomProperty(property_string) => property_string.as_str(),
39-
PropertyClass::DefaultAssertion => "assertion",
40-
PropertyClass::ExactDiv => "exact_div",
41-
PropertyClass::ExpectFail => "expect_fail",
42-
PropertyClass::FiniteCheck => "finite_check",
43-
PropertyClass::KaniCheck => "kani_check",
44-
PropertyClass::PointerOffset => "pointer_offset",
45-
PropertyClass::SanityCheck => "sanity_check",
46-
PropertyClass::Unimplemented => "unimplemented",
47-
PropertyClass::Unreachable => "unreachable",
48-
PropertyClass::UnsupportedConstruct => "unsupported_construct",
49-
}
50-
}
51-
52-
pub fn from_str(input: &str) -> PropertyClass {
53-
match input {
54-
"arithmetic_overflow" => PropertyClass::ArithmeticOverflow,
55-
"assert_false" => PropertyClass::AssertFalse,
56-
"assume" => PropertyClass::Assume,
57-
"assertion" => PropertyClass::DefaultAssertion,
58-
"coverage_check" => PropertyClass::Cover,
59-
"exact_div" => PropertyClass::ExactDiv,
60-
"expect_fail" => PropertyClass::ExpectFail,
61-
"finite_check" => PropertyClass::FiniteCheck,
62-
"kani_check" => PropertyClass::KaniCheck,
63-
"pointer_offset" => PropertyClass::PointerOffset,
64-
"sanity_check" => PropertyClass::SanityCheck,
65-
"unimplemented" => PropertyClass::Unimplemented,
66-
"unreachable" => PropertyClass::Unreachable,
67-
"unsupported_construct" => PropertyClass::UnsupportedConstruct,
68-
_ => PropertyClass::CustomProperty(input.to_owned()),
69-
}
37+
self.as_ref()
7038
}
7139
}
7240

kani-compiler/src/codegen_cprover_gotoc/codegen/intrinsic.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,12 @@ impl<'tcx> GotocCtx<'tcx> {
106106
debug!("codegen_never_return_intrinsic:\n\tinstance {:?}\n\tspan {:?}", instance, span);
107107

108108
match intrinsic {
109-
"abort" => self.codegen_fatal_error(
110-
PropertyClass::DefaultAssertion,
111-
"reached intrinsic::abort",
112-
span,
113-
),
109+
"abort" => {
110+
self.codegen_fatal_error(PropertyClass::Assertion, "reached intrinsic::abort", span)
111+
}
114112
// Transmuting to an uninhabited type is UB.
115113
"transmute" => self.codegen_fatal_error(
116-
PropertyClass::DefaultAssertion,
114+
PropertyClass::SafetyCheck,
117115
"transmuting to uninhabited type has undefined behavior",
118116
span,
119117
),
@@ -763,7 +761,7 @@ impl<'tcx> GotocCtx<'tcx> {
763761
// precise error message
764762
if layout.abi.is_uninhabited() {
765763
return self.codegen_fatal_error(
766-
PropertyClass::DefaultAssertion,
764+
PropertyClass::SafetyCheck,
767765
&format!("attempted to instantiate uninhabited type `{}`", ty),
768766
span,
769767
);
@@ -775,7 +773,7 @@ impl<'tcx> GotocCtx<'tcx> {
775773
&& !layout.might_permit_raw_init(self, InitKind::Zero, false)
776774
{
777775
return self.codegen_fatal_error(
778-
PropertyClass::DefaultAssertion,
776+
PropertyClass::SafetyCheck,
779777
&format!("attempted to zero-initialize type `{}`, which is invalid", ty),
780778
span,
781779
);
@@ -785,7 +783,7 @@ impl<'tcx> GotocCtx<'tcx> {
785783
&& !layout.might_permit_raw_init(self, InitKind::Uninit, false)
786784
{
787785
return self.codegen_fatal_error(
788-
PropertyClass::DefaultAssertion,
786+
PropertyClass::SafetyCheck,
789787
&format!("attempted to leave type `{}` uninitialized, which is invalid", ty),
790788
span,
791789
);
@@ -928,14 +926,14 @@ impl<'tcx> GotocCtx<'tcx> {
928926
let src_align = self.is_ptr_aligned(farg_types[0], src.clone());
929927
let src_align_check = self.codegen_assert(
930928
src_align,
931-
PropertyClass::DefaultAssertion,
929+
PropertyClass::SafetyCheck,
932930
"`src` must be properly aligned",
933931
loc,
934932
);
935933
let dst_align = self.is_ptr_aligned(farg_types[1], dst.clone());
936934
let dst_align_check = self.codegen_assert(
937935
dst_align,
938-
PropertyClass::DefaultAssertion,
936+
PropertyClass::SafetyCheck,
939937
"`dst` must be properly aligned",
940938
loc,
941939
);
@@ -1061,7 +1059,7 @@ impl<'tcx> GotocCtx<'tcx> {
10611059

10621060
let non_negative_check = self.codegen_assert_assume(
10631061
offset_overflow.result.is_non_negative(),
1064-
PropertyClass::KaniCheck,
1062+
PropertyClass::SafetyCheck,
10651063
"attempt to compute unsigned offset with negative distance",
10661064
loc,
10671065
);
@@ -1341,7 +1339,7 @@ impl<'tcx> GotocCtx<'tcx> {
13411339
let align = self.is_ptr_aligned(dst_typ, dst.clone());
13421340
let align_check = self.codegen_assert(
13431341
align,
1344-
PropertyClass::DefaultAssertion,
1342+
PropertyClass::SafetyCheck,
13451343
"`dst` must be properly aligned",
13461344
loc,
13471345
);
@@ -1372,7 +1370,7 @@ impl<'tcx> GotocCtx<'tcx> {
13721370
let align = self.is_ptr_aligned(dst_typ, dst.clone());
13731371
let align_check = self.codegen_assert(
13741372
align,
1375-
PropertyClass::DefaultAssertion,
1373+
PropertyClass::SafetyCheck,
13761374
"`dst` must be properly aligned",
13771375
loc,
13781376
);

kani-compiler/src/codegen_cprover_gotoc/codegen/rvalue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl<'tcx> GotocCtx<'tcx> {
5151
let ret_type = Type::Bool;
5252
let body = vec![
5353
self.codegen_assert_false(
54-
PropertyClass::KaniCheck,
54+
PropertyClass::SafetyCheck,
5555
format!("Reached unstable vtable comparison '{:?}'", op).as_str(),
5656
loc,
5757
),

kani-compiler/src/codegen_cprover_gotoc/codegen/statement.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl<'tcx> GotocCtx<'tcx> {
124124
None,
125125
loc,
126126
),
127-
self.codegen_assert_false(PropertyClass::DefaultAssertion, &msg_str, loc),
127+
self.codegen_assert_false(PropertyClass::Assertion, &msg_str, loc),
128128
Stmt::goto(self.current_fn().find_label(target), loc),
129129
],
130130
loc,
@@ -496,7 +496,7 @@ impl<'tcx> GotocCtx<'tcx> {
496496
let call_is_nonnull = fn_ptr.clone().is_nonnull();
497497
let assert_msg = format!("Non-null virtual function call for {:?}", vtable_field_name);
498498
let assert_nonnull =
499-
self.codegen_assert(call_is_nonnull, PropertyClass::DefaultAssertion, &assert_msg, loc);
499+
self.codegen_assert(call_is_nonnull, PropertyClass::SanityCheck, &assert_msg, loc);
500500

501501
// Virtual function call and corresponding nonnull assertion.
502502
let call = fn_ptr.dereference().call(fargs.to_vec());
@@ -530,7 +530,7 @@ impl<'tcx> GotocCtx<'tcx> {
530530
"This is a placeholder message; Kani doesn't support message formatted at runtime",
531531
));
532532

533-
self.codegen_fatal_error(PropertyClass::DefaultAssertion, &msg, span)
533+
self.codegen_fatal_error(PropertyClass::Assertion, &msg, span)
534534
}
535535

536536
// Generate code for fatal error which should trigger an assertion failure and abort the

kani-compiler/src/codegen_cprover_gotoc/overrides/hooks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ impl<'tcx> GotocHook<'tcx> for Assert {
168168
vec![
169169
reach_stmt,
170170
Stmt::decl(tmp.clone(), Some(cond), caller_loc),
171-
tcx.codegen_assert(tmp.clone(), PropertyClass::DefaultAssertion, &msg, caller_loc),
171+
tcx.codegen_assert(tmp.clone(), PropertyClass::Assertion, &msg, caller_loc),
172172
Stmt::assume(tmp, caller_loc),
173173
Stmt::goto(tcx.current_fn().find_label(&target), caller_loc),
174174
],

0 commit comments

Comments
 (0)