This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] Canonicalize variable declarations in VarRegion objects.
ClosedPublic

Authored by NoQ on Feb 1 2019, 2:23 PM.

Details

Summary

A follow-up from D46421#1375147 - huh, yes, indeed, this is broken:

extern int x;

void foo() { x = 2; }

extern int x;

int main() {
  x = 1;
  foo();

  // TRUE but should be FALSE
  clang_analyzer_eval(x == 1);
  // FALSE but should be TRUE
  clang_analyzer_eval(x == 2); 
}

This does actually create a Store that looks like this:

(x,0,direct) : 1 S32b

(x,0,direct) : 2 S32b

Fxd. Note that we cannot canonicalize decls in constructors because static VarRegion::Profile() gets called in MemRegionManager::getSubRegion() before calling the actual constructor in order to find the location of the variable, and this should correspond exactly to the non-static VarRegion::Profile() at later points in the program, otherwise even in this example we get much more than 2 duplicate regions (MemRegionManager would repeatedly construct the region and then fail to look it up next time it is requested).

Diff Detail