]> granicus.if.org Git - clang/commitdiff
[analyzer] Canonicalize declarations within variable regions.
authorArtem Dergachev <artem.dergachev@gmail.com>
Thu, 7 Feb 2019 00:30:20 +0000 (00:30 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Thu, 7 Feb 2019 00:30:20 +0000 (00:30 +0000)
Memory region that correspond to a variable is identified by the variable's
declaration and, in case of local variables, the stack frame it belongs to.

The declaration needs to be canonical, otherwise we'd have two different
memory regions that correspond to the same variable.

Fix such bug for global variables with forward declarations and assert
that no other problems of this kind happen.

Differential Revision: https://reviews.llvm.org/D57619

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@353353 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
lib/StaticAnalyzer/Core/MemRegion.cpp
test/Analysis/globals.cpp

index 85eb4b865abc9e289937232798a84344a25f57fe..071e35085a5f93f6a0620e18186c56a7e7ef3849 100644 (file)
@@ -908,7 +908,7 @@ protected:
   DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k)
       : TypedValueRegion(sReg, k), D(d) {
     assert(classof(this));
-    assert(d);
+    assert(d && d->isCanonicalDecl());
   }
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
index fd08f92a658e8ff07a5af01fec7fd71e35981edb..b9619d173ddf967962cc0dcfdb401eb8654bf39f 100644 (file)
@@ -844,6 +844,7 @@ getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
 
 const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
                                                 const LocationContext *LC) {
+  D = D->getCanonicalDecl();
   const MemRegion *sReg = nullptr;
 
   if (D->hasGlobalStorage() && !D->isStaticLocal()) {
@@ -930,6 +931,7 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
 
 const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
                                                 const MemRegion *superR) {
+  D = D->getCanonicalDecl();
   return getSubRegion<VarRegion>(D, superR);
 }
 
index 5bbb241bdcf377046e1ef7eb64857cd0c4b1ed5e..d3df6eb6d27c04c8efa82bc45182d15acc276fbb 100644 (file)
@@ -109,3 +109,18 @@ void recordinit()
     S3 s3;
     *(s3.p - 1) = 0; // expected-warning{{Dereference of null pointer}}
 }
+
+extern int ext_int;
+
+void update_original_declaration() {
+  ext_int = 2;
+}
+
+extern int ext_int;
+
+int test_redeclaration() {
+  ext_int = 1;
+  update_original_declaration();
+  int int_int = 3 / (ext_int - 1); // no-warning
+  return int_int / (ext_int - 2); // expected-warning{{Division by zero}}
+}