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).