| ;; Part of the Crubit project, under the Apache License v2.0 with LLVM | |
| ;; Exceptions. See /LICENSE for license information. | |
| ;; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| ;; Run: cvc5 --lang smt --incremental --fmf-bound gradual_nullability_code_synthesis.smt2 | |
| (set-option :produce-models true) | |
| (set-option :produce-assertions true) | |
| (set-option :produce-assignments true) | |
| (set-option :produce-unsat-cores true) | |
| (set-logic HO_ALL) | |
| (declare-datatype FlowConditions | |
| ((make-FlowConditions | |
| (_get-fc-1 Bool) | |
| (_get-fc-2 Bool) | |
| (_get-fc-3 Bool) | |
| (_get-fc-4 Bool) | |
| (_get-fc-5 Bool) | |
| (_get-fc-6 Bool)))) | |
| ;; Redefine selectors as regular functions, because predefined ones | |
| ;; can't be converted to values of function type for some reason. | |
| (define-fun get-fc-1 ((fcs FlowConditions)) Bool | |
| (_get-fc-1 fcs)) | |
| (define-fun get-fc-2 ((fcs FlowConditions)) Bool | |
| (_get-fc-2 fcs)) | |
| (define-fun get-fc-3 ((fcs FlowConditions)) Bool | |
| (_get-fc-3 fcs)) | |
| (define-fun get-fc-4 ((fcs FlowConditions)) Bool | |
| (_get-fc-4 fcs)) | |
| (define-fun get-fc-5 ((fcs FlowConditions)) Bool | |
| (_get-fc-5 fcs)) | |
| (define-fun get-fc-6 ((fcs FlowConditions)) Bool | |
| (_get-fc-6 fcs)) | |
| (define-fun join-fc ((c Bool) (fc-then Bool) (fc-else Bool)) Bool | |
| (or (and c fc-then) | |
| (and (not c) fc-else))) | |
| (assert | |
| (forall ((c Bool) (fc-then Bool) (fc-else Bool)) | |
| (= (join-fc c fc-then fc-else) | |
| (join-fc (not c) fc-else fc-then)))) | |
| (declare-datatype PointerValue | |
| ((make-PointerValue | |
| (get-x0 Bool) | |
| (get-x1 Bool) | |
| ))) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Solution: unconstrained declarations. | |
| ;; Flow condition conjuncts that constrain a pointer according to its | |
| ;; annotation. | |
| (declare-fun fc-conj--ptr-is-null (PointerValue) Bool) | |
| (declare-fun fc-conj--ptr-is-unknown (PointerValue) Bool) | |
| (declare-fun fc-conj--ptr-is-nonnull (PointerValue) Bool) | |
| (declare-fun fc-conj--ptr-is-nullable (PointerValue) Bool) | |
| (declare-fun fc-conj--ptr-is-maybe-unknown-but-nonnull (PointerValue) Bool) | |
| (declare-fun fc-conj--ptr-is-maybe-unknown-but-null (PointerValue) Bool) | |
| ;; Flow condition conjunct that constrains the result of comparing two | |
| ;; pointers for equality. | |
| ;; | |
| ;; Args: lhs, rhs, are-equal. | |
| (declare-fun fc-conj--ptrs-were-compared (PointerValue PointerValue Bool) Bool) | |
| ;; Flow condition conjunct that constrains the new joined pointer, | |
| ;; by combining the pointers coming from the "then" and the "else" branches | |
| ;; of an "if" statement. | |
| ;; | |
| ;; Args: condition, ptr-then, ptr-else, ptr-joined. | |
| (declare-fun fc-conj--join-ptr (Bool PointerValue PointerValue PointerValue) Bool) | |
| ;; Safety criteria, tells us whether it is safe to dereference a given | |
| ;; pointer at a given program point. The program point is identified | |
| ;; by its flow condition. | |
| ;; | |
| ;; Args: flow-condition, pointer. | |
| (declare-fun is-unsafe-to-deref (Bool PointerValue) Bool) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Solution S1: two bits, no quantifiers | |
| ;; - Bit 1 represents if the pointer's nullability is known | |
| ;; - Bit 2 represents if the pointer is not null | |
| (define-fun enable-solution-s1 () Bool false) | |
| (assert (=> enable-solution-s1 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-null p) | |
| (= p (make-PointerValue true false)))))) | |
| (assert (=> enable-solution-s1 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-unknown p) | |
| (or | |
| (= p (make-PointerValue false false)) | |
| (= p (make-PointerValue false true))))))) | |
| (assert (=> enable-solution-s1 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-nonnull p) | |
| (= p (make-PointerValue true true)))))) | |
| (assert (=> enable-solution-s1 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-nullable p) | |
| (or | |
| (= p (make-PointerValue true false)) | |
| (= p (make-PointerValue true true))))))) | |
| (assert (=> enable-solution-s1 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-maybe-unknown-but-nonnull p) | |
| (or | |
| (= p (make-PointerValue true true)) | |
| (= p (make-PointerValue false true))))))) | |
| (assert (=> enable-solution-s1 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-maybe-unknown-but-null p) | |
| (or | |
| (= p (make-PointerValue true false)) | |
| (= p (make-PointerValue false false))))))) | |
| (assert (=> enable-solution-s1 | |
| (forall ((lhs PointerValue) (rhs PointerValue) (eq Bool)) | |
| (= (fc-conj--ptrs-were-compared lhs rhs eq) | |
| (and | |
| ;; nullptr == nullptr | |
| (=> (and (fc-conj--ptr-is-maybe-unknown-but-null lhs) (fc-conj--ptr-is-maybe-unknown-but-null rhs)) | |
| eq) | |
| ;; nullptr != nonnull | |
| (=> (and (fc-conj--ptr-is-maybe-unknown-but-null lhs) (fc-conj--ptr-is-maybe-unknown-but-nonnull rhs)) | |
| (not eq)) | |
| ;; nonnull != nullptr | |
| (=> (and (fc-conj--ptr-is-maybe-unknown-but-nonnull lhs) (fc-conj--ptr-is-maybe-unknown-but-null rhs)) | |
| (not eq))))))) | |
| (assert (=> enable-solution-s1 | |
| (forall ((c Bool) | |
| (ptr-then PointerValue) | |
| (ptr-else PointerValue) | |
| (ptr-joined PointerValue)) | |
| (= (fc-conj--join-ptr c ptr-then ptr-else ptr-joined) | |
| (or (and c (= ptr-joined ptr-then)) | |
| (and (not c) (= ptr-joined ptr-else))))))) | |
| (assert (=> enable-solution-s1 | |
| (forall ((fc Bool) (p PointerValue)) | |
| (= (is-unsafe-to-deref fc p) | |
| (and fc (fc-conj--ptr-is-null p)))))) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Solution S2: two bits, no quantifiers | |
| ;; - Bit 1 represents if the pointer's value came from a nullable source | |
| ;; - Bit 2 represents if the pointer is null | |
| (define-fun enable-solution-s2 () Bool false) | |
| (assert (=> enable-solution-s2 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-null p) | |
| (= p (make-PointerValue true true)))))) | |
| (assert (=> enable-solution-s2 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-unknown p) | |
| (or | |
| (= p (make-PointerValue false false)) | |
| (= p (make-PointerValue false true))))))) | |
| (assert (=> enable-solution-s2 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-nonnull p) | |
| (= p (make-PointerValue false false)))))) | |
| (assert (=> enable-solution-s2 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-nullable p) | |
| (or | |
| (= p (make-PointerValue true false)) | |
| (= p (make-PointerValue true true))))))) | |
| (assert (=> enable-solution-s2 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-maybe-unknown-but-nonnull p) | |
| (or | |
| (= p (make-PointerValue true false)) | |
| (= p (make-PointerValue false false))))))) | |
| (assert (=> enable-solution-s2 | |
| (forall ((p PointerValue)) | |
| (= (fc-conj--ptr-is-maybe-unknown-but-null p) | |
| (or | |
| (= p (make-PointerValue true true)) | |
| (= p (make-PointerValue false true))))))) | |
| (assert (=> enable-solution-s2 | |
| (forall ((lhs PointerValue) (rhs PointerValue) (eq Bool)) | |
| (= (fc-conj--ptrs-were-compared lhs rhs eq) | |
| (and | |
| ;; nullptr == nullptr | |
| (=> (and (fc-conj--ptr-is-maybe-unknown-but-null lhs) (fc-conj--ptr-is-maybe-unknown-but-null rhs)) | |
| eq) | |
| ;; nullptr != nonnull | |
| (=> (and (fc-conj--ptr-is-maybe-unknown-but-null lhs) (fc-conj--ptr-is-maybe-unknown-but-nonnull rhs)) | |
| (not eq)) | |
| ;; nonnull != nullptr | |
| (=> (and (fc-conj--ptr-is-maybe-unknown-but-nonnull lhs) (fc-conj--ptr-is-maybe-unknown-but-null rhs)) | |
| (not eq))))))) | |
| (assert (=> enable-solution-s2 | |
| (forall ((c Bool) | |
| (ptr-then PointerValue) | |
| (ptr-else PointerValue) | |
| (ptr-joined PointerValue)) | |
| (= (fc-conj--join-ptr c ptr-then ptr-else ptr-joined) | |
| (or (and c (= ptr-joined ptr-then)) | |
| (and (not c) (= ptr-joined ptr-else))))))) | |
| (assert (=> enable-solution-s2 | |
| (forall ((fc Bool) (p PointerValue)) | |
| (= (is-unsafe-to-deref fc p) | |
| (and fc (fc-conj--ptr-is-null p)))))) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Solution S3: ??? bits, with quantifiers. | |
| ;; TODO: Implement. | |
| (define-fun enable-solution-s3 () Bool false) | |
| ;(assert (=> enable-solution-s3 | |
| ; (forall ((p PointerValue)) | |
| ; (= (fc-conj--ptr-is-null p) | |
| ; TODO)))) | |
| ;(assert (=> enable-solution-s3 | |
| ; (forall ((p PointerValue)) | |
| ; (= (fc-conj--ptr-is-unknown p) | |
| ; TODO)))) | |
| ;(assert (=> enable-solution-s3 | |
| ; (forall ((p PointerValue)) | |
| ; (= (fc-conj--ptr-is-nonnull p) | |
| ; TODO)))) | |
| ;(assert (=> enable-solution-s3 | |
| ; (forall ((p PointerValue)) | |
| ; (= (fc-conj--ptr-is-nullable p) | |
| ; TODO)))) | |
| ;(assert (=> enable-solution-s3 | |
| ; (forall ((lhs PointerValue) (rhs PointerValue) (eq Bool)) | |
| ; (= (fc-conj--ptrs-were-compared lhs rhs eq) | |
| ; TODO)))) | |
| ;(assert (=> enable-solution-s3 | |
| ; (forall ((c Bool) | |
| ; (ptr-then PointerValue) | |
| ; (ptr-else PointerValue) | |
| ; (ptr-joined PointerValue)) | |
| ; (= (fc-conj--join-ptr c ptr-then ptr-else ptr-joined) | |
| ; TODO)))) | |
| ;(assert (=> enable-solution-s3 | |
| ; (forall ((fc Bool) (p PointerValue)) | |
| ; (= (is-unsafe-to-deref fc p) | |
| ; TODO)))) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Check the solution. | |
| (echo "Checking satisfiability of the selected solution.") | |
| (check-sat) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Properties that the solution must satisfy. | |
| (define-fun is-valid-pointer ((p PointerValue)) Bool | |
| (or (fc-conj--ptr-is-null p) | |
| (fc-conj--ptr-is-unknown p) | |
| (fc-conj--ptr-is-nonnull p) | |
| (fc-conj--ptr-is-nullable p))) | |
| ;; Reflexivity for fc-conj--ptrs-were-compared. | |
| (assert | |
| (forall ((p PointerValue)) | |
| (=> (is-valid-pointer p) | |
| (fc-conj--ptrs-were-compared p p true)))) | |
| ;; Symmetry for fc-conj--ptrs-were-compared. | |
| (assert | |
| (forall ((p1 PointerValue) (p2 PointerValue) (are-equal Bool)) | |
| (=> (and (is-valid-pointer p1) (is-valid-pointer p2)) | |
| (= (fc-conj--ptrs-were-compared p1 p2 are-equal) | |
| (fc-conj--ptrs-were-compared p2 p1 are-equal))))) | |
| ;; Transitivity for fc-conj--ptrs-were-compared. | |
| (assert | |
| (forall ((p1 PointerValue) (p2 PointerValue) (p3 PointerValue)) | |
| (=> (and (is-valid-pointer p1) | |
| (is-valid-pointer p2) | |
| (is-valid-pointer p3) | |
| (fc-conj--ptrs-were-compared p1 p2 true) | |
| (fc-conj--ptrs-were-compared p2 p3 true)) | |
| (fc-conj--ptrs-were-compared p1 p3 true)))) | |
| ;; Symmetry for fc-conj--join-ptr with regards to pointers. | |
| (assert | |
| (forall ((b Bool) (p1 PointerValue) (p2 PointerValue) (p3 PointerValue)) | |
| (= (fc-conj--join-ptr b p1 p2 p3) | |
| (fc-conj--join-ptr (not b) p2 p1 p3)))) | |
| (echo "Checking whether the selected solution satisfies the properties.") | |
| (check-sat) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example DerefAllUnchecked | |
| ;; | |
| ;; ``` | |
| ;; void target( | |
| ;; int *ptr_unknown, | |
| ;; int * _NonNull ptr_nonnull, | |
| ;; int * _Nullable ptr_nullable) { | |
| ;; int *ptr_nullptr = nullptr; | |
| ;; // (1) | |
| ;; *ptr_unknown; // safe | |
| ;; *ptr_nonnull; // safe | |
| ;; *ptr_nullable; // unsafe | |
| ;; *ptr_nullptr; // unsafe | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-DerefAllUnchecked | |
| ((make-State-DerefAllUnchecked | |
| (_get-ptr_unknown PointerValue) | |
| (_get-ptr_nonnull PointerValue) | |
| (_get-ptr_nullable PointerValue) | |
| (_get-ptr_nullptr PointerValue)))) | |
| (define-fun get-ptr_unknown-DerefAllUnchecked | |
| ((state State-DerefAllUnchecked)) PointerValue | |
| (_get-ptr_unknown state)) | |
| (define-fun get-ptr_nonnull-DerefAllUnchecked | |
| ((state State-DerefAllUnchecked)) PointerValue | |
| (_get-ptr_nonnull state)) | |
| (define-fun get-ptr_nullable-DerefAllUnchecked | |
| ((state State-DerefAllUnchecked)) PointerValue | |
| (_get-ptr_nullable state)) | |
| (define-fun get-ptr_nullptr-DerefAllUnchecked | |
| ((state State-DerefAllUnchecked)) PointerValue | |
| (_get-ptr_nullptr state)) | |
| (define-fun run-DerefAllUnchecked | |
| ((state State-DerefAllUnchecked)) | |
| FlowConditions | |
| (match state | |
| (((make-State-DerefAllUnchecked | |
| ptr_unknown ptr_nonnull ptr_nullable ptr_nullptr) | |
| (let ((fc-1 (and (fc-conj--ptr-is-unknown ptr_unknown) | |
| (fc-conj--ptr-is-nonnull ptr_nonnull) | |
| (fc-conj--ptr-is-nullable ptr_nullable) | |
| (fc-conj--ptr-is-null ptr_nullptr)))) | |
| (make-FlowConditions fc-1 false false false false false)))))) | |
| (define-fun is-reachable-DerefAllUnchecked | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-DerefAllUnchecked)) | |
| (let ((fcs (run-DerefAllUnchecked state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-DerefAllUnchecked | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-DerefAllUnchecked PointerValue))) | |
| Bool | |
| (exists ((state State-DerefAllUnchecked)) | |
| (let ((fcs (run-DerefAllUnchecked state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-DerefAllUnchecked get-fc-1) | |
| :named DerefAllUnchecked-reachable-1)) | |
| (assert | |
| (! (not (is-unsafe-deref-DerefAllUnchecked get-fc-1 get-ptr_unknown-DerefAllUnchecked)) | |
| :named DerefAllUnchecked-deref-unknown)) | |
| (assert | |
| (! (not (is-unsafe-deref-DerefAllUnchecked get-fc-1 get-ptr_nonnull-DerefAllUnchecked)) | |
| :named DerefAllUnchecked-deref-nonnull)) | |
| (assert | |
| (! (is-unsafe-deref-DerefAllUnchecked get-fc-1 get-ptr_nullable-DerefAllUnchecked) | |
| :named DerefAllUnchecked-deref-nullable)) | |
| (assert | |
| (! (is-unsafe-deref-DerefAllUnchecked get-fc-1 get-ptr_nullptr-DerefAllUnchecked) | |
| :named DerefAllUnchecked-deref-nullptr)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example MixedNullableAndNonNull | |
| ;; | |
| ;; ``` | |
| ;; void target(int * _Nullable x, bool b) { | |
| ;; // (1) | |
| ;; int i; | |
| ;; *x; // unsafe | |
| ;; if (b) { | |
| ;; // (2) | |
| ;; *x; // unsafe | |
| ;; x = &i; | |
| ;; // (3) | |
| ;; *x; // safe | |
| ;; } | |
| ;; // (4) | |
| ;; *x; // unsafe | |
| ;; if (b) { | |
| ;; // (5) | |
| ;; *x; // safe | |
| ;; } else { | |
| ;; // (6) | |
| ;; *x; // unsafe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-MixedNullableAndNonNull | |
| ((make-State-MixedNullableAndNonNull | |
| (_get-x-1 PointerValue) | |
| (_get-x-3 PointerValue) | |
| (_get-x-4 PointerValue) | |
| (b Bool)))) | |
| (define-fun get-x-1-MixedNullableAndNonNull | |
| ((state State-MixedNullableAndNonNull)) PointerValue | |
| (_get-x-1 state)) | |
| (define-fun get-x-3-MixedNullableAndNonNull | |
| ((state State-MixedNullableAndNonNull)) PointerValue | |
| (_get-x-3 state)) | |
| (define-fun get-x-4-MixedNullableAndNonNull | |
| ((state State-MixedNullableAndNonNull)) PointerValue | |
| (_get-x-4 state)) | |
| (define-fun run-MixedNullableAndNonNull | |
| ((state State-MixedNullableAndNonNull)) | |
| FlowConditions | |
| (match state | |
| (((make-State-MixedNullableAndNonNull x-1 x-3 x-4 b) | |
| (let ((fc-1 (fc-conj--ptr-is-nullable x-1))) | |
| (let ((fc-2 (and fc-1 b))) | |
| (let ((fc-3 (and fc-2 (fc-conj--ptr-is-nonnull x-3)))) | |
| (let ((fc-4 (and (join-fc b fc-3 fc-1) | |
| (fc-conj--join-ptr b x-3 x-1 x-4)))) | |
| (let ((fc-5 (and fc-4 b))) | |
| (let ((fc-6 (and fc-4 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 fc-5 fc-6))))))))))) | |
| (define-fun is-reachable-MixedNullableAndNonNull | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-MixedNullableAndNonNull)) | |
| (let ((fcs (run-MixedNullableAndNonNull state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-MixedNullableAndNonNull | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-MixedNullableAndNonNull PointerValue))) | |
| Bool | |
| (exists ((state State-MixedNullableAndNonNull)) | |
| (let ((fcs (run-MixedNullableAndNonNull state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-MixedNullableAndNonNull get-fc-1) | |
| :named MixedNullableAndNonNull-reachable-1)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndNonNull get-fc-2) | |
| :named MixedNullableAndNonNull-reachable-2)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndNonNull get-fc-3) | |
| :named MixedNullableAndNonNull-reachable-3)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndNonNull get-fc-4) | |
| :named MixedNullableAndNonNull-reachable-4)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndNonNull get-fc-5) | |
| :named MixedNullableAndNonNull-reachable-5)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndNonNull get-fc-6) | |
| :named MixedNullableAndNonNull-reachable-6)) | |
| (assert | |
| (! (is-unsafe-deref-MixedNullableAndNonNull get-fc-1 get-x-1-MixedNullableAndNonNull) | |
| :named MixedNullableAndNonNull-deref-1)) | |
| (assert | |
| (! (is-unsafe-deref-MixedNullableAndNonNull get-fc-2 get-x-1-MixedNullableAndNonNull) | |
| :named MixedNullableAndNonNull-deref-2)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedNullableAndNonNull get-fc-3 get-x-3-MixedNullableAndNonNull)) | |
| :named MixedNullableAndNonNull-deref-3)) | |
| (assert | |
| (! (is-unsafe-deref-MixedNullableAndNonNull get-fc-4 get-x-4-MixedNullableAndNonNull) | |
| :named MixedNullableAndNonNull-deref-4)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedNullableAndNonNull get-fc-5 get-x-4-MixedNullableAndNonNull)) | |
| :named MixedNullableAndNonNull-deref-5)) | |
| (assert | |
| (! (is-unsafe-deref-MixedNullableAndNonNull get-fc-6 get-x-4-MixedNullableAndNonNull) | |
| :named MixedNullableAndNonNull-deref-6)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example MixedNullableAndUnknown | |
| ;; | |
| ;; ``` | |
| ;; void target(int * _Nullable x, bool b) { | |
| ;; // (1) | |
| ;; *x; // unsafe | |
| ;; if (b) { | |
| ;; // (2) | |
| ;; *x; // unsafe | |
| ;; x = MakeUnknown(); | |
| ;; // (3) | |
| ;; *x; // safe | |
| ;; } | |
| ;; // (4) | |
| ;; *x; // unsafe | |
| ;; if (b) { | |
| ;; // (5) | |
| ;; *x; // safe | |
| ;; } else { | |
| ;; // (6) | |
| ;; *x; // unsafe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-MixedNullableAndUnknown | |
| ((make-State-MixedNullableAndUnknown | |
| (_get-x-1 PointerValue) | |
| (_get-x-3 PointerValue) | |
| (_get-x-4 PointerValue) | |
| (b Bool)))) | |
| (define-fun get-x-1-MixedNullableAndUnknown | |
| ((state State-MixedNullableAndUnknown)) PointerValue | |
| (_get-x-1 state)) | |
| (define-fun get-x-3-MixedNullableAndUnknown | |
| ((state State-MixedNullableAndUnknown)) PointerValue | |
| (_get-x-3 state)) | |
| (define-fun get-x-4-MixedNullableAndUnknown | |
| ((state State-MixedNullableAndUnknown)) PointerValue | |
| (_get-x-4 state)) | |
| (define-fun run-MixedNullableAndUnknown | |
| ((state State-MixedNullableAndUnknown)) | |
| FlowConditions | |
| (match state | |
| (((make-State-MixedNullableAndUnknown x-1 x-3 x-4 b) | |
| (let ((fc-1 (fc-conj--ptr-is-nullable x-1))) | |
| (let ((fc-2 (and fc-1 b))) | |
| (let ((fc-3 (and fc-2 (fc-conj--ptr-is-unknown x-3)))) | |
| (let ((fc-4 (and (join-fc b fc-3 fc-1) | |
| (fc-conj--join-ptr b x-3 x-1 x-4)))) | |
| (let ((fc-5 (and fc-4 b))) | |
| (let ((fc-6 (and fc-4 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 fc-5 fc-6))))))))))) | |
| (define-fun is-reachable-MixedNullableAndUnknown | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-MixedNullableAndUnknown)) | |
| (let ((fcs (run-MixedNullableAndUnknown state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-MixedNullableAndUnknown | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-MixedNullableAndUnknown PointerValue))) | |
| Bool | |
| (exists ((state State-MixedNullableAndUnknown)) | |
| (let ((fcs (run-MixedNullableAndUnknown state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-MixedNullableAndUnknown get-fc-1) | |
| :named MixedNullableAndUnknown-reachable-1)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndUnknown get-fc-2) | |
| :named MixedNullableAndUnknown-reachable-2)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndUnknown get-fc-3) | |
| :named MixedNullableAndUnknown-reachable-3)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndUnknown get-fc-4) | |
| :named MixedNullableAndUnknown-reachable-4)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndUnknown get-fc-5) | |
| :named MixedNullableAndUnknown-reachable-5)) | |
| (assert | |
| (! (is-reachable-MixedNullableAndUnknown get-fc-6) | |
| :named MixedNullableAndUnknown-reachable-6)) | |
| (assert | |
| (! (is-unsafe-deref-MixedNullableAndUnknown get-fc-1 get-x-1-MixedNullableAndUnknown) | |
| :named MixedNullableAndUnknown-deref-1)) | |
| (assert | |
| (! (is-unsafe-deref-MixedNullableAndUnknown get-fc-2 get-x-1-MixedNullableAndUnknown) | |
| :named MixedNullableAndUnknown-deref-2)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedNullableAndUnknown get-fc-3 get-x-3-MixedNullableAndUnknown)) | |
| :named MixedNullableAndUnknown-deref-3)) | |
| (assert | |
| (! (is-unsafe-deref-MixedNullableAndUnknown get-fc-4 get-x-4-MixedNullableAndUnknown) | |
| :named MixedNullableAndUnknown-deref-4)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedNullableAndUnknown get-fc-5 get-x-4-MixedNullableAndUnknown)) | |
| :named MixedNullableAndUnknown-deref-5)) | |
| (assert | |
| (! (is-unsafe-deref-MixedNullableAndUnknown get-fc-6 get-x-4-MixedNullableAndUnknown) | |
| :named MixedNullableAndUnknown-deref-6)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example MixedUnknownAndNull | |
| ;; | |
| ;; ``` | |
| ;; void target(int *x, bool b) { | |
| ;; // (1) | |
| ;; *x; // safe | |
| ;; if (b) { | |
| ;; // (2) | |
| ;; *x; // safe | |
| ;; x = nullptr; | |
| ;; // (3) | |
| ;; *x; // unsafe | |
| ;; } | |
| ;; // (4) | |
| ;; *x; // unsafe | |
| ;; if (b) { | |
| ;; // (5) | |
| ;; *x; // unsafe | |
| ;; } else { | |
| ;; // (6) | |
| ;; *x; // safe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-MixedUnknownAndNull | |
| ((make-State-MixedUnknownAndNull | |
| (_get-x-1 PointerValue) | |
| (_get-x-3 PointerValue) | |
| (_get-x-4 PointerValue) | |
| (b Bool)))) | |
| (define-fun get-x-1-MixedUnknownAndNull | |
| ((state State-MixedUnknownAndNull)) PointerValue | |
| (_get-x-1 state)) | |
| (define-fun get-x-3-MixedUnknownAndNull | |
| ((state State-MixedUnknownAndNull)) PointerValue | |
| (_get-x-3 state)) | |
| (define-fun get-x-4-MixedUnknownAndNull | |
| ((state State-MixedUnknownAndNull)) PointerValue | |
| (_get-x-4 state)) | |
| (define-fun run-MixedUnknownAndNull | |
| ((state State-MixedUnknownAndNull)) | |
| FlowConditions | |
| (match state | |
| (((make-State-MixedUnknownAndNull x-1 x-3 x-4 b) | |
| (let ((fc-1 (fc-conj--ptr-is-unknown x-1))) | |
| (let ((fc-2 (and fc-1 b))) | |
| (let ((fc-3 (and fc-2 (fc-conj--ptr-is-null x-3)))) | |
| (let ((fc-4 (and (join-fc b fc-3 fc-1) | |
| (fc-conj--join-ptr b x-3 x-1 x-4)))) | |
| (let ((fc-5 (and fc-4 b))) | |
| (let ((fc-6 (and fc-4 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 fc-5 fc-6))))))))))) | |
| (define-fun is-reachable-MixedUnknownAndNull | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-MixedUnknownAndNull)) | |
| (let ((fcs (run-MixedUnknownAndNull state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-MixedUnknownAndNull | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-MixedUnknownAndNull PointerValue))) | |
| Bool | |
| (exists ((state State-MixedUnknownAndNull)) | |
| (let ((fcs (run-MixedUnknownAndNull state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNull get-fc-1) | |
| :named MixedUnknownAndNull-reachable-1)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNull get-fc-2) | |
| :named MixedUnknownAndNull-reachable-2)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNull get-fc-3) | |
| :named MixedUnknownAndNull-reachable-3)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNull get-fc-4) | |
| :named MixedUnknownAndNull-reachable-4)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNull get-fc-5) | |
| :named MixedUnknownAndNull-reachable-5)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNull get-fc-6) | |
| :named MixedUnknownAndNull-reachable-6)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedUnknownAndNull get-fc-1 get-x-1-MixedUnknownAndNull)) | |
| :named MixedUnknownAndNull-deref-1)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedUnknownAndNull get-fc-2 get-x-1-MixedUnknownAndNull)) | |
| :named MixedUnknownAndNull-deref-2)) | |
| (assert | |
| (! (is-unsafe-deref-MixedUnknownAndNull get-fc-3 get-x-3-MixedUnknownAndNull) | |
| :named MixedUnknownAndNull-deref-3)) | |
| (assert | |
| (! (is-unsafe-deref-MixedUnknownAndNull get-fc-4 get-x-4-MixedUnknownAndNull) | |
| :named MixedUnknownAndNull-deref-4)) | |
| (assert | |
| (! (is-unsafe-deref-MixedUnknownAndNull get-fc-5 get-x-4-MixedUnknownAndNull) | |
| :named MixedUnknownAndNull-deref-5)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedUnknownAndNull get-fc-6 get-x-4-MixedUnknownAndNull)) | |
| :named MixedUnknownAndNull-deref-6)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example MixedUnknownAndNonNull | |
| ;; | |
| ;; ``` | |
| ;; void target(int *x, bool b) { | |
| ;; // (1) | |
| ;; *x; // safe | |
| ;; if (b) { | |
| ;; // (2) | |
| ;; *x; // safe | |
| ;; x = MakeNonNull(); | |
| ;; // (3) | |
| ;; *x; // safe | |
| ;; } | |
| ;; // (4) | |
| ;; *x; // safe | |
| ;; if (b) { | |
| ;; // (5) | |
| ;; *x; // safe | |
| ;; } else { | |
| ;; // (6) | |
| ;; *x; // safe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-MixedUnknownAndNonNull | |
| ((make-State-MixedUnknownAndNonNull | |
| (_get-x-1 PointerValue) | |
| (_get-x-3 PointerValue) | |
| (_get-x-4 PointerValue) | |
| (b Bool)))) | |
| (define-fun get-x-1-MixedUnknownAndNonNull | |
| ((state State-MixedUnknownAndNonNull)) PointerValue | |
| (_get-x-1 state)) | |
| (define-fun get-x-3-MixedUnknownAndNonNull | |
| ((state State-MixedUnknownAndNonNull)) PointerValue | |
| (_get-x-3 state)) | |
| (define-fun get-x-4-MixedUnknownAndNonNull | |
| ((state State-MixedUnknownAndNonNull)) PointerValue | |
| (_get-x-4 state)) | |
| (define-fun run-MixedUnknownAndNonNull | |
| ((state State-MixedUnknownAndNonNull)) | |
| FlowConditions | |
| (match state | |
| (((make-State-MixedUnknownAndNonNull x-1 x-3 x-4 b) | |
| (let ((fc-1 (fc-conj--ptr-is-unknown x-1))) | |
| (let ((fc-2 (and fc-1 b))) | |
| (let ((fc-3 (and fc-2 (fc-conj--ptr-is-nonnull x-3)))) | |
| (let ((fc-4 (and (join-fc b fc-3 fc-1) | |
| (fc-conj--join-ptr b x-3 x-1 x-4)))) | |
| (let ((fc-5 (and fc-4 b))) | |
| (let ((fc-6 (and fc-4 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 fc-5 fc-6))))))))))) | |
| (define-fun is-reachable-MixedUnknownAndNonNull | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-MixedUnknownAndNonNull)) | |
| (let ((fcs (run-MixedUnknownAndNonNull state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-MixedUnknownAndNonNull | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-MixedUnknownAndNonNull PointerValue))) | |
| Bool | |
| (exists ((state State-MixedUnknownAndNonNull)) | |
| (let ((fcs (run-MixedUnknownAndNonNull state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNonNull get-fc-1) | |
| :named MixedUnknownAndNonNull-reachable-1)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNonNull get-fc-2) | |
| :named MixedUnknownAndNonNull-reachable-2)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNonNull get-fc-3) | |
| :named MixedUnknownAndNonNull-reachable-3)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNonNull get-fc-4) | |
| :named MixedUnknownAndNonNull-reachable-4)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNonNull get-fc-5) | |
| :named MixedUnknownAndNonNull-reachable-5)) | |
| (assert | |
| (! (is-reachable-MixedUnknownAndNonNull get-fc-6) | |
| :named MixedUnknownAndNonNull-reachable-6)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedUnknownAndNonNull get-fc-1 get-x-1-MixedUnknownAndNonNull)) | |
| :named MixedUnknownAndNonNull-deref-1)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedUnknownAndNonNull get-fc-2 get-x-1-MixedUnknownAndNonNull)) | |
| :named MixedUnknownAndNonNull-deref-2)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedUnknownAndNonNull get-fc-3 get-x-3-MixedUnknownAndNonNull)) | |
| :named MixedUnknownAndNonNull-deref-3)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedUnknownAndNonNull get-fc-4 get-x-4-MixedUnknownAndNonNull)) | |
| :named MixedUnknownAndNonNull-deref-4)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedUnknownAndNonNull get-fc-5 get-x-4-MixedUnknownAndNonNull)) | |
| :named MixedUnknownAndNonNull-deref-5)) | |
| (assert | |
| (! (not (is-unsafe-deref-MixedUnknownAndNonNull get-fc-6 get-x-4-MixedUnknownAndNonNull)) | |
| :named MixedUnknownAndNonNull-deref-6)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example CompareNullAndNull | |
| ;; | |
| ;; ``` | |
| ;; void target() { | |
| ;; int *x = nullptr; | |
| ;; int *y = nullptr; | |
| ;; // (1) | |
| ;; bool b = x == y; | |
| ;; // (2) | |
| ;; if (b) { | |
| ;; // (3) | |
| ;; *x; // unsafe | |
| ;; *y; // unsafe | |
| ;; } else { | |
| ;; // (4) - unreachable | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-CompareNullAndNull | |
| ((make-State-CompareNullAndNull | |
| (_get-x PointerValue) | |
| (_get-y PointerValue) | |
| (_get-b Bool)))) | |
| (define-fun get-x-CompareNullAndNull | |
| ((state State-CompareNullAndNull)) PointerValue | |
| (_get-x state)) | |
| (define-fun get-y-CompareNullAndNull | |
| ((state State-CompareNullAndNull)) PointerValue | |
| (_get-y state)) | |
| (define-fun run-CompareNullAndNull | |
| ((state State-CompareNullAndNull)) | |
| FlowConditions | |
| (match state | |
| (((make-State-CompareNullAndNull x y b) | |
| (let ((fc-1 (and (fc-conj--ptr-is-null x) | |
| (fc-conj--ptr-is-null y)))) | |
| (let ((fc-2 (and fc-1 (fc-conj--ptrs-were-compared x y b)))) | |
| (let ((fc-3 (and fc-2 b))) | |
| (let ((fc-4 (and fc-2 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 false false))))))))) | |
| (define-fun is-reachable-CompareNullAndNull | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-CompareNullAndNull)) | |
| (let ((fcs (run-CompareNullAndNull state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-CompareNullAndNull | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-CompareNullAndNull PointerValue))) | |
| Bool | |
| (exists ((state State-CompareNullAndNull)) | |
| (let ((fcs (run-CompareNullAndNull state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-CompareNullAndNull get-fc-1) | |
| :named CompareNullAndNull-reachable-1)) | |
| (assert | |
| (! (is-reachable-CompareNullAndNull get-fc-2) | |
| :named CompareNullAndNull-reachable-2)) | |
| (assert | |
| (! (is-reachable-CompareNullAndNull get-fc-3) | |
| :named CompareNullAndNull-reachable-3)) | |
| (assert | |
| (! (not (is-reachable-CompareNullAndNull get-fc-4)) | |
| :named CompareNullAndNull-reachable-4)) | |
| (assert | |
| (! (is-unsafe-deref-CompareNullAndNull get-fc-3 get-x-CompareNullAndNull) | |
| :named CompareNullAndNull-deref-3-x)) | |
| (assert | |
| (! (is-unsafe-deref-CompareNullAndNull get-fc-3 get-y-CompareNullAndNull) | |
| :named CompareNullAndNull-deref-3-y)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example CompareUnknownAndUnknown | |
| ;; | |
| ;; ``` | |
| ;; void target(int *x, int *y) { | |
| ;; // (1) | |
| ;; bool b = x == y; | |
| ;; // (2) | |
| ;; if (b) { | |
| ;; // (3) | |
| ;; *x; // safe | |
| ;; *y; // safe | |
| ;; } else { | |
| ;; // (4) | |
| ;; *x; // safe | |
| ;; *y; // safe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-CompareUnknownAndUnknown | |
| ((make-State-CompareUnknownAndUnknown | |
| (_get-x PointerValue) | |
| (_get-y PointerValue) | |
| (_get-b Bool)))) | |
| (define-fun get-x-CompareUnknownAndUnknown | |
| ((state State-CompareUnknownAndUnknown)) PointerValue | |
| (_get-x state)) | |
| (define-fun get-y-CompareUnknownAndUnknown | |
| ((state State-CompareUnknownAndUnknown)) PointerValue | |
| (_get-y state)) | |
| (define-fun run-CompareUnknownAndUnknown | |
| ((state State-CompareUnknownAndUnknown)) | |
| FlowConditions | |
| (match state | |
| (((make-State-CompareUnknownAndUnknown x y b) | |
| (let ((fc-1 (and (fc-conj--ptr-is-unknown x) | |
| (fc-conj--ptr-is-unknown y)))) | |
| (let ((fc-2 (and fc-1 (fc-conj--ptrs-were-compared x y b)))) | |
| (let ((fc-3 (and fc-2 b))) | |
| (let ((fc-4 (and fc-2 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 false false))))))))) | |
| (define-fun is-reachable-CompareUnknownAndUnknown | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-CompareUnknownAndUnknown)) | |
| (let ((fcs (run-CompareUnknownAndUnknown state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-CompareUnknownAndUnknown | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-CompareUnknownAndUnknown PointerValue))) | |
| Bool | |
| (exists ((state State-CompareUnknownAndUnknown)) | |
| (let ((fcs (run-CompareUnknownAndUnknown state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-CompareUnknownAndUnknown get-fc-1) | |
| :named CompareUnknownAndUnknown-reachable-1)) | |
| (assert | |
| (! (is-reachable-CompareUnknownAndUnknown get-fc-2) | |
| :named CompareUnknownAndUnknown-reachable-2)) | |
| (assert | |
| (! (is-reachable-CompareUnknownAndUnknown get-fc-3) | |
| :named CompareUnknownAndUnknown-reachable-3)) | |
| (assert | |
| (! (is-reachable-CompareUnknownAndUnknown get-fc-4) | |
| :named CompareUnknownAndUnknown-reachable-4)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndUnknown get-fc-3 get-x-CompareUnknownAndUnknown)) | |
| :named CompareUnknownAndUnknown-deref-3-x)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndUnknown get-fc-3 get-y-CompareUnknownAndUnknown)) | |
| :named CompareUnknownAndUnknown-deref-3-y)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndUnknown get-fc-4 get-x-CompareUnknownAndUnknown)) | |
| :named CompareUnknownAndUnknown-deref-4-x)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndUnknown get-fc-4 get-y-CompareUnknownAndUnknown)) | |
| :named CompareUnknownAndUnknown-deref-4-y)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example CompareNonNullAndNonNull | |
| ;; | |
| ;; ``` | |
| ;; void target(int * _NonNull x, int * _NonNull y) { | |
| ;; // (1) | |
| ;; bool b = x == y; | |
| ;; // (2) | |
| ;; if (b) { | |
| ;; // (3) | |
| ;; *x; // safe | |
| ;; *y; // safe | |
| ;; } else { | |
| ;; // (4) | |
| ;; *x; // safe | |
| ;; *y; // safe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-CompareNonNullAndNonNull | |
| ((make-State-CompareNonNullAndNonNull | |
| (_get-x PointerValue) | |
| (_get-y PointerValue) | |
| (_get-b Bool)))) | |
| (define-fun get-x-CompareNonNullAndNonNull | |
| ((state State-CompareNonNullAndNonNull)) PointerValue | |
| (_get-x state)) | |
| (define-fun get-y-CompareNonNullAndNonNull | |
| ((state State-CompareNonNullAndNonNull)) PointerValue | |
| (_get-y state)) | |
| (define-fun run-CompareNonNullAndNonNull | |
| ((state State-CompareNonNullAndNonNull)) | |
| FlowConditions | |
| (match state | |
| (((make-State-CompareNonNullAndNonNull x y b) | |
| (let ((fc-1 (and (fc-conj--ptr-is-nonnull x) | |
| (fc-conj--ptr-is-nonnull y)))) | |
| (let ((fc-2 (and fc-1 (fc-conj--ptrs-were-compared x y b)))) | |
| (let ((fc-3 (and fc-2 b))) | |
| (let ((fc-4 (and fc-2 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 false false))))))))) | |
| (define-fun is-reachable-CompareNonNullAndNonNull | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-CompareNonNullAndNonNull)) | |
| (let ((fcs (run-CompareNonNullAndNonNull state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-CompareNonNullAndNonNull | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-CompareNonNullAndNonNull PointerValue))) | |
| Bool | |
| (exists ((state State-CompareNonNullAndNonNull)) | |
| (let ((fcs (run-CompareNonNullAndNonNull state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-CompareNonNullAndNonNull get-fc-1) | |
| :named CompareNonNullAndNonNull-reachable-1)) | |
| (assert | |
| (! (is-reachable-CompareNonNullAndNonNull get-fc-2) | |
| :named CompareNonNullAndNonNull-reachable-2)) | |
| (assert | |
| (! (is-reachable-CompareNonNullAndNonNull get-fc-3) | |
| :named CompareNonNullAndNonNull-reachable-3)) | |
| (assert | |
| (! (is-reachable-CompareNonNullAndNonNull get-fc-4) | |
| :named CompareNonNullAndNonNull-reachable-4)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareNonNullAndNonNull get-fc-3 get-x-CompareNonNullAndNonNull)) | |
| :named CompareNonNullAndNonNull-deref-3-x)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareNonNullAndNonNull get-fc-3 get-y-CompareNonNullAndNonNull)) | |
| :named CompareNonNullAndNonNull-deref-3-y)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareNonNullAndNonNull get-fc-4 get-x-CompareNonNullAndNonNull)) | |
| :named CompareNonNullAndNonNull-deref-4-x)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareNonNullAndNonNull get-fc-4 get-y-CompareNonNullAndNonNull)) | |
| :named CompareNonNullAndNonNull-deref-4-y)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example CompareNonNullAndNull | |
| ;; | |
| ;; ``` | |
| ;; void target(int * _NonNull x) { | |
| ;; // (1) | |
| ;; *x; // safe | |
| ;; bool b = x == nullptr; | |
| ;; // (2) | |
| ;; *x; // safe | |
| ;; if (b) { | |
| ;; // (3) - unreachable | |
| ;; } else { | |
| ;; // (4) | |
| ;; *x; // safe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-CompareNonNullAndNull | |
| ((make-State-CompareNonNullAndNull | |
| (_get-the-nullptr PointerValue) | |
| (_get-x PointerValue) | |
| (_get-b Bool)))) | |
| (define-fun get-x-CompareNonNullAndNull | |
| ((state State-CompareNonNullAndNull)) PointerValue | |
| (_get-x state)) | |
| (define-fun run-CompareNonNullAndNull | |
| ((state State-CompareNonNullAndNull)) | |
| FlowConditions | |
| (match state | |
| (((make-State-CompareNonNullAndNull the-nullptr x b) | |
| (let ((fc-1 (and (fc-conj--ptr-is-null the-nullptr) | |
| (fc-conj--ptr-is-nonnull x)))) | |
| (let ((fc-2 (and fc-1 (fc-conj--ptrs-were-compared x the-nullptr b)))) | |
| (let ((fc-3 (and fc-2 b))) | |
| (let ((fc-4 (and fc-2 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 false false))))))))) | |
| (define-fun is-reachable-CompareNonNullAndNull | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-CompareNonNullAndNull)) | |
| (let ((fcs (run-CompareNonNullAndNull state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-CompareNonNullAndNull | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-CompareNonNullAndNull PointerValue))) | |
| Bool | |
| (exists ((state State-CompareNonNullAndNull)) | |
| (let ((fcs (run-CompareNonNullAndNull state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-CompareNonNullAndNull get-fc-1) | |
| :named CompareNonNullAndNull-reachable-1)) | |
| (assert | |
| (! (is-reachable-CompareNonNullAndNull get-fc-2) | |
| :named CompareNonNullAndNull-reachable-2)) | |
| (assert | |
| (! (not (is-reachable-CompareNonNullAndNull get-fc-3)) | |
| :named CompareNonNullAndNull-reachable-3)) | |
| (assert | |
| (! (is-reachable-CompareNonNullAndNull get-fc-4) | |
| :named CompareNonNullAndNull-reachable-4)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareNonNullAndNull get-fc-1 get-x-CompareNonNullAndNull)) | |
| :named CompareNonNullAndNull-deref-1)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareNonNullAndNull get-fc-2 get-x-CompareNonNullAndNull)) | |
| :named CompareNonNullAndNull-deref-2)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareNonNullAndNull get-fc-4 get-x-CompareNonNullAndNull)) | |
| :named CompareNonNullAndNull-deref-4)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example CompareNullableAndNull | |
| ;; | |
| ;; ``` | |
| ;; void target(int * _Nullable x) { | |
| ;; // (1) | |
| ;; *x; // unsafe | |
| ;; bool b = x == nullptr; | |
| ;; // (2) | |
| ;; *x; // unsafe | |
| ;; if (b) { | |
| ;; // (3) | |
| ;; *x; // unsafe | |
| ;; } else { | |
| ;; // (4) | |
| ;; *x; // safe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-CompareNullableAndNull | |
| ((make-State-CompareNullableAndNull | |
| (_get-the-nullptr PointerValue) | |
| (_get-x PointerValue) | |
| (_get-b Bool)))) | |
| (define-fun get-x-CompareNullableAndNull | |
| ((state State-CompareNullableAndNull)) PointerValue | |
| (_get-x state)) | |
| (define-fun run-CompareNullableAndNull | |
| ((state State-CompareNullableAndNull)) | |
| FlowConditions | |
| (match state | |
| (((make-State-CompareNullableAndNull the-nullptr x b) | |
| (let ((fc-1 (and (fc-conj--ptr-is-null the-nullptr) | |
| (fc-conj--ptr-is-nullable x)))) | |
| (let ((fc-2 (and fc-1 (fc-conj--ptrs-were-compared x the-nullptr b)))) | |
| (let ((fc-3 (and fc-2 b))) | |
| (let ((fc-4 (and fc-2 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 false false))))))))) | |
| (define-fun is-reachable-CompareNullableAndNull | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-CompareNullableAndNull)) | |
| (let ((fcs (run-CompareNullableAndNull state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-CompareNullableAndNull | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-CompareNullableAndNull PointerValue))) | |
| Bool | |
| (exists ((state State-CompareNullableAndNull)) | |
| (let ((fcs (run-CompareNullableAndNull state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-CompareNullableAndNull get-fc-1) | |
| :named CompareNullableAndNull-reachable-1)) | |
| (assert | |
| (! (is-reachable-CompareNullableAndNull get-fc-2) | |
| :named CompareNullableAndNull-reachable-2)) | |
| (assert | |
| (! (is-reachable-CompareNullableAndNull get-fc-3) | |
| :named CompareNullableAndNull-reachable-3)) | |
| (assert | |
| (! (is-reachable-CompareNullableAndNull get-fc-4) | |
| :named CompareNullableAndNull-reachable-4)) | |
| (assert | |
| (! (is-unsafe-deref-CompareNullableAndNull get-fc-1 get-x-CompareNullableAndNull) | |
| :named CompareNullableAndNull-deref-1)) | |
| (assert | |
| (! (is-unsafe-deref-CompareNullableAndNull get-fc-2 get-x-CompareNullableAndNull) | |
| :named CompareNullableAndNull-deref-2)) | |
| (assert | |
| (! (is-unsafe-deref-CompareNullableAndNull get-fc-3 get-x-CompareNullableAndNull) | |
| :named CompareNullableAndNull-deref-3)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareNullableAndNull get-fc-4 get-x-CompareNullableAndNull)) | |
| :named CompareNullableAndNull-deref-4)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example CompareUnknownAndNullSimple | |
| ;; | |
| ;; ``` | |
| ;; void target(int *x) { | |
| ;; // (1) | |
| ;; *x; // safe - false negative | |
| ;; bool b = x == nullptr; | |
| ;; // (2) | |
| ;; *x; // safe - false negative | |
| ;; if (b) { | |
| ;; // (3) | |
| ;; *x; // safe - false negative | |
| ;; } else { | |
| ;; // (4) | |
| ;; *x; // safe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-CompareUnknownAndNullSimple | |
| ((make-State-CompareUnknownAndNullSimple | |
| (_get-the-nullptr PointerValue) | |
| (_get-x PointerValue) | |
| (_get-b Bool)))) | |
| (define-fun get-x-CompareUnknownAndNullSimple | |
| ((state State-CompareUnknownAndNullSimple)) PointerValue | |
| (_get-x state)) | |
| (define-fun run-CompareUnknownAndNullSimple | |
| ((state State-CompareUnknownAndNullSimple)) | |
| FlowConditions | |
| (match state | |
| (((make-State-CompareUnknownAndNullSimple the-nullptr x b) | |
| (let ((fc-1 (and (fc-conj--ptr-is-null the-nullptr) | |
| (fc-conj--ptr-is-unknown x)))) | |
| (let ((fc-2 (and fc-1 (fc-conj--ptrs-were-compared x the-nullptr b)))) | |
| (let ((fc-3 (and fc-2 b))) | |
| (let ((fc-4 (and fc-2 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 false false))))))))) | |
| (define-fun is-reachable-CompareUnknownAndNullSimple | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-CompareUnknownAndNullSimple)) | |
| (let ((fcs (run-CompareUnknownAndNullSimple state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-CompareUnknownAndNullSimple | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-CompareUnknownAndNullSimple PointerValue))) | |
| Bool | |
| (exists ((state State-CompareUnknownAndNullSimple)) | |
| (let ((fcs (run-CompareUnknownAndNullSimple state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (define-fun is-solvable-CompareUnknownAndNullSimple () Bool | |
| (or enable-solution-s1 enable-solution-s2)) | |
| (assert (=> is-solvable-CompareUnknownAndNullSimple | |
| (! (is-reachable-CompareUnknownAndNullSimple get-fc-1) | |
| :named CompareUnknownAndNullSimple-reachable-1))) | |
| (assert (=> is-solvable-CompareUnknownAndNullSimple | |
| (! (is-reachable-CompareUnknownAndNullSimple get-fc-2) | |
| :named CompareUnknownAndNullSimple-reachable-2))) | |
| (assert (=> is-solvable-CompareUnknownAndNullSimple | |
| (! (is-reachable-CompareUnknownAndNullSimple get-fc-3) | |
| :named CompareUnknownAndNullSimple-reachable-3))) | |
| (assert (=> is-solvable-CompareUnknownAndNullSimple | |
| (! (is-reachable-CompareUnknownAndNullSimple get-fc-4) | |
| :named CompareUnknownAndNullSimple-reachable-4))) | |
| (assert (=> is-solvable-CompareUnknownAndNullSimple | |
| (! (not (is-unsafe-deref-CompareUnknownAndNullSimple get-fc-1 get-x-CompareUnknownAndNullSimple)) | |
| :named CompareUnknownAndNullSimple-deref-1))) | |
| (assert (=> is-solvable-CompareUnknownAndNullSimple | |
| (! (not (is-unsafe-deref-CompareUnknownAndNullSimple get-fc-2 get-x-CompareUnknownAndNullSimple)) | |
| :named CompareUnknownAndNullSimple-deref-2))) | |
| (assert (=> is-solvable-CompareUnknownAndNullSimple | |
| (! (not (is-unsafe-deref-CompareUnknownAndNullSimple get-fc-3 get-x-CompareUnknownAndNullSimple)) | |
| :named CompareUnknownAndNullSimple-deref-3))) | |
| (assert (=> is-solvable-CompareUnknownAndNullSimple | |
| (! (not (is-unsafe-deref-CompareUnknownAndNullSimple get-fc-4 get-x-CompareUnknownAndNullSimple)) | |
| :named CompareUnknownAndNullSimple-deref-4))) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example CompareUnknownAndNonNull | |
| ;; | |
| ;; ``` | |
| ;; void target(int *x, int * _NonNull y) { | |
| ;; // (1) | |
| ;; *x; // safe | |
| ;; *y; // safe | |
| ;; bool b = x == y; | |
| ;; // (2) | |
| ;; *x; // safe | |
| ;; *y; // safe | |
| ;; if (b) { | |
| ;; // (3) | |
| ;; *x; // safe | |
| ;; *y; // safe | |
| ;; } else { | |
| ;; // (4) | |
| ;; *x; // safe | |
| ;; *y; // safe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-CompareUnknownAndNonNull | |
| ((make-State-CompareUnknownAndNonNull | |
| (_get-x PointerValue) | |
| (_get-y PointerValue) | |
| (_get-b Bool)))) | |
| (define-fun get-x-CompareUnknownAndNonNull | |
| ((state State-CompareUnknownAndNonNull)) PointerValue | |
| (_get-x state)) | |
| (define-fun get-y-CompareUnknownAndNonNull | |
| ((state State-CompareUnknownAndNonNull)) PointerValue | |
| (_get-y state)) | |
| (define-fun run-CompareUnknownAndNonNull | |
| ((state State-CompareUnknownAndNonNull)) | |
| FlowConditions | |
| (match state | |
| (((make-State-CompareUnknownAndNonNull x y b) | |
| (let ((fc-1 (and (fc-conj--ptr-is-unknown x) | |
| (fc-conj--ptr-is-nonnull y)))) | |
| (let ((fc-2 (and fc-1 (fc-conj--ptrs-were-compared x y b)))) | |
| (let ((fc-3 (and fc-2 b))) | |
| (let ((fc-4 (and fc-2 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 false false))))))))) | |
| (define-fun is-reachable-CompareUnknownAndNonNull | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-CompareUnknownAndNonNull)) | |
| (let ((fcs (run-CompareUnknownAndNonNull state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-CompareUnknownAndNonNull | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-CompareUnknownAndNonNull PointerValue))) | |
| Bool | |
| (exists ((state State-CompareUnknownAndNonNull)) | |
| (let ((fcs (run-CompareUnknownAndNonNull state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (assert | |
| (! (is-reachable-CompareUnknownAndNonNull get-fc-1) | |
| :named CompareUnknownAndNonNull-reachable-1)) | |
| (assert | |
| (! (is-reachable-CompareUnknownAndNonNull get-fc-2) | |
| :named CompareUnknownAndNonNull-reachable-2)) | |
| (assert | |
| (! (is-reachable-CompareUnknownAndNonNull get-fc-3) | |
| :named CompareUnknownAndNonNull-reachable-3)) | |
| (assert | |
| (! (is-reachable-CompareUnknownAndNonNull get-fc-4) | |
| :named CompareUnknownAndNonNull-reachable-4)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndNonNull get-fc-1 get-x-CompareUnknownAndNonNull)) | |
| :named CompareUnknownAndNonNull-deref-1-x)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndNonNull get-fc-1 get-y-CompareUnknownAndNonNull)) | |
| :named CompareUnknownAndNonNull-deref-1-y)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndNonNull get-fc-2 get-x-CompareUnknownAndNonNull)) | |
| :named CompareUnknownAndNonNull-deref-2-x)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndNonNull get-fc-2 get-y-CompareUnknownAndNonNull)) | |
| :named CompareUnknownAndNonNull-deref-2-y)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndNonNull get-fc-3 get-x-CompareUnknownAndNonNull)) | |
| :named CompareUnknownAndNonNull-deref-3-x)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndNonNull get-fc-3 get-y-CompareUnknownAndNonNull)) | |
| :named CompareUnknownAndNonNull-deref-3-y)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndNonNull get-fc-4 get-x-CompareUnknownAndNonNull)) | |
| :named CompareUnknownAndNonNull-deref-4-x)) | |
| (assert | |
| (! (not (is-unsafe-deref-CompareUnknownAndNonNull get-fc-4 get-y-CompareUnknownAndNonNull)) | |
| :named CompareUnknownAndNonNull-deref-4-y)) | |
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| ;; Example CompareUnknownAndNullAdvanced | |
| ;; | |
| ;; ``` | |
| ;; void target(int *x) { | |
| ;; // (1) | |
| ;; *x; // unsafe | |
| ;; bool b = x == nullptr; | |
| ;; // (2) | |
| ;; *x; // unsafe | |
| ;; if (b) { | |
| ;; // (3) | |
| ;; *x; // unsafe | |
| ;; } else { | |
| ;; // (4) | |
| ;; *x; // safe | |
| ;; } | |
| ;; } | |
| ;; ``` | |
| (declare-datatype State-CompareUnknownAndNullAdvanced | |
| ((make-State-CompareUnknownAndNullAdvanced | |
| (_get-the-nullptr PointerValue) | |
| (_get-x PointerValue) | |
| (_get-b Bool)))) | |
| (define-fun get-x-CompareUnknownAndNullAdvanced | |
| ((state State-CompareUnknownAndNullAdvanced)) PointerValue | |
| (_get-x state)) | |
| (define-fun run-CompareUnknownAndNullAdvanced | |
| ((state State-CompareUnknownAndNullAdvanced)) | |
| FlowConditions | |
| (match state | |
| (((make-State-CompareUnknownAndNullAdvanced the-nullptr x b) | |
| (let ((fc-1 (and (fc-conj--ptr-is-null the-nullptr) | |
| (fc-conj--ptr-is-unknown x)))) | |
| (let ((fc-2 (and fc-1 (fc-conj--ptrs-were-compared x the-nullptr b)))) | |
| (let ((fc-3 (and fc-2 b))) | |
| (let ((fc-4 (and fc-2 (not b)))) | |
| (make-FlowConditions fc-1 fc-2 fc-3 fc-4 false false))))))))) | |
| (define-fun is-reachable-CompareUnknownAndNullAdvanced | |
| ((fc-getter (-> FlowConditions Bool))) | |
| Bool | |
| (exists ((state State-CompareUnknownAndNullAdvanced)) | |
| (let ((fcs (run-CompareUnknownAndNullAdvanced state))) | |
| (fc-getter fcs)))) | |
| (define-fun is-unsafe-deref-CompareUnknownAndNullAdvanced | |
| ((fc-getter (-> FlowConditions Bool)) | |
| (ptr-getter (-> State-CompareUnknownAndNullAdvanced PointerValue))) | |
| Bool | |
| (exists ((state State-CompareUnknownAndNullAdvanced)) | |
| (let ((fcs (run-CompareUnknownAndNullAdvanced state))) | |
| (is-unsafe-to-deref (fc-getter fcs) (ptr-getter state))))) | |
| (define-fun is-solvable-CompareUnknownAndNullAdvanced () Bool | |
| (not (or enable-solution-s1 enable-solution-s2))) | |
| (assert (=> is-solvable-CompareUnknownAndNullAdvanced | |
| (! (is-reachable-CompareUnknownAndNullAdvanced get-fc-1) | |
| :named CompareUnknownAndNullAdvanced-reachable-1))) | |
| (assert (=> is-solvable-CompareUnknownAndNullAdvanced | |
| (! (is-reachable-CompareUnknownAndNullAdvanced get-fc-2) | |
| :named CompareUnknownAndNullAdvanced-reachable-2))) | |
| (assert (=> is-solvable-CompareUnknownAndNullAdvanced | |
| (! (is-reachable-CompareUnknownAndNullAdvanced get-fc-3) | |
| :named CompareUnknownAndNullAdvanced-reachable-3))) | |
| (assert (=> is-solvable-CompareUnknownAndNullAdvanced | |
| (! (is-reachable-CompareUnknownAndNullAdvanced get-fc-4) | |
| :named CompareUnknownAndNullAdvanced-reachable-4))) | |
| (assert (=> is-solvable-CompareUnknownAndNullAdvanced | |
| ;; The dereference at (1) is actually unsafe, but the structure of the | |
| ;; dataflow analysis defined in this file can't detect that. The issue is | |
| ;; that the flow condition at (1) does not have information about what happens | |
| ;; later. | |
| (! (not (is-unsafe-deref-CompareUnknownAndNullAdvanced get-fc-1 get-x-CompareUnknownAndNullAdvanced)) | |
| :named CompareUnknownAndNullAdvanced-deref-1))) | |
| (assert (=> is-solvable-CompareUnknownAndNullAdvanced | |
| (! (is-unsafe-deref-CompareUnknownAndNullAdvanced get-fc-2 get-x-CompareUnknownAndNullAdvanced) | |
| :named CompareUnknownAndNullAdvanced-deref-2))) | |
| (assert (=> is-solvable-CompareUnknownAndNullAdvanced | |
| (! (is-unsafe-deref-CompareUnknownAndNullAdvanced get-fc-3 get-x-CompareUnknownAndNullAdvanced) | |
| :named CompareUnknownAndNullAdvanced-deref-3))) | |
| (assert (=> is-solvable-CompareUnknownAndNullAdvanced | |
| (! (not (is-unsafe-deref-CompareUnknownAndNullAdvanced get-fc-4 get-x-CompareUnknownAndNullAdvanced)) | |
| :named CompareUnknownAndNullAdvanced-deref-4))) | |
| (echo "Verifying the selected solution against test cases.") | |
| (check-sat) | |
| (get-unsat-core) | |
| (get-value (fc-conj--ptr-is-null)) | |
| (get-value (fc-conj--ptr-is-unknown)) | |
| (get-value (fc-conj--ptr-is-nonnull)) | |
| (get-value (fc-conj--ptr-is-nullable)) | |
| (get-value (fc-conj--ptrs-were-compared)) | |
| (get-value (fc-conj--join-ptr)) | |
| (get-value (is-unsafe-to-deref)) | |
| ; vim: set syntax=scheme: |