r334554 - [analyzer] Ensure that loop widening does not invalidate references

Matthew Voss via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 12 15:22:35 PDT 2018


Author: ormris
Date: Tue Jun 12 15:22:35 2018
New Revision: 334554

URL: http://llvm.org/viewvc/llvm-project?rev=334554&view=rev
Log:
[analyzer] Ensure that loop widening does not invalidate references

Loop widening can invalidate a reference. If the analyzer attempts to visit the
destructor to a non-existent reference, it will crash. This patch ensures that
the reference is preserved.

https://reviews.llvm.org/D47044


Added:
    cfe/trunk/test/Analysis/loop-widening-preserve-reference-type.cpp
Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp?rev=334554&r1=334553&r2=334554&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/LoopWidening.cpp Tue Jun 12 15:22:35 2018
@@ -14,10 +14,16 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "clang/AST/AST.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h"
 
 using namespace clang;
 using namespace ento;
+using namespace clang::ast_matchers;
+
+const auto MatchRef = "matchref";
 
 /// Return the loops condition Stmt or NULL if LoopStmt is not a loop
 static const Expr *getLoopCondition(const Stmt *LoopStmt) {
@@ -49,6 +55,7 @@ ProgramStateRef getWidenedLoopState(Prog
   // TODO Nested loops are currently widened as a result of the invalidation
   //      being so inprecise. When the invalidation is improved, the handling
   //      of nested loops will also need to be improved.
+  ASTContext &ASTCtx = LCtx->getAnalysisDeclContext()->getASTContext();
   const StackFrameContext *STC = LCtx->getCurrentStackFrame();
   MemRegionManager &MRMgr = PrevState->getStateManager().getRegionManager();
   const MemRegion *Regions[] = {MRMgr.getStackLocalsRegion(STC),
@@ -60,6 +67,18 @@ ProgramStateRef getWidenedLoopState(Prog
                      RegionAndSymbolInvalidationTraits::TK_EntireMemSpace);
   }
 
+  // References should not be invalidated.
+  auto Matches = match(findAll(stmt(hasDescendant(varDecl(hasType(referenceType())).bind(MatchRef)))),
+                       *LCtx->getDecl()->getBody(), ASTCtx);
+  for (BoundNodes Match : Matches) {
+    const VarDecl *VD = Match.getNodeAs<VarDecl>(MatchRef);
+    assert(VD);
+    const VarRegion *VarMem = MRMgr.getVarRegion(VD, LCtx);
+    ITraits.setTrait(VarMem,
+                     RegionAndSymbolInvalidationTraits::TK_PreserveContents);
+  }
+
+
   // 'this' pointer is not an lvalue, we should not invalidate it. If the loop
   // is located in a method, constructor or destructor, the value of 'this'
   // pointer shoule remain unchanged.

Added: cfe/trunk/test/Analysis/loop-widening-preserve-reference-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/loop-widening-preserve-reference-type.cpp?rev=334554&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/loop-widening-preserve-reference-type.cpp (added)
+++ cfe/trunk/test/Analysis/loop-widening-preserve-reference-type.cpp Tue Jun 12 15:22:35 2018
@@ -0,0 +1,14 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s
+
+void clang_analyzer_eval(int);
+
+struct A {
+  ~A() {}
+};
+struct B : public A {};
+
+void invalid_type_region_access() {
+  const A &x = B();
+  for (int i = 0; i < 10; ++i) { }
+  clang_analyzer_eval(&x != 0); // expected-warning{{TRUE}}
+}                               // expected-warning at -1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}




More information about the cfe-commits mailing list