ormris updated this revision to Diff 150567.
ormris added a comment.
Herald added a subscriber: mikhail.ramalho.
- Reformat with clang-format-diff.py
- Rename test
- Modify test to use clang_analyzer_eval
Repository:
rC Clang
https://reviews.llvm.org/D47044
Files:
include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
lib/StaticAnalyzer/Core/ExprEngine.cpp
lib/StaticAnalyzer/Core/LoopWidening.cpp
test/Analysis/loop-widening-preserve-reference-type.cpp
Index: test/Analysis/loop-widening-preserve-reference-type.cpp
===================================================================
--- /dev/null
+++ test/Analysis/loop-widening-preserve-reference-type.cpp
@@ -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 == &x); // expected-warning{{TRUE}}
+}
Index: lib/StaticAnalyzer/Core/LoopWidening.cpp
===================================================================
--- lib/StaticAnalyzer/Core/LoopWidening.cpp
+++ lib/StaticAnalyzer/Core/LoopWidening.cpp
@@ -15,9 +15,15 @@
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h"
+#include "clang/AST/AST.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+#include "llvm/ADT/SmallSet.h"
using namespace clang;
using namespace ento;
+using namespace clang::ast_matchers;
/// Return the loops condition Stmt or NULL if LoopStmt is not a loop
static const Expr *getLoopCondition(const Stmt *LoopStmt) {
@@ -33,10 +39,26 @@
}
}
+struct Callback : public MatchFinder::MatchCallback {
+ const LocationContext *LCtx;
+ MemRegionManager &MRMgr;
+ RegionAndSymbolInvalidationTraits &ITraits;
+ explicit Callback(const LocationContext *LCtx_, MemRegionManager &MRMgr_,
+ RegionAndSymbolInvalidationTraits &ITraits_)
+ : LCtx(LCtx_), MRMgr(MRMgr_), ITraits(ITraits_) {}
+ virtual void run(const MatchFinder::MatchResult &Result) override {
+ const VarDecl *VD = Result.Nodes.getNodeAs<VarDecl>("match");
+ const VarRegion *VarMem = MRMgr.getVarRegion(VD, LCtx);
+ ITraits.setTrait(VarMem,
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents);
+ }
+};
+
namespace clang {
namespace ento {
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState,
+ ASTContext &ASTCtx,
const LocationContext *LCtx,
unsigned BlockCount, const Stmt *LoopStmt) {
@@ -60,6 +82,12 @@
RegionAndSymbolInvalidationTraits::TK_EntireMemSpace);
}
+ // References should not be invalidated.
+ MatchFinder Finder;
+ Finder.addMatcher(varDecl(hasType(referenceType())).bind("match"),
+ new Callback(LCtx, MRMgr, ITraits));
+ Finder.matchAST(ASTCtx);
+
// '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.
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1854,8 +1854,8 @@
return;
// Widen.
const LocationContext *LCtx = Pred->getLocationContext();
- ProgramStateRef WidenedState =
- getWidenedLoopState(Pred->getState(), LCtx, BlockCount, Term);
+ ProgramStateRef WidenedState = getWidenedLoopState(
+ Pred->getState(), AMgr.getASTContext(), LCtx, BlockCount, Term);
nodeBuilder.generateNode(WidenedState, Pred);
return;
}
Index: include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
@@ -27,6 +27,7 @@
/// Widen the loop by invalidating anything that might be modified
/// by the loop body in any iteration.
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState,
+ ASTContext &ASTCtx,
const LocationContext *LCtx,
unsigned BlockCount, const Stmt *LoopStmt);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits