Clearly specify the behavior of llvm_extract
/llvm_compositional_extract
with respect to global variables
#2093
Labels
subsystem: crucible-llvm
Issues related to LLVM bitcode verification with crucible-llvm
type: enhancement
Issues describing an improvement to an existing feature or capability
SAW's
:help
output forllvm_extract
andllvm_compositional_extract
do not clearly specify how either command should behave in the presence of code that reads or modifies global variables. I'd request that this be done, as the current implementation is somewhat hard to explain.Here are a series of examples that attempt to demonstrate how each command currently works with respect to global variables, along with my recommendations for how the commands should work. First, let's look at
llvm_extract
. At the moment, callingllvm_extract
on any function that references a global variable at all will fail with the following error:The error message is a bit much, but I think this behavior isn't entirely unreasonable. My impression is that
llvm_extract
is primarily meant for C functions that do not involve any side effects (as you'd likely want a full-blown SAW specification to reason about those), and reading from a global variable ought to be considered a side effect. I propose thatllvm_extract
explicitly document the fact that it does not support global variables, perhaps improving the error message as well.Now let's move on to
llvm_compositional_extract
. Unlikellvm_extract
,llvm_compositional_extract
does require a full-blown SAW specification, so I would expect it to be able to reason about global variables. Some experimentation suggests that this is indeed the case, but it's less clear on when global variables will be part of the type of the extracted definition.To explain what I mean, first consider this example:
Should
g
be considered an input in the extracted definition? An output? As it turns out, that depends on how you define the specification forf
. Here is a SAW script that contains four specifications forf
, and although they are all very similar, they causellvm_compositional_extract
to produce very different definitions:Here is a breakdown of each result:
f_spec_1
andf_spec_2
both produce the definition\x -> x
. That is,g
is neither an input nor an output. I think there is a case to be made thatg
isn't a meaningful input, as the specification either leavesg
's initial value unspecified (f_spec_1
) or requires that the initial value be0
(f_spec_2
). I do find it strange thatg
is not listed as an output, however, given that the function modifiesg
.f_spec_3
produces the definition\x g -> x
. That is,g
is now an explicit input. I think this is sensible, given thatg
's initial value can be anything.g
is still not listed as an output parameter, however. This seems especially bad here, given thatg
's value can change after the function is invoked.f_spec_4
produces the definition\x g -> (x, 0)
. I think this is the most reasonable-looking result of the whole bunch, but unfortunately, it also required the most boilerplate (in the form of extrallvm_fresh_var
s in the postconditions).I think that
llvm_compositional_extract
's behavior around extracting global variables as inputs is fairly reasonable, but I find its behavior around extracting global variables as outputs to be very surprising. (See also #2091, which is in similar territory.) I propose that if a function modifies a global variable, then it should always be treated as an output.The text was updated successfully, but these errors were encountered: