rapx/verify/smt_check/
valid_ptr.rs1use super::{
18 common::{SmtCheckResult, SmtChecker, TypeSizeClass},
19 deref,
20};
21use crate::verify::{
22 contract::{Property, PropertyKind},
23 helpers::Checkpoint,
24 report::CheckResult,
25 verifier::ForwardVisitResult,
26};
27
28pub(crate) fn check<'tcx>(
30 checker: &SmtChecker<'tcx>,
31 checkpoint: &Checkpoint<'tcx>,
32 property: &Property<'tcx>,
33 forward: &ForwardVisitResult<'tcx>,
34) -> SmtCheckResult {
35 let Some(required_ty) = checker.property_required_ty(checkpoint, property) else {
36 return SmtCheckResult::unknown("ValidPtr type could not be resolved");
37 };
38
39 match checker.type_size_class(checkpoint.caller, required_ty) {
40 TypeSizeClass::Zero => {
41 SmtCheckResult::proved(format!("ValidPtr proved by Size({required_ty:?}, 0)"))
42 }
43 TypeSizeClass::NonZero => {
44 let deref_property = primitive_property(property, PropertyKind::Deref);
45 let deref = deref::check(checker, checkpoint, &deref_property, forward);
46 match &deref.result {
47 CheckResult::Proved => {
48 SmtCheckResult::proved("ValidPtr proved: non-ZST target satisfies Deref")
49 }
50 CheckResult::Failed => SmtCheckResult {
51 result: CheckResult::Failed,
52 query: None,
53 notes: vec![String::from(
54 "ValidPtr failed: non-ZST target does not satisfy Deref",
55 )],
56 },
57 CheckResult::Unknown => {
58 SmtCheckResult::unknown("ValidPtr unknown: non-ZST Deref is not proved")
59 }
60 }
61 .with_note(format!("primitive Deref via SMT: {:?}", deref.result))
62 }
63 TypeSizeClass::Unknown => {
64 let deref_property = primitive_property(property, PropertyKind::Deref);
65 let deref = deref::check(checker, checkpoint, &deref_property, forward);
66 match &deref.result {
67 CheckResult::Proved => SmtCheckResult::proved(
68 "ValidPtr proved: Deref holds, so the formula holds for zero and non-zero sizes",
69 ),
70 CheckResult::Failed | CheckResult::Unknown => SmtCheckResult::unknown(
71 "ValidPtr unknown: type size is unresolved and Deref is not proved",
72 ),
73 }
74 .with_note("type size: Unknown")
75 .with_note(format!("primitive Deref via SMT: {:?}", deref.result))
76 }
77 }
78}
79
80fn primitive_property<'tcx>(property: &Property<'tcx>, kind: PropertyKind) -> Property<'tcx> {
82 Property {
83 kind,
84 args: property.args.clone(),
85 }
86}