NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet.
Herald added subscribers: cfe-commits, rnkovacs.
Make use of the new callback introduced in https://reviews.llvm.org/D41406 for
tracking values allocated by `operator new()` in `-analyzer-config
c++-allocator-inlining=true` mode. Most of the patch actually has no intended
functional changes, apart from the `StripCasts` part, which is similar to
https://reviews.llvm.org/D41796 and fixes two tests in `ptr-arith.cpp`
(`checkNew()` and `getArray()`).
(@xazax.hun - this is an alpha checker last touched by you, do you still have
plans for it?)
Repository:
rC Clang
https://reviews.llvm.org/D41799
Files:
lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
test/Analysis/ptr-arith.cpp
Index: test/Analysis/ptr-arith.cpp
===================================================================
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14
-analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
+// RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14
-analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm
-analyzer-config c++-allocator-inlining=true -verify %s
struct X {
int *p;
int zero;
Index: lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
+++ lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
@@ -46,7 +46,7 @@
check::PreStmt<BinaryOperator>, check::PreStmt<UnaryOperator>,
check::PreStmt<ArraySubscriptExpr>, check::PreStmt<CastExpr>,
check::PostStmt<CastExpr>, check::PostStmt<CXXNewExpr>,
- check::PostStmt<CallExpr>, check::DeadSymbols> {
+ check::PostStmt<CallExpr>, check::DeadSymbols, check::NewAllocator> {
AllocKind getKindOfNewOp(const CXXNewExpr *NE, const FunctionDecl *FD) const;
const MemRegion *getArrayRegion(const MemRegion *Region, bool &Polymorphic,
AllocKind &AKind, CheckerContext &C) const;
@@ -56,6 +56,9 @@
bool PointedNeeded = false) const;
void initAllocIdentifiers(ASTContext &C) const;
+ void processNewAllocatorAux(const CXXNewExpr *NE, SVal Target,
+ CheckerContext &C) const;
+
mutable std::unique_ptr<BuiltinBug> BT_pointerArith;
mutable std::unique_ptr<BuiltinBug> BT_polyArray;
mutable llvm::SmallSet<IdentifierInfo *, 8> AllocFunctions;
@@ -69,6 +72,8 @@
void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
+ void checkNewAllocator(const CXXNewExpr *NE, SVal Target,
+ CheckerContext &C) const;
};
} // end namespace
@@ -239,21 +244,34 @@
C.addTransition(State);
}
-void PointerArithChecker::checkPostStmt(const CXXNewExpr *NE,
- CheckerContext &C) const {
+void PointerArithChecker::processNewAllocatorAux(const CXXNewExpr *NE,
+ SVal Target,
+ CheckerContext &C) const {
const FunctionDecl *FD = NE->getOperatorNew();
if (!FD)
return;
- AllocKind Kind = getKindOfNewOp(NE, FD);
-
- ProgramStateRef State = C.getState();
- SVal AllocedVal = State->getSVal(NE, C.getLocationContext());
- const MemRegion *Region = AllocedVal.getAsRegion();
+ const MemRegion *Region = Target.getAsRegion();
if (!Region)
return;
- State = State->set<RegionState>(Region, Kind);
- C.addTransition(State);
+
+ Region = Region->StripCasts();
+
+ AllocKind Kind = getKindOfNewOp(NE, FD);
+
+ C.addTransition(C.getState()->set<RegionState>(Region, Kind));
+}
+
+void PointerArithChecker::checkPostStmt(const CXXNewExpr *NE,
+ CheckerContext &C) const {
+ if (!C.getAnalysisManager().getAnalyzerOptions().mayInlineCXXAllocator())
+ processNewAllocatorAux(NE, C.getSVal(NE), C);
+}
+
+void PointerArithChecker::checkNewAllocator(const CXXNewExpr *NE,
+ SVal Target, CheckerContext &C) const {
+ if (!C.wasInlined)
+ processNewAllocatorAux(NE, Target, C);
}
void PointerArithChecker::checkPostStmt(const CastExpr *CE,
Index: test/Analysis/ptr-arith.cpp
===================================================================
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14 -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
+// RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14 -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -analyzer-config c++-allocator-inlining=true -verify %s
struct X {
int *p;
int zero;
Index: lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
+++ lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
@@ -46,7 +46,7 @@
check::PreStmt<BinaryOperator>, check::PreStmt<UnaryOperator>,
check::PreStmt<ArraySubscriptExpr>, check::PreStmt<CastExpr>,
check::PostStmt<CastExpr>, check::PostStmt<CXXNewExpr>,
- check::PostStmt<CallExpr>, check::DeadSymbols> {
+ check::PostStmt<CallExpr>, check::DeadSymbols, check::NewAllocator> {
AllocKind getKindOfNewOp(const CXXNewExpr *NE, const FunctionDecl *FD) const;
const MemRegion *getArrayRegion(const MemRegion *Region, bool &Polymorphic,
AllocKind &AKind, CheckerContext &C) const;
@@ -56,6 +56,9 @@
bool PointedNeeded = false) const;
void initAllocIdentifiers(ASTContext &C) const;
+ void processNewAllocatorAux(const CXXNewExpr *NE, SVal Target,
+ CheckerContext &C) const;
+
mutable std::unique_ptr<BuiltinBug> BT_pointerArith;
mutable std::unique_ptr<BuiltinBug> BT_polyArray;
mutable llvm::SmallSet<IdentifierInfo *, 8> AllocFunctions;
@@ -69,6 +72,8 @@
void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
+ void checkNewAllocator(const CXXNewExpr *NE, SVal Target,
+ CheckerContext &C) const;
};
} // end namespace
@@ -239,21 +244,34 @@
C.addTransition(State);
}
-void PointerArithChecker::checkPostStmt(const CXXNewExpr *NE,
- CheckerContext &C) const {
+void PointerArithChecker::processNewAllocatorAux(const CXXNewExpr *NE,
+ SVal Target,
+ CheckerContext &C) const {
const FunctionDecl *FD = NE->getOperatorNew();
if (!FD)
return;
- AllocKind Kind = getKindOfNewOp(NE, FD);
-
- ProgramStateRef State = C.getState();
- SVal AllocedVal = State->getSVal(NE, C.getLocationContext());
- const MemRegion *Region = AllocedVal.getAsRegion();
+ const MemRegion *Region = Target.getAsRegion();
if (!Region)
return;
- State = State->set<RegionState>(Region, Kind);
- C.addTransition(State);
+
+ Region = Region->StripCasts();
+
+ AllocKind Kind = getKindOfNewOp(NE, FD);
+
+ C.addTransition(C.getState()->set<RegionState>(Region, Kind));
+}
+
+void PointerArithChecker::checkPostStmt(const CXXNewExpr *NE,
+ CheckerContext &C) const {
+ if (!C.getAnalysisManager().getAnalyzerOptions().mayInlineCXXAllocator())
+ processNewAllocatorAux(NE, C.getSVal(NE), C);
+}
+
+void PointerArithChecker::checkNewAllocator(const CXXNewExpr *NE,
+ SVal Target, CheckerContext &C) const {
+ if (!C.wasInlined)
+ processNewAllocatorAux(NE, Target, C);
}
void PointerArithChecker::checkPostStmt(const CastExpr *CE,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits