[cfe-dev] uninitialized variable
Artem Dergachev via cfe-dev
cfe-dev at lists.llvm.org
Thu Sep 15 13:05:41 PDT 2016
Structures are represented by compound and "lazy" compound values. These
values are considered to be defined values even when their contents are
undefined; you can explore their contents to see if all fields of the
structures you receive are undefined.
---
Normal compound values (nonloc::CompoundVal objects) are simple vectors
of SVals; you can iterate over fields in the structure, and
simultaneously iterate over the vector components, and they'd match.
However, compound values are rare, and finding undefined values in them
is even more rare - after all, they're mostly produced from initializer
lists.
---
Lazy compound values (nonloc::LazyCompoundVal objects) are more
interesting and more frequent. They are, essentially, a performance
optimization within the analyzer, which allows quickly copying
structural values when they are passed around. The trick is as follows.
Suppose there's a region R, which is of TypedValueRegion class, and its
value type is a record type. Then, for its fields, there may or may not
be some bindings in the Store (that is, in the section of the
ProgramState that contains values stored in memory). Store is an
immutable ("functional") object which is O(1) to copy. Then, when we
take the value of the region R (for, say, copying purposes), we
construct a LazyCompoundVal object that consists of two items: the
region R and a snapshot of the whole(!) current Store.
The resulting LazyCompoundVal is a frozen value of R at the moment of
copying: subsequent binds to R would not change LazyCompoundVal
retroactively, because the Store within the LazyCompoundVal, like any
other Store, is immutable.
In order to access fields within LazyCompoundVal, you need to:
1. Construct a memory region F that represents the field you're looking
for, within R. For that, you need to find the respective FieldDecl in
the AST, and use MemRegionManager to construct a FieldRegion with this
decl inside R.
2. Find the value of F within the old frozen Store object stored inside
the LazyCompoundVal. For that, you need to take the StoreManager object
for the current analysis (it's a singleton), and ask him to get binding
from the frozen Store for the region F.
---
You might be interested in having a look at the discussion here:
https://reviews.llvm.org/D22374
It was there that we have accidentally realized that we're treating
completely-undefined structures as defined values. It is also
interesting to figure out what to do with partially-undefined
structures. You might also decide to combine your checker with the
existing UndefinedAssignment checker.
On 9/15/16 9:47 PM, McDowell, Raymond C. via cfe-dev wrote:
>
> I am writing a checker to check that a variable is given a value
> before it is accessed. So I created a checkLocation call-back:
>
> void checkLocation(SVal L, bool IsLoad, const Stmt* S, CheckerContext
> &ChCtx) const {
>
> if (!IsLoad) return; // location value is not being accessed
>
> const MemRegion* MemReg = L.getAsRegion();
>
> if (!MemReg) return; // L is not a memory location
>
> const VarRegion* VarReg = MemReg->getAs<VarRegion>();
>
> if (!VarReg) return; // L is not a variable location
>
> SVal VarVal = ChCtx.getState()->getSVal(VarReg);
>
> if (VarVal.isUndef()) {
>
> // Variable value is undefined; report error
>
> EmitReport(S->getSourceRange(), ChCtx, “Variable may not have been
> assigned a value”);
>
> }
>
> }
>
> This works fine for scalar variables like ints, but I’ve discovered
> that a struct variable will be defined even if it hasn’t been given a
> value. So my plan is to check the struct fields to see if they’ve
> been given values.
>
> My question is: are there other cases where VarVal.isUndef() will
> return false even though the variable has not been given a value?
>
> Ray
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
More information about the cfe-dev
mailing list