gradual-verification / silicon-gv

Mozilla Public License 2.0
0 stars 3 forks source link

Unable to match type for Null during static verification of avlja.c0 #46

Closed icmccorm closed 2 years ago

icmccorm commented 2 years ago

Certain permutations of AVL cause static verification to fail with the following exception:

java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unable to match type for Null!

The following three permutations recreate this issue:

jennalwise commented 2 years ago

Major Issue causing the above error: //@unfold avlh(node->right->left, node->right->leftHeight); on line 194 has its predicate optimistically assumed and the verifier at this point does not know whether node->right->left is null (probably due to optimism) and so when the predicate body is produced it branches on whether node->right->left is null or not and that information is added to the path condition. Permission to node->right->left is saved in the optimistic heap as well at this point. Upon analyzing the next line: rllh = node->right->left->leftHeight; eval is used to evaluate the rhs which looks for permission to node->right->left->leftHeight in the symbolic heaps. It is not there, so the verifier optimistically assumes it has access to it (thanks to imprecision) and adds permission to it into the optimistic heap. This creates an invalid state as permission to node->right->left->leftHeight implies node->right->left != null and the path condition contains node->right->left == null. Instead, the verifier should fail execution down this path at the point where eval looks to assume permission to node->right->left->leftHeight as doing so contradicts currently known information by the verifier. Other places where eval/eval-pc are used should be reconsidered for correctness based on the aforementioned realization.

Viper does not need to worry about this functionality in eval, because they fail if an accessibility predicate for a field is not available in the symbolic heap and an accessibility predicate implies the field receiver is not null.

jennalwise commented 2 years ago

A secondary issue with the aforementioned examples: The given error does not always occur on every run. Upon initial inspection it looks like for some reason symbolic execution is not going down the if case/branch where the error occurs in like 1 out of 10 runs, the other runs it does and produces the error. This is highly unusual behavior, and I still need to figure out why the offending branch is sometimes being pruned and sometimes not being pruned.

jennalwise commented 2 years ago

Primary issue fixed in commits: https://github.com/gradual-verification/silicon-gv/commit/281e7075f59a130f3674e45404c23480c0a16926, https://github.com/gradual-verification/silicon-gv/commit/6047a7925905f0ba1a27537ecaabe053dfd03689, and https://github.com/gradual-verification/silicon-gv/commit/54daa45fa2eae431093f4b79570621b9c5d947bd