This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] const init: handle non-explicit cases more accurately
ClosedPublic

Authored by r.stahl on May 14 2018, 3:08 AM.

Diff Detail

Event Timeline

r.stahl created this revision.May 14 2018, 3:08 AM
NoQ added a comment.May 14 2018, 4:33 PM

Yay thanks!

I think some cornercases would need to be dealt with.

lib/StaticAnalyzer/Core/RegionStore.cpp
1650

What if we have an out-of-bounds access to a variable-length array? I don't think it'd yield zero.

1650–1652

Would this work correctly if the element is not of an integral or enumeration type? I think this needs an explicit check.

1733

Same: would this work correctly if the field is not of an integral or enumeration type?

test/Analysis/initialization.c
3

We try to avoid using dump() on tests because it makes tests test the dump syntax, which isn't the point.

For checking constants, it's easier to do something like clang_analyzer_eval(parr[i] == 2); // expected-warning{{TRUE}}.

For finding undefined values, you can enable core.uninitialized checkers and receive warnings when the argument of clang_analyzer_eval is an uninitialized value. Or just increment the value.

r.stahl updated this revision to Diff 146809.May 15 2018, 6:43 AM
r.stahl marked 2 inline comments as done.

updated test

lib/StaticAnalyzer/Core/RegionStore.cpp
1650

I'm getting "variable-sized object may not be initialized", so this case should not be possible.

1650–1652

I'm having a hard time reproducing this either.

struct S {
  int a = 3;
};
S const sarr[2] = {};
void definit() {
  int i = 1;
  clang_analyzer_dump(sarr[i].a); // expected-warning{{test}}
}

results in a symbolic value, because makeZeroVal returns an empty SVal list for arrays, records, vectors and complex types. Otherwise it just returns UnknownVal (for example for not-yet-implemented floats).

Can you think of a case where this would be an issue?

NoQ accepted this revision.May 25 2018, 11:41 AM

Looks good!

Do you have commit access? I think you should get commit access.

lib/StaticAnalyzer/Core/RegionStore.cpp
1650

Yup, sounds reasonable.

1650–1652

Had a look. This indeed looks fine, but for a completely different reason. In fact structs don't appear in getBindingForElement() because they all go through getBindingForStruct() instead. Hopefully this does take care of other cornercases.

So your test case doesn't even trigger your code to be executed, neither would S s = sarr[i]; clang_analyzer_dump(s.a);.

Still, as far as i understand, sarr here should be zero-initialized, so i think the symbolic value can be improved upon, so we might as well add this as a FIXME test.

This revision is now accepted and ready to land.May 25 2018, 11:41 AM
r.stahl updated this revision to Diff 148809.May 28 2018, 6:48 AM

Added FIXME tests.

I know my example didn't exercise your scenario, but it was the only one I could think of where returning zero would have been straight up wrong. Note that I default initialized a to 3 there, so sarr is not just zero-initialized.

I do not have access yet, but applied today!

This revision was automatically updated to reflect the committed changes.