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 cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits