diff --git a/clang/include/clang/Analysis/Analyses/Consumed.h b/clang/include/clang/Analysis/Analyses/Consumed.h index 3e2788cac3c9c..0e4818f043b9e 100644 --- a/clang/include/clang/Analysis/Analyses/Consumed.h +++ b/clang/include/clang/Analysis/Analyses/Consumed.h @@ -38,235 +38,235 @@ class VarDecl; namespace consumed { - class ConsumedStmtVisitor; - - enum ConsumedState { - // No state information for the given variable. - CS_None, - - CS_Unknown, - CS_Unconsumed, - CS_Consumed - }; - - using OptionalNotes = SmallVector; - using DelayedDiag = std::pair; - using DiagList = std::list; - - class ConsumedWarningsHandlerBase { - public: - virtual ~ConsumedWarningsHandlerBase(); - - /// Emit the warnings and notes left by the analysis. - virtual void emitDiagnostics() {} - - /// Warn that a variable's state doesn't match at the entry and exit - /// of a loop. - /// - /// \param Loc -- The location of the end of the loop. - /// - /// \param VariableName -- The name of the variable that has a mismatched - /// state. - virtual void warnLoopStateMismatch(SourceLocation Loc, - StringRef VariableName) {} - - /// Warn about parameter typestate mismatches upon return. - /// - /// \param Loc -- The SourceLocation of the return statement. - /// - /// \param ExpectedState -- The state the return value was expected to be - /// in. - /// - /// \param ObservedState -- The state the return value was observed to be - /// in. - virtual void warnParamReturnTypestateMismatch(SourceLocation Loc, - StringRef VariableName, - StringRef ExpectedState, - StringRef ObservedState) {} - - // FIXME: Add documentation. - virtual void warnParamTypestateMismatch(SourceLocation LOC, - StringRef ExpectedState, - StringRef ObservedState) {} - - // FIXME: This can be removed when the attr propagation fix for templated - // classes lands. - /// Warn about return typestates set for unconsumable types. - /// - /// \param Loc -- The location of the attributes. - /// - /// \param TypeName -- The name of the unconsumable type. - virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc, - StringRef TypeName) {} - - /// Warn about return typestate mismatches. - /// - /// \param Loc -- The SourceLocation of the return statement. - /// - /// \param ExpectedState -- The state the return value was expected to be - /// in. - /// - /// \param ObservedState -- The state the return value was observed to be - /// in. - virtual void warnReturnTypestateMismatch(SourceLocation Loc, - StringRef ExpectedState, - StringRef ObservedState) {} - - /// Warn about use-while-consumed errors. - /// \param MethodName -- The name of the method that was incorrectly - /// invoked. - /// - /// \param State -- The state the object was used in. - /// - /// \param Loc -- The SourceLocation of the method invocation. - virtual void warnUseOfTempInInvalidState(StringRef MethodName, - StringRef State, - SourceLocation Loc) {} - - /// Warn about use-while-consumed errors. - /// \param MethodName -- The name of the method that was incorrectly - /// invoked. - /// - /// \param State -- The state the object was used in. - /// - /// \param VariableName -- The name of the variable that holds the unique - /// value. - /// - /// \param Loc -- The SourceLocation of the method invocation. - virtual void warnUseInInvalidState(StringRef MethodName, - StringRef VariableName, - StringRef State, - SourceLocation Loc) {} - }; - - class ConsumedStateMap { - using VarMapType = llvm::DenseMap; - using TmpMapType = - llvm::DenseMap; - - protected: - bool Reachable = true; - const Stmt *From = nullptr; - VarMapType VarMap; - TmpMapType TmpMap; - - public: - ConsumedStateMap() = default; - ConsumedStateMap(const ConsumedStateMap &Other) - : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap) {} - - // The copy assignment operator is defined as deleted pending further - // motivation. - ConsumedStateMap &operator=(const ConsumedStateMap &) = delete; - - /// Warn if any of the parameters being tracked are not in the state - /// they were declared to be in upon return from a function. - void checkParamsForReturnTypestate(SourceLocation BlameLoc, +class ConsumedStmtVisitor; + +enum ConsumedState { + // No state information for the given variable. + CS_None, + + CS_Unknown, + CS_Unconsumed, + CS_Consumed +}; + +using OptionalNotes = SmallVector; +using DelayedDiag = std::pair; +using DiagList = std::list; + +class ConsumedWarningsHandlerBase { +public: + virtual ~ConsumedWarningsHandlerBase(); + + /// Emit the warnings and notes left by the analysis. + virtual void emitDiagnostics() {} + + /// Warn that a variable's state doesn't match at the entry and exit + /// of a loop. + /// + /// \param Loc -- The location of the end of the loop. + /// + /// \param VariableName -- The name of the variable that has a mismatched + /// state. + virtual void warnLoopStateMismatch(SourceLocation Loc, + StringRef VariableName) {} + + /// Warn about parameter typestate mismatches upon return. + /// + /// \param Loc -- The SourceLocation of the return statement. + /// + /// \param ExpectedState -- The state the return value was expected to be + /// in. + /// + /// \param ObservedState -- The state the return value was observed to be + /// in. + virtual void warnParamReturnTypestateMismatch(SourceLocation Loc, + StringRef VariableName, + StringRef ExpectedState, + StringRef ObservedState) {} + + // FIXME: Add documentation. + virtual void warnParamTypestateMismatch(SourceLocation LOC, + StringRef ExpectedState, + StringRef ObservedState) {} + + // FIXME: This can be removed when the attr propagation fix for templated + // classes lands. + /// Warn about return typestates set for unconsumable types. + /// + /// \param Loc -- The location of the attributes. + /// + /// \param TypeName -- The name of the unconsumable type. + virtual void warnReturnTypestateForUnconsumableType(SourceLocation Loc, + StringRef TypeName) {} + + /// Warn about return typestate mismatches. + /// + /// \param Loc -- The SourceLocation of the return statement. + /// + /// \param ExpectedState -- The state the return value was expected to be + /// in. + /// + /// \param ObservedState -- The state the return value was observed to be + /// in. + virtual void warnReturnTypestateMismatch(SourceLocation Loc, + StringRef ExpectedState, + StringRef ObservedState) {} + + /// Warn about use-while-consumed errors. + /// \param MethodName -- The name of the method that was incorrectly + /// invoked. + /// + /// \param State -- The state the object was used in. + /// + /// \param Loc -- The SourceLocation of the method invocation. + virtual void warnUseOfTempInInvalidState(StringRef MethodName, + StringRef State, + SourceLocation Loc) {} + + /// Warn about use-while-consumed errors. + /// \param MethodName -- The name of the method that was incorrectly + /// invoked. + /// + /// \param State -- The state the object was used in. + /// + /// \param VariableName -- The name of the variable that holds the unique + /// value. + /// + /// \param Loc -- The SourceLocation of the method invocation. + virtual void warnUseInInvalidState(StringRef MethodName, + StringRef VariableName, StringRef State, + SourceLocation Loc) {} +}; + +class ConsumedStateMap { + using VarMapType = llvm::DenseMap; + using TmpMapType = + llvm::DenseMap; + +protected: + bool Reachable = true; + const Stmt *From = nullptr; + VarMapType VarMap; + TmpMapType TmpMap; + +public: + ConsumedStateMap() = default; + ConsumedStateMap(const ConsumedStateMap &Other) + : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap) {} + + // The copy assignment operator is defined as deleted pending further + // motivation. + ConsumedStateMap &operator=(const ConsumedStateMap &) = delete; + + /// Warn if any of the parameters being tracked are not in the state + /// they were declared to be in upon return from a function. + void checkParamsForReturnTypestate( + SourceLocation BlameLoc, ConsumedWarningsHandlerBase &WarningsHandler) const; - /// Clear the TmpMap. - void clearTemporaries(); + /// Clear the TmpMap. + void clearTemporaries(); - /// Get the consumed state of a given variable. - ConsumedState getState(const VarDecl *Var) const; + /// Get the consumed state of a given variable. + ConsumedState getState(const VarDecl *Var) const; - /// Get the consumed state of a given temporary value. - ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const; + /// Get the consumed state of a given temporary value. + ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const; - /// Merge this state map with another map. - void intersect(const ConsumedStateMap &Other); + /// Merge this state map with another map. + void intersect(const ConsumedStateMap &Other); - void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack, - const ConsumedStateMap *LoopBackStates, - ConsumedWarningsHandlerBase &WarningsHandler); + void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack, + const ConsumedStateMap *LoopBackStates, + ConsumedWarningsHandlerBase &WarningsHandler); - /// Return true if this block is reachable. - bool isReachable() const { return Reachable; } + /// Return true if this block is reachable. + bool isReachable() const { return Reachable; } - /// Mark the block as unreachable. - void markUnreachable(); + /// Mark the block as unreachable. + void markUnreachable(); - /// Set the source for a decision about the branching of states. - /// \param Source -- The statement that was the origin of a branching - /// decision. - void setSource(const Stmt *Source) { this->From = Source; } + /// Set the source for a decision about the branching of states. + /// \param Source -- The statement that was the origin of a branching + /// decision. + void setSource(const Stmt *Source) { this->From = Source; } - /// Set the consumed state of a given variable. - void setState(const VarDecl *Var, ConsumedState State); + /// Set the consumed state of a given variable. + void setState(const VarDecl *Var, ConsumedState State); - /// Set the consumed state of a given temporary value. - void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State); + /// Set the consumed state of a given temporary value. + void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State); - /// Remove the temporary value from our state map. - void remove(const CXXBindTemporaryExpr *Tmp); + /// Remove the temporary value from our state map. + void remove(const CXXBindTemporaryExpr *Tmp); - /// Tests to see if there is a mismatch in the states stored in two - /// maps. - /// - /// \param Other -- The second map to compare against. - bool operator!=(const ConsumedStateMap *Other) const; - }; + /// Tests to see if there is a mismatch in the states stored in two + /// maps. + /// + /// \param Other -- The second map to compare against. + bool operator!=(const ConsumedStateMap *Other) const; +}; - class ConsumedBlockInfo { - std::vector> StateMapsArray; - std::vector VisitOrder; +class ConsumedBlockInfo { + std::vector> StateMapsArray; + std::vector VisitOrder; - public: - ConsumedBlockInfo() = default; +public: + ConsumedBlockInfo() = default; - ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph) - : StateMapsArray(NumBlocks), VisitOrder(NumBlocks, 0) { - unsigned int VisitOrderCounter = 0; - for (const auto BI : *SortedGraph) - VisitOrder[BI->getBlockID()] = VisitOrderCounter++; - } + ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph) + : StateMapsArray(NumBlocks), VisitOrder(NumBlocks, 0) { + unsigned int VisitOrderCounter = 0; + for (const auto BI : *SortedGraph) + VisitOrder[BI->getBlockID()] = VisitOrderCounter++; + } - bool allBackEdgesVisited(const CFGBlock *CurrBlock, - const CFGBlock *TargetBlock); + bool allBackEdgesVisited(const CFGBlock *CurrBlock, + const CFGBlock *TargetBlock); - void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, - std::unique_ptr &OwnedStateMap); - void addInfo(const CFGBlock *Block, - std::unique_ptr StateMap); + void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, + std::unique_ptr &OwnedStateMap); + void addInfo(const CFGBlock *Block, + std::unique_ptr StateMap); - ConsumedStateMap* borrowInfo(const CFGBlock *Block); + ConsumedStateMap *borrowInfo(const CFGBlock *Block); - void discardInfo(const CFGBlock *Block); + void discardInfo(const CFGBlock *Block); - std::unique_ptr getInfo(const CFGBlock *Block); + std::unique_ptr getInfo(const CFGBlock *Block); - bool isBackEdge(const CFGBlock *From, const CFGBlock *To); - bool isBackEdgeTarget(const CFGBlock *Block); - }; + bool isBackEdge(const CFGBlock *From, const CFGBlock *To); + bool isBackEdgeTarget(const CFGBlock *Block); +}; - /// A class that handles the analysis of uniqueness violations. - class ConsumedAnalyzer { - ConsumedBlockInfo BlockInfo; - std::unique_ptr CurrStates; +/// A class that handles the analysis of uniqueness violations. +class ConsumedAnalyzer { + ConsumedBlockInfo BlockInfo; + std::unique_ptr CurrStates; - ConsumedState ExpectedReturnState = CS_None; + ConsumedState ExpectedReturnState = CS_None; - void determineExpectedReturnState(AnalysisDeclContext &AC, - const FunctionDecl *D); - bool splitState(const CFGBlock *CurrBlock, - const ConsumedStmtVisitor &Visitor); + void determineExpectedReturnState(AnalysisDeclContext &AC, + const FunctionDecl *D); + bool splitState(const CFGBlock *CurrBlock, + const ConsumedStmtVisitor &Visitor); - public: - ConsumedWarningsHandlerBase &WarningsHandler; +public: + ConsumedWarningsHandlerBase &WarningsHandler; - ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler) - : WarningsHandler(WarningsHandler) {} + ConsumedAnalyzer(ConsumedWarningsHandlerBase &WarningsHandler) + : WarningsHandler(WarningsHandler) {} - ConsumedState getExpectedReturnState() const { return ExpectedReturnState; } + ConsumedState getExpectedReturnState() const { return ExpectedReturnState; } - /// Check a function's CFG for consumed violations. - /// - /// We traverse the blocks in the CFG, keeping track of the state of each - /// value who's type has uniqueness annotations. If methods are invoked in - /// the wrong state a warning is issued. Each block in the CFG is traversed - /// exactly once. - void run(AnalysisDeclContext &AC); - }; + /// Check a function's CFG for consumed violations. + /// + /// We traverse the blocks in the CFG, keeping track of the state of each + /// value who's type has uniqueness annotations. If methods are invoked in + /// the wrong state a warning is issued. Each block in the CFG is traversed + /// exactly once. + void run(AnalysisDeclContext &AC); +}; } // namespace consumed diff --git a/clang/include/clang/Analysis/Analyses/Dominators.h b/clang/include/clang/Analysis/Analyses/Dominators.h index 7dd54c5ce262c..05d62dbaa6315 100644 --- a/clang/include/clang/Analysis/Analyses/Dominators.h +++ b/clang/include/clang/Analysis/Analyses/Dominators.h @@ -18,9 +18,9 @@ #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/iterator.h" -#include "llvm/Support/GenericIteratedDominanceFrontier.h" #include "llvm/Support/GenericDomTree.h" #include "llvm/Support/GenericDomTreeConstruction.h" +#include "llvm/Support/GenericIteratedDominanceFrontier.h" #include "llvm/Support/raw_ostream.h" // FIXME: There is no good reason for the domtree to require a print method @@ -38,8 +38,7 @@ namespace clang { using DomTreeNode = llvm::DomTreeNodeBase; /// Dominator tree builder for Clang's CFG based on llvm::DominatorTreeBase. -template -class CFGDominatorTreeImpl : public ManagedAnalysis { +template class CFGDominatorTreeImpl : public ManagedAnalysis { virtual void anchor(); public: @@ -47,9 +46,7 @@ class CFGDominatorTreeImpl : public ManagedAnalysis { CFGDominatorTreeImpl() = default; - CFGDominatorTreeImpl(CFG *cfg) { - buildDominatorTree(cfg); - } + CFGDominatorTreeImpl(CFG *cfg) { buildDominatorTree(cfg); } ~CFGDominatorTreeImpl() override = default; @@ -58,14 +55,10 @@ class CFGDominatorTreeImpl : public ManagedAnalysis { CFG *getCFG() { return cfg; } /// \returns the root CFGBlock of the dominators tree. - CFGBlock *getRoot() const { - return DT.getRoot(); - } + CFGBlock *getRoot() const { return DT.getRoot(); } /// \returns the root DomTreeNode, which is the wrapper for CFGBlock. - DomTreeNode *getRootNode() { - return DT.getRootNode(); - } + DomTreeNode *getRootNode() { return DT.getRootNode(); } /// Compares two dominator trees. /// \returns false if the other dominator tree matches this dominator tree, @@ -94,8 +87,7 @@ class CFGDominatorTreeImpl : public ManagedAnalysis { void dump() { llvm::errs() << "Immediate " << (IsPostDom ? "post " : "") << "dominance tree (Node#,IDom#):\n"; - for (CFG::const_iterator I = cfg->begin(), - E = cfg->end(); I != E; ++I) { + for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { assert(*I && "LLVM's Dominator tree builder uses nullpointers to signify the " @@ -103,10 +95,8 @@ class CFGDominatorTreeImpl : public ManagedAnalysis { DomTreeNode *IDom = DT.getNode(*I)->getIDom(); if (IDom && IDom->getBlock()) - llvm::errs() << "(" << (*I)->getBlockID() - << "," - << IDom->getBlock()->getBlockID() - << ")\n"; + llvm::errs() << "(" << (*I)->getBlockID() << "," + << IDom->getBlock()->getBlockID() << ")\n"; else { bool IsEntryBlock = *I == &(*I)->getParent()->getEntry(); bool IsExitBlock = *I == &(*I)->getParent()->getExit(); @@ -125,8 +115,8 @@ class CFGDominatorTreeImpl : public ManagedAnalysis { (void)IsDomTreeRoot; (void)IsPostDomTreeRoot; - llvm::errs() << "(" << (*I)->getBlockID() - << "," << (*I)->getBlockID() << ")\n"; + llvm::errs() << "(" << (*I)->getBlockID() << "," << (*I)->getBlockID() + << ")\n"; } } } @@ -170,7 +160,7 @@ class CFGDominatorTreeImpl : public ManagedAnalysis { virtual void releaseMemory() { DT.reset(); } /// Converts the dominator tree to human readable form. - virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const { + virtual void print(raw_ostream &OS, const llvm::Module *M = nullptr) const { DT.print(OS); } @@ -182,8 +172,8 @@ class CFGDominatorTreeImpl : public ManagedAnalysis { using CFGDomTree = CFGDominatorTreeImpl; using CFGPostDomTree = CFGDominatorTreeImpl; -template<> void CFGDominatorTreeImpl::anchor(); -template<> void CFGDominatorTreeImpl::anchor(); +template <> void CFGDominatorTreeImpl::anchor(); +template <> void CFGDominatorTreeImpl::anchor(); } // end of namespace clang @@ -191,8 +181,7 @@ namespace llvm { namespace IDFCalculatorDetail { /// Specialize ChildrenGetterTy to skip nullpointer successors. -template -struct ChildrenGetterTy { +template struct ChildrenGetterTy { using NodeRef = typename GraphTraits::NodeRef; using ChildrenTy = SmallVector; @@ -224,7 +213,7 @@ class ControlDependencyCalculator : public ManagedAnalysis { public: ControlDependencyCalculator(CFG *cfg) - : PostDomTree(cfg), IDFCalc(PostDomTree.getBase()) {} + : PostDomTree(cfg), IDFCalc(PostDomTree.getBase()) {} const CFGPostDomTree &getCFGPostDomTree() const { return PostDomTree; } @@ -261,10 +250,8 @@ class ControlDependencyCalculator : public ManagedAnalysis { "virtual root!"); for (CFGBlock *isControlDependency : getControlDependencies(BB)) - llvm::errs() << "(" << BB->getBlockID() - << "," - << isControlDependency->getBlockID() - << ")\n"; + llvm::errs() << "(" << BB->getBlockID() << "," + << isControlDependency->getBlockID() << ")\n"; } } }; @@ -297,7 +284,8 @@ template <> struct GraphTraits { } }; -template <> struct GraphTraits +template <> +struct GraphTraits : public GraphTraits { static NodeRef getEntryNode(clang::CFGDomTree *DT) { return DT->getRootNode(); diff --git a/clang/include/clang/Analysis/Analyses/LiveVariables.h b/clang/include/clang/Analysis/Analyses/LiveVariables.h index 8a3dd0c35e64c..96aada4f90593 100644 --- a/clang/include/clang/Analysis/Analyses/LiveVariables.h +++ b/clang/include/clang/Analysis/Analyses/LiveVariables.h @@ -29,7 +29,6 @@ class LiveVariables : public ManagedAnalysis { public: class LivenessValues { public: - llvm::ImmutableSet liveExprs; llvm::ImmutableSet liveDecls; llvm::ImmutableSet liveBindings; @@ -37,7 +36,7 @@ class LiveVariables : public ManagedAnalysis { bool equals(const LivenessValues &V) const; LivenessValues() - : liveExprs(nullptr), liveDecls(nullptr), liveBindings(nullptr) {} + : liveExprs(nullptr), liveDecls(nullptr), liveBindings(nullptr) {} LivenessValues(llvm::ImmutableSet liveExprs, llvm::ImmutableSet LiveDecls, @@ -53,14 +52,14 @@ class LiveVariables : public ManagedAnalysis { class Observer { virtual void anchor(); + public: virtual ~Observer() {} /// A callback invoked right before invoking the /// liveness transfer function on the given statement. - virtual void observeStmt(const Stmt *S, - const CFGBlock *currentBlock, - const LivenessValues& V) {} + virtual void observeStmt(const Stmt *S, const CFGBlock *currentBlock, + const LivenessValues &V) {} /// Called when the live variables analysis registers /// that a variable is killed. diff --git a/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h b/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h index c4998bb2285f7..f1e8546df0928 100644 --- a/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h +++ b/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h @@ -40,7 +40,9 @@ class PostOrderCFGView : public ManagedAnalysis { public: // po_iterator requires this iterator, but the only interface needed is the // value_type type. - struct iterator { using value_type = const CFGBlock *; }; + struct iterator { + using value_type = const CFGBlock *; + }; CFGBlockSet() = default; CFGBlockSet(const CFG *G) : VisitedBlockIDs(G->getNumBlockIDs(), false) {} @@ -135,9 +137,7 @@ class PostOrderCFGView : public ManagedAnalysis { bool operator()(const CFGBlock *b1, const CFGBlock *b2) const; }; - BlockOrderCompare getComparator() const { - return BlockOrderCompare(*this); - } + BlockOrderCompare getComparator() const { return BlockOrderCompare(*this); } // Used by AnalyisContext to construct this object. static const void *getTag(); diff --git a/clang/include/clang/Analysis/Analyses/ReachableCode.h b/clang/include/clang/Analysis/Analyses/ReachableCode.h index f1b63f74b6c80..44cb6633aaafa 100644 --- a/clang/include/clang/Analysis/Analyses/ReachableCode.h +++ b/clang/include/clang/Analysis/Analyses/ReachableCode.h @@ -20,14 +20,14 @@ //===----------------------------------------------------------------------===// namespace llvm { - class BitVector; +class BitVector; } namespace clang { - class AnalysisDeclContext; - class CFGBlock; - class Preprocessor; -} +class AnalysisDeclContext; +class CFGBlock; +class Preprocessor; +} // namespace clang //===----------------------------------------------------------------------===// // API. @@ -37,15 +37,11 @@ namespace clang { namespace reachable_code { /// Classifications of unreachable code. -enum UnreachableKind { - UK_Return, - UK_Break, - UK_Loop_Increment, - UK_Other -}; +enum UnreachableKind { UK_Return, UK_Break, UK_Loop_Increment, UK_Other }; class Callback { virtual void anchor(); + public: virtual ~Callback() {} virtual void HandleUnreachable(UnreachableKind UK, SourceLocation L, @@ -61,6 +57,7 @@ unsigned ScanReachableFromBlock(const CFGBlock *Start, void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP, Callback &CB); -}} // end namespace clang::reachable_code +} // namespace reachable_code +} // namespace clang #endif diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafety.h b/clang/include/clang/Analysis/Analyses/ThreadSafety.h index 0866b09bab299..d76f5804bfa31 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafety.h @@ -10,7 +10,8 @@ // A intra-procedural analysis for thread safety (e.g. deadlocks and race // conditions), based off of an annotation system. // -// See http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking +// See +// http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking // for more information. // //===----------------------------------------------------------------------===// @@ -250,8 +251,7 @@ class ThreadSafetyHandler { /// at the end of each block, and issue warnings for thread safety violations. /// Each block in the CFG is traversed exactly once. void runThreadSafetyAnalysis(AnalysisDeclContext &AC, - ThreadSafetyHandler &Handler, - BeforeSet **Bset); + ThreadSafetyHandler &Handler, BeforeSet **Bset); void threadSafetyCleanup(BeforeSet *Cache); diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 13e37ac2b56b6..b00fa4f71922d 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -94,7 +94,7 @@ inline std::string toString(const til::SExpr *E) { return ss.str(); } -} // namespace sx +} // namespace sx // This class defines the interface of a clang CFG Visitor. // CFGWalker will invoke the following methods. @@ -168,8 +168,7 @@ class CFGWalker { } // Traverse the CFG, calling methods on V as appropriate. - template - void walk(Visitor &V) { + template void walk(Visitor &V) { PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph); V.enterCFG(CFGraph, getDecl(), &CFGraph->getEntry()); @@ -181,7 +180,7 @@ class CFGWalker { // Process predecessors, handling back edges last if (V.visitPredecessors()) { - SmallVector BackEdges; + SmallVector BackEdges; // Process successors for (CFGBlock::const_pred_iterator SI = CurrBlock->pred_begin(), SE = CurrBlock->pred_end(); @@ -226,7 +225,7 @@ class CFGWalker { // Process successors, handling back edges first. if (V.visitSuccessors()) { - SmallVector ForwardEdges; + SmallVector ForwardEdges; // Process successors for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(), @@ -312,7 +311,7 @@ class CapabilityExpr { sx::partiallyMatches(sexpr(), other.sexpr()); } - const ValueDecl* valueDecl() const { + const ValueDecl *valueDecl() const { if (negative() || sexpr() == nullptr) return nullptr; if (const auto *P = dyn_cast(sexpr())) @@ -349,7 +348,7 @@ class SExprBuilder { /// by the lock_returned attribute. struct CallingContext { // The previous context; or 0 if none. - CallingContext *Prev; + CallingContext *Prev; // The decl to which the attr is attached. const NamedDecl *AttrDecl; @@ -395,7 +394,7 @@ class SExprBuilder { // Also performs substitution of variables; Ctx provides the context. // Dispatches on the type of S. til::SExpr *translate(const Stmt *S, CallingContext *Ctx); - til::SCFG *buildCFG(CFGWalker &Walker); + til::SCFG *buildCFG(CFGWalker &Walker); til::SExpr *lookupStmt(const Stmt *S); @@ -410,8 +409,7 @@ class SExprBuilder { // We implement the CFGVisitor API friend class CFGWalker; - til::SExpr *translateDeclRefExpr(const DeclRefExpr *DRE, - CallingContext *Ctx) ; + til::SExpr *translateDeclRefExpr(const DeclRefExpr *DRE, CallingContext *Ctx); til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx); til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx); til::SExpr *translateObjCIVarRefExpr(const ObjCIvarRefExpr *IVRE, @@ -424,19 +422,19 @@ class SExprBuilder { CallingContext *Ctx); til::SExpr *translateUnaryOperator(const UnaryOperator *UO, CallingContext *Ctx); - til::SExpr *translateBinOp(til::TIL_BinaryOpcode Op, - const BinaryOperator *BO, + til::SExpr *translateBinOp(til::TIL_BinaryOpcode Op, const BinaryOperator *BO, CallingContext *Ctx, bool Reverse = false); til::SExpr *translateBinAssign(til::TIL_BinaryOpcode Op, - const BinaryOperator *BO, - CallingContext *Ctx, bool Assign = false); + const BinaryOperator *BO, CallingContext *Ctx, + bool Assign = false); til::SExpr *translateBinaryOperator(const BinaryOperator *BO, CallingContext *Ctx); til::SExpr *translateCastExpr(const CastExpr *CE, CallingContext *Ctx); til::SExpr *translateArraySubscriptExpr(const ArraySubscriptExpr *E, CallingContext *Ctx); - til::SExpr *translateAbstractConditionalOperator( - const AbstractConditionalOperator *C, CallingContext *Ctx); + til::SExpr * + translateAbstractConditionalOperator(const AbstractConditionalOperator *C, + CallingContext *Ctx); til::SExpr *translateDeclStmt(const DeclStmt *S, CallingContext *Ctx); diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyLogical.h index 8d938c1b23c07..6712199d7729d 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyLogical.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyLogical.h @@ -20,12 +20,7 @@ namespace lexpr { class LExpr { public: - enum Opcode { - Terminal, - And, - Or, - Not - }; + enum Opcode { Terminal, And, Or, Not }; Opcode kind() const { return Kind; } /// Logical implication. Returns true if the LExpr implies RHS, i.e. if @@ -55,7 +50,8 @@ class BinOp : public LExpr { LExpr *LHS, *RHS; protected: - BinOp(LExpr *LHS, LExpr *RHS, Opcode Code) : LExpr(Code), LHS(LHS), RHS(RHS) {} + BinOp(LExpr *LHS, LExpr *RHS, Opcode Code) + : LExpr(Code), LHS(LHS), RHS(RHS) {} public: const LExpr *left() const { return LHS; } @@ -99,9 +95,8 @@ bool LExpr::implies(const LExpr *RHS) const { return lexpr::implies(this, RHS); } -} -} -} +} // namespace lexpr +} // namespace threadSafety +} // namespace clang #endif - diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h index 65dd66ee093fe..bddbf236f7ad1 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h @@ -82,30 +82,30 @@ enum TIL_Opcode : unsigned char { /// Opcode for unary arithmetic operations. enum TIL_UnaryOpcode : unsigned char { - UOP_Minus, // - - UOP_BitNot, // ~ - UOP_LogicNot // ! + UOP_Minus, // - + UOP_BitNot, // ~ + UOP_LogicNot // ! }; /// Opcode for binary arithmetic operations. enum TIL_BinaryOpcode : unsigned char { - BOP_Add, // + - BOP_Sub, // - - BOP_Mul, // * - BOP_Div, // / - BOP_Rem, // % - BOP_Shl, // << - BOP_Shr, // >> - BOP_BitAnd, // & - BOP_BitXor, // ^ - BOP_BitOr, // | - BOP_Eq, // == - BOP_Neq, // != - BOP_Lt, // < - BOP_Leq, // <= - BOP_Cmp, // <=> - BOP_LogicAnd, // && (no short-circuit) - BOP_LogicOr // || (no short-circuit) + BOP_Add, // + + BOP_Sub, // - + BOP_Mul, // * + BOP_Div, // / + BOP_Rem, // % + BOP_Shl, // << + BOP_Shr, // >> + BOP_BitAnd, // & + BOP_BitXor, // ^ + BOP_BitOr, // | + BOP_Eq, // == + BOP_Neq, // != + BOP_Lt, // < + BOP_Leq, // <= + BOP_Cmp, // <=> + BOP_LogicAnd, // && (no short-circuit) + BOP_LogicOr // || (no short-circuit) }; /// Opcode for cast operations. @@ -128,14 +128,14 @@ enum TIL_CastOpcode : unsigned char { CAST_objToPtr }; -const TIL_Opcode COP_Min = COP_Future; -const TIL_Opcode COP_Max = COP_Branch; -const TIL_UnaryOpcode UOP_Min = UOP_Minus; -const TIL_UnaryOpcode UOP_Max = UOP_LogicNot; -const TIL_BinaryOpcode BOP_Min = BOP_Add; -const TIL_BinaryOpcode BOP_Max = BOP_LogicOr; -const TIL_CastOpcode CAST_Min = CAST_none; -const TIL_CastOpcode CAST_Max = CAST_toInt; +const TIL_Opcode COP_Min = COP_Future; +const TIL_Opcode COP_Max = COP_Branch; +const TIL_UnaryOpcode UOP_Min = UOP_Minus; +const TIL_UnaryOpcode UOP_Max = UOP_LogicNot; +const TIL_BinaryOpcode BOP_Min = BOP_Add; +const TIL_BinaryOpcode BOP_Max = BOP_LogicOr; +const TIL_CastOpcode CAST_Min = CAST_none; +const TIL_CastOpcode CAST_Max = CAST_toInt; /// Return the name of a unary opcode. StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op); @@ -155,7 +155,7 @@ struct ValueType { BT_Bool, BT_Int, BT_Float, - BT_String, // String literals + BT_String, // String literals BT_Pointer, BT_ValueRef }; @@ -175,8 +175,7 @@ struct ValueType { inline static SizeType getSizeType(unsigned nbytes); - template - inline static ValueType getValueType(); + template inline static ValueType getValueType(); BaseType Base; SizeType Size; @@ -188,88 +187,79 @@ struct ValueType { inline ValueType::SizeType ValueType::getSizeType(unsigned nbytes) { switch (nbytes) { - case 1: return ST_8; - case 2: return ST_16; - case 4: return ST_32; - case 8: return ST_64; - case 16: return ST_128; - default: return ST_0; + case 1: + return ST_8; + case 2: + return ST_16; + case 4: + return ST_32; + case 8: + return ST_64; + case 16: + return ST_128; + default: + return ST_0; } } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Void, ST_0, false, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Bool, ST_1, false, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Int, ST_8, true, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Int, ST_8, false, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Int, ST_16, true, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Int, ST_16, false, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Int, ST_32, true, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Int, ST_32, false, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Int, ST_64, true, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Int, ST_64, false, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Float, ST_32, true, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Float, ST_64, true, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_Float, ST_128, true, 0); } -template<> -inline ValueType ValueType::getValueType() { +template <> inline ValueType ValueType::getValueType() { return ValueType(BT_String, getSizeType(sizeof(StringRef)), false, 0); } -template<> -inline ValueType ValueType::getValueType() { - return ValueType(BT_Pointer, getSizeType(sizeof(void*)), false, 0); +template <> inline ValueType ValueType::getValueType() { + return ValueType(BT_Pointer, getSizeType(sizeof(void *)), false, 0); } /// Base class for AST nodes in the typed intermediate language. @@ -293,9 +283,7 @@ class SExpr { // template typename C::CType compare(CType* E, C& Cmp) { // compare all subexpressions, following the comparator interface // } - void *operator new(size_t S, MemRegionRef &R) { - return ::operator new(S, R); - } + void *operator new(size_t S, MemRegionRef &R) { return ::operator new(S, R); } /// SExpr objects must be created in an arena. void *operator new(size_t) = delete; @@ -314,7 +302,10 @@ class SExpr { BasicBlock *block() const { return Block; } /// Set the basic block and instruction ID for this expression. - void setID(BasicBlock *B, unsigned id) { Block = B; SExprID = id; } + void setID(BasicBlock *B, unsigned id) { + Block = B; + SExprID = id; + } protected: SExpr(TIL_Opcode Op) : Opcode(Op) {} @@ -371,12 +362,12 @@ class Variable : public SExpr { } Variable(SExpr *D, const ValueDecl *Cvd = nullptr) - : SExpr(COP_Variable), Name(Cvd ? Cvd->getName() : "_x"), - Definition(D), Cvdecl(Cvd) { + : SExpr(COP_Variable), Name(Cvd ? Cvd->getName() : "_x"), Definition(D), + Cvdecl(Cvd) { Flags = VK_Let; } - Variable(const Variable &Vd, SExpr *D) // rewrite constructor + Variable(const Variable &Vd, SExpr *D) // rewrite constructor : SExpr(Vd), Name(Vd.Name), Definition(D), Cvdecl(Vd.Cvdecl) { Flags = Vd.kind(); } @@ -398,7 +389,7 @@ class Variable : public SExpr { SExpr *definition() { return Definition; } const SExpr *definition() const { return Definition; } - void setName(StringRef S) { Name = S; } + void setName(StringRef S) { Name = S; } void setKind(VariableKind K) { Flags = K; } void setDefinition(SExpr *E) { Definition = E; } void setClangDecl(const ValueDecl *VD) { Cvdecl = VD; } @@ -410,7 +401,7 @@ class Variable : public SExpr { } template - typename C::CType compare(const Variable* E, C& Cmp) const { + typename C::CType compare(const Variable *E, C &Cmp) const { return Cmp.compareVariableRefs(this, E); } @@ -434,11 +425,7 @@ class Variable : public SExpr { /// Used to implement lazy copy and rewriting strategies. class Future : public SExpr { public: - enum FutureStatus { - FS_pending, - FS_evaluating, - FS_done - }; + enum FutureStatus { FS_pending, FS_evaluating, FS_done }; Future() : SExpr(COP_Future) {} virtual ~Future() = delete; @@ -469,15 +456,14 @@ class Future : public SExpr { return Vs.traverse(Result, Ctx); } - template - typename C::CType compare(const Future* E, C& Cmp) const { + template typename C::CType compare(const Future *E, C &Cmp) const { if (!Result || !E->Result) return Cmp.comparePointers(this, E); return Cmp.compare(Result, E->Result); } private: - SExpr* force(); + SExpr *force(); FutureStatus Status = FS_pending; SExpr *Result = nullptr; @@ -501,7 +487,7 @@ class Undefined : public SExpr { } template - typename C::CType compare(const Undefined* E, C& Cmp) const { + typename C::CType compare(const Undefined *E, C &Cmp) const { return Cmp.trueResult(); } @@ -517,12 +503,13 @@ class Wildcard : public SExpr { static bool classof(const SExpr *E) { return E->opcode() == COP_Wildcard; } - template typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) { + template + typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) { return Vs.reduceWildcard(*this); } template - typename C::CType compare(const Wildcard* E, C& Cmp) const { + typename C::CType compare(const Wildcard *E, C &Cmp) const { return Cmp.trueResult(); } }; @@ -533,7 +520,8 @@ template class LiteralT; class Literal : public SExpr { public: Literal(const Expr *C) - : SExpr(COP_Literal), ValType(ValueType::getValueType()), Cexpr(C) {} + : SExpr(COP_Literal), ValType(ValueType::getValueType()), Cexpr(C) { + } Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT) {} Literal(const Literal &) = default; @@ -544,17 +532,16 @@ class Literal : public SExpr { ValueType valueType() const { return ValType; } - template const LiteralT& as() const { - return *static_cast*>(this); + template const LiteralT &as() const { + return *static_cast *>(this); } - template LiteralT& as() { - return *static_cast*>(this); + template LiteralT &as() { + return *static_cast *>(this); } template typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx); - template - typename C::CType compare(const Literal* E, C& Cmp) const { + template typename C::CType compare(const Literal *E, C &Cmp) const { // TODO: defer actual comparison to LiteralT return Cmp.trueResult(); } @@ -565,8 +552,7 @@ class Literal : public SExpr { }; // Derived class for literal values, which stores the actual value. -template -class LiteralT : public Literal { +template class LiteralT : public Literal { public: LiteralT(T Dat) : Literal(ValueType::getValueType()), Val(Dat) {} LiteralT(const LiteralT &L) : Literal(L), Val(L.Val) {} @@ -575,8 +561,8 @@ class LiteralT : public Literal { // motivation. LiteralT &operator=(const LiteralT &) = delete; - T value() const { return Val;} - T& value() { return Val; } + T value() const { return Val; } + T &value() { return Val; } private: T Val; @@ -631,7 +617,7 @@ typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) { case ValueType::BT_String: return Vs.reduceLiteralT(as()); case ValueType::BT_Pointer: - return Vs.reduceLiteralT(as()); + return Vs.reduceLiteralT(as()); case ValueType::BT_ValueRef: break; } @@ -657,7 +643,7 @@ class LiteralPtr : public SExpr { } template - typename C::CType compare(const LiteralPtr* E, C& Cmp) const { + typename C::CType compare(const LiteralPtr *E, C &Cmp) const { if (!Cvdecl || !E->Cvdecl) return Cmp.comparePointers(this, E); return Cmp.comparePointers(Cvdecl, E->Cvdecl); @@ -684,7 +670,7 @@ class Function : public SExpr { static bool classof(const SExpr *E) { return E->opcode() == COP_Function; } - Variable *variableDecl() { return VarDecl; } + Variable *variableDecl() { return VarDecl; } const Variable *variableDecl() const { return VarDecl; } SExpr *body() { return Body; } @@ -702,9 +688,9 @@ class Function : public SExpr { } template - typename C::CType compare(const Function* E, C& Cmp) const { + typename C::CType compare(const Function *E, C &Cmp) const { typename C::CType Ct = - Cmp.compare(VarDecl->definition(), E->VarDecl->definition()); + Cmp.compare(VarDecl->definition(), E->VarDecl->definition()); if (Cmp.notTrue(Ct)) return Ct; Cmp.enterScope(variableDecl(), E->variableDecl()); @@ -715,7 +701,7 @@ class Function : public SExpr { private: Variable *VarDecl; - SExpr* Body; + SExpr *Body; }; /// A self-applicable function. @@ -758,7 +744,7 @@ class SFunction : public SExpr { } template - typename C::CType compare(const SFunction* E, C& Cmp) const { + typename C::CType compare(const SFunction *E, C &Cmp) const { Cmp.enterScope(variableDecl(), E->variableDecl()); typename C::CType Ct = Cmp.compare(body(), E->body()); Cmp.leaveScope(); @@ -767,7 +753,7 @@ class SFunction : public SExpr { private: Variable *VarDecl; - SExpr* Body; + SExpr *Body; }; /// A block of code -- e.g. the body of a function. @@ -788,12 +774,11 @@ class Code : public SExpr { template typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) { auto Nt = Vs.traverse(ReturnType, Vs.typeCtx(Ctx)); - auto Nb = Vs.traverse(Body, Vs.lazyCtx(Ctx)); + auto Nb = Vs.traverse(Body, Vs.lazyCtx(Ctx)); return Vs.reduceCode(*this, Nt, Nb); } - template - typename C::CType compare(const Code* E, C& Cmp) const { + template typename C::CType compare(const Code *E, C &Cmp) const { typename C::CType Ct = Cmp.compare(returnType(), E->returnType()); if (Cmp.notTrue(Ct)) return Ct; @@ -801,8 +786,8 @@ class Code : public SExpr { } private: - SExpr* ReturnType; - SExpr* Body; + SExpr *ReturnType; + SExpr *Body; }; /// A typed, writable location in memory @@ -823,12 +808,11 @@ class Field : public SExpr { template typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) { auto Nr = Vs.traverse(Range, Vs.typeCtx(Ctx)); - auto Nb = Vs.traverse(Body, Vs.lazyCtx(Ctx)); + auto Nb = Vs.traverse(Body, Vs.lazyCtx(Ctx)); return Vs.reduceField(*this, Nr, Nb); } - template - typename C::CType compare(const Field* E, C& Cmp) const { + template typename C::CType compare(const Field *E, C &Cmp) const { typename C::CType Ct = Cmp.compare(range(), E->range()); if (Cmp.notTrue(Ct)) return Ct; @@ -836,8 +820,8 @@ class Field : public SExpr { } private: - SExpr* Range; - SExpr* Body; + SExpr *Range; + SExpr *Body; }; /// Apply an argument to a function. @@ -848,7 +832,7 @@ class Field : public SExpr { class Apply : public SExpr { public: Apply(SExpr *F, SExpr *A) : SExpr(COP_Apply), Fun(F), Arg(A) {} - Apply(const Apply &A, SExpr *F, SExpr *Ar) // rewrite constructor + Apply(const Apply &A, SExpr *F, SExpr *Ar) // rewrite constructor : SExpr(A), Fun(F), Arg(Ar) {} static bool classof(const SExpr *E) { return E->opcode() == COP_Apply; } @@ -866,8 +850,7 @@ class Apply : public SExpr { return Vs.reduceApply(*this, Nf, Na); } - template - typename C::CType compare(const Apply* E, C& Cmp) const { + template typename C::CType compare(const Apply *E, C &Cmp) const { typename C::CType Ct = Cmp.compare(fun(), E->fun()); if (Cmp.notTrue(Ct)) return Ct; @@ -875,8 +858,8 @@ class Apply : public SExpr { } private: - SExpr* Fun; - SExpr* Arg; + SExpr *Fun; + SExpr *Arg; }; /// Apply a self-argument to a self-applicable function. @@ -899,13 +882,12 @@ class SApply : public SExpr { template typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) { auto Nf = Vs.traverse(Sfun, Vs.subExprCtx(Ctx)); - typename V::R_SExpr Na = Arg ? Vs.traverse(Arg, Vs.subExprCtx(Ctx)) - : nullptr; + typename V::R_SExpr Na = + Arg ? Vs.traverse(Arg, Vs.subExprCtx(Ctx)) : nullptr; return Vs.reduceSApply(*this, Nf, Na); } - template - typename C::CType compare(const SApply* E, C& Cmp) const { + template typename C::CType compare(const SApply *E, C &Cmp) const { typename C::CType Ct = Cmp.compare(sfun(), E->sfun()); if (Cmp.notTrue(Ct) || (!arg() && !E->arg())) return Ct; @@ -913,8 +895,8 @@ class SApply : public SExpr { } private: - SExpr* Sfun; - SExpr* Arg; + SExpr *Sfun; + SExpr *Arg; }; /// Project a named slot from a C++ struct or class. @@ -935,8 +917,10 @@ class Project : public SExpr { bool isArrow() const { return (Flags & 0x01) != 0; } void setArrow(bool b) { - if (b) Flags |= 0x01; - else Flags &= 0xFFFE; + if (b) + Flags |= 0x01; + else + Flags &= 0xFFFE; } StringRef slotName() const { @@ -956,8 +940,7 @@ class Project : public SExpr { return Vs.reduceProject(*this, Nr); } - template - typename C::CType compare(const Project* E, C& Cmp) const { + template typename C::CType compare(const Project *E, C &Cmp) const { typename C::CType Ct = Cmp.compare(record(), E->record()); if (Cmp.notTrue(Ct)) return Ct; @@ -965,7 +948,7 @@ class Project : public SExpr { } private: - SExpr* Rec; + SExpr *Rec; mutable std::optional SlotName; const ValueDecl *Cvdecl; }; @@ -990,23 +973,19 @@ class Call : public SExpr { return Vs.reduceCall(*this, Nt); } - template - typename C::CType compare(const Call* E, C& Cmp) const { + template typename C::CType compare(const Call *E, C &Cmp) const { return Cmp.compare(target(), E->target()); } private: - SExpr* Target; + SExpr *Target; const CallExpr *Cexpr; }; /// Allocate memory for a new value on the heap or stack. class Alloc : public SExpr { public: - enum AllocKind { - AK_Stack, - AK_Heap - }; + enum AllocKind { AK_Stack, AK_Heap }; Alloc(SExpr *D, AllocKind K) : SExpr(COP_Alloc), Dtype(D) { Flags = K; } Alloc(const Alloc &A, SExpr *Dt) : SExpr(A), Dtype(Dt) { Flags = A.kind(); } @@ -1024,8 +1003,7 @@ class Alloc : public SExpr { return Vs.reduceAlloc(*this, Nd); } - template - typename C::CType compare(const Alloc* E, C& Cmp) const { + template typename C::CType compare(const Alloc *E, C &Cmp) const { typename C::CType Ct = Cmp.compareIntegers(kind(), E->kind()); if (Cmp.notTrue(Ct)) return Ct; @@ -1033,7 +1011,7 @@ class Alloc : public SExpr { } private: - SExpr* Dtype; + SExpr *Dtype; }; /// Load a value from memory. @@ -1053,13 +1031,12 @@ class Load : public SExpr { return Vs.reduceLoad(*this, Np); } - template - typename C::CType compare(const Load* E, C& Cmp) const { + template typename C::CType compare(const Load *E, C &Cmp) const { return Cmp.compare(pointer(), E->pointer()); } private: - SExpr* Ptr; + SExpr *Ptr; }; /// Store a value to memory. @@ -1071,21 +1048,20 @@ class Store : public SExpr { static bool classof(const SExpr *E) { return E->opcode() == COP_Store; } - SExpr *destination() { return Dest; } // Address to store to + SExpr *destination() { return Dest; } // Address to store to const SExpr *destination() const { return Dest; } - SExpr *source() { return Source; } // Value to store + SExpr *source() { return Source; } // Value to store const SExpr *source() const { return Source; } template typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) { - auto Np = Vs.traverse(Dest, Vs.subExprCtx(Ctx)); + auto Np = Vs.traverse(Dest, Vs.subExprCtx(Ctx)); auto Nv = Vs.traverse(Source, Vs.subExprCtx(Ctx)); return Vs.reduceStore(*this, Np, Nv); } - template - typename C::CType compare(const Store* E, C& Cmp) const { + template typename C::CType compare(const Store *E, C &Cmp) const { typename C::CType Ct = Cmp.compare(destination(), E->destination()); if (Cmp.notTrue(Ct)) return Ct; @@ -1093,8 +1069,8 @@ class Store : public SExpr { } private: - SExpr* Dest; - SExpr* Source; + SExpr *Dest; + SExpr *Source; }; /// If p is a reference to an array, then p[i] is a reference to the i'th @@ -1121,7 +1097,7 @@ class ArrayIndex : public SExpr { } template - typename C::CType compare(const ArrayIndex* E, C& Cmp) const { + typename C::CType compare(const ArrayIndex *E, C &Cmp) const { typename C::CType Ct = Cmp.compare(array(), E->array()); if (Cmp.notTrue(Ct)) return Ct; @@ -1129,8 +1105,8 @@ class ArrayIndex : public SExpr { } private: - SExpr* Array; - SExpr* Index; + SExpr *Array; + SExpr *Index; }; /// Pointer arithmetic, restricted to arrays only. @@ -1158,7 +1134,7 @@ class ArrayAdd : public SExpr { } template - typename C::CType compare(const ArrayAdd* E, C& Cmp) const { + typename C::CType compare(const ArrayAdd *E, C &Cmp) const { typename C::CType Ct = Cmp.compare(array(), E->array()); if (Cmp.notTrue(Ct)) return Ct; @@ -1166,8 +1142,8 @@ class ArrayAdd : public SExpr { } private: - SExpr* Array; - SExpr* Index; + SExpr *Array; + SExpr *Index; }; /// Simple arithmetic unary operations, e.g. negate and not. @@ -1195,17 +1171,15 @@ class UnaryOp : public SExpr { return Vs.reduceUnaryOp(*this, Ne); } - template - typename C::CType compare(const UnaryOp* E, C& Cmp) const { - typename C::CType Ct = - Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode()); + template typename C::CType compare(const UnaryOp *E, C &Cmp) const { + typename C::CType Ct = Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode()); if (Cmp.notTrue(Ct)) return Ct; return Cmp.compare(expr(), E->expr()); } private: - SExpr* Expr0; + SExpr *Expr0; }; /// Simple arithmetic binary operations, e.g. +, -, etc. @@ -1242,9 +1216,9 @@ class BinaryOp : public SExpr { } template - typename C::CType compare(const BinaryOp* E, C& Cmp) const { + typename C::CType compare(const BinaryOp *E, C &Cmp) const { typename C::CType Ct = - Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode()); + Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode()); if (Cmp.notTrue(Ct)) return Ct; Ct = Cmp.compare(expr0(), E->expr0()); @@ -1254,8 +1228,8 @@ class BinaryOp : public SExpr { } private: - SExpr* Expr0; - SExpr* Expr1; + SExpr *Expr0; + SExpr *Expr1; }; /// Cast expressions. @@ -1281,17 +1255,15 @@ class Cast : public SExpr { return Vs.reduceCast(*this, Ne); } - template - typename C::CType compare(const Cast* E, C& Cmp) const { - typename C::CType Ct = - Cmp.compareIntegers(castOpcode(), E->castOpcode()); + template typename C::CType compare(const Cast *E, C &Cmp) const { + typename C::CType Ct = Cmp.compareIntegers(castOpcode(), E->castOpcode()); if (Cmp.notTrue(Ct)) return Ct; return Cmp.compare(expr(), E->expr()); } private: - SExpr* Expr0; + SExpr *Expr0; }; class SCFG; @@ -1313,7 +1285,7 @@ class Phi : public SExpr { }; Phi() : SExpr(COP_Phi) {} - Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {} + Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {} Phi(const Phi &P, ValArray &&Vs) : SExpr(P), Values(std::move(Vs)) {} static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; } @@ -1332,23 +1304,21 @@ class Phi : public SExpr { template typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) { - typename V::template Container - Nvs(Vs, Values.size()); + typename V::template Container Nvs(Vs, Values.size()); for (const auto *Val : Values) - Nvs.push_back( Vs.traverse(Val, Vs.subExprCtx(Ctx)) ); + Nvs.push_back(Vs.traverse(Val, Vs.subExprCtx(Ctx))); return Vs.reducePhi(*this, Nvs); } - template - typename C::CType compare(const Phi *E, C &Cmp) const { + template typename C::CType compare(const Phi *E, C &Cmp) const { // TODO: implement CFG comparisons return Cmp.comparePointers(this, E); } private: ValArray Values; - const ValueDecl* Cvdecl = nullptr; + const ValueDecl *Cvdecl = nullptr; }; /// Base class for basic block terminators: Branch, Goto, and Return. @@ -1366,7 +1336,7 @@ class Terminator : public SExpr { ArrayRef successors(); ArrayRef successors() const { - return const_cast(this)->successors(); + return const_cast(this)->successors(); } }; @@ -1399,8 +1369,7 @@ class Goto : public Terminator { return Vs.reduceGoto(*this, Ntb); } - template - typename C::CType compare(const Goto *E, C &Cmp) const { + template typename C::CType compare(const Goto *E, C &Cmp) const { // TODO: implement CFG comparisons return Cmp.comparePointers(this, E); } @@ -1449,8 +1418,7 @@ class Branch : public Terminator { return Vs.reduceBranch(*this, Nc, Ntb, Nte); } - template - typename C::CType compare(const Branch *E, C &Cmp) const { + template typename C::CType compare(const Branch *E, C &Cmp) const { // TODO: implement CFG comparisons return Cmp.comparePointers(this, E); } @@ -1464,8 +1432,8 @@ class Branch : public Terminator { /// Only the exit block should end with a return statement. class Return : public Terminator { public: - Return(SExpr* Rval) : Terminator(COP_Return), Retval(Rval) {} - Return(const Return &R, SExpr* Rval) : Terminator(R), Retval(Rval) {} + Return(SExpr *Rval) : Terminator(COP_Return), Retval(Rval) {} + Return(const Return &R, SExpr *Rval) : Terminator(R), Retval(Rval) {} static bool classof(const SExpr *E) { return E->opcode() == COP_Return; } @@ -1481,22 +1449,24 @@ class Return : public Terminator { return Vs.reduceReturn(*this, Ne); } - template - typename C::CType compare(const Return *E, C &Cmp) const { + template typename C::CType compare(const Return *E, C &Cmp) const { return Cmp.compare(Retval, E->Retval); } private: - SExpr* Retval; + SExpr *Retval; }; -inline ArrayRef Terminator::successors() { +inline ArrayRef Terminator::successors() { switch (opcode()) { - case COP_Goto: return cast(this)->successors(); - case COP_Branch: return cast(this)->successors(); - case COP_Return: return cast(this)->successors(); - default: - return std::nullopt; + case COP_Goto: + return cast(this)->successors(); + case COP_Branch: + return cast(this)->successors(); + case COP_Return: + return cast(this)->successors(); + default: + return std::nullopt; } } @@ -1525,12 +1495,12 @@ class BasicBlock : public SExpr { TopologyNode() = default; - bool isParentOf(const TopologyNode& OtherNode) { + bool isParentOf(const TopologyNode &OtherNode) { return OtherNode.NodeID > NodeID && OtherNode.NodeID < NodeID + SizeOfSubTree; } - bool isParentOfOrEqual(const TopologyNode& OtherNode) { + bool isParentOfOrEqual(const TopologyNode &OtherNode) { return OtherNode.NodeID >= NodeID && OtherNode.NodeID < NodeID + SizeOfSubTree; } @@ -1552,8 +1522,8 @@ class BasicBlock : public SExpr { size_t numPredecessors() const { return Predecessors.size(); } size_t numSuccessors() const { return successors().size(); } - const SCFG* cfg() const { return CFGPtr; } - SCFG* cfg() { return CFGPtr; } + const SCFG *cfg() const { return CFGPtr; } + SCFG *cfg() { return CFGPtr; } const BasicBlock *parent() const { return DominatorNode.Parent; } BasicBlock *parent() { return DominatorNode.Parent; } @@ -1570,8 +1540,8 @@ class BasicBlock : public SExpr { BlockArray &predecessors() { return Predecessors; } const BlockArray &predecessors() const { return Predecessors; } - ArrayRef successors() { return TermInstr->successors(); } - ArrayRef successors() const { return TermInstr->successors(); } + ArrayRef successors() { return TermInstr->successors(); } + ArrayRef successors() const { return TermInstr->successors(); } const Terminator *terminator() const { return TermInstr; } Terminator *terminator() { return TermInstr; } @@ -1603,7 +1573,7 @@ class BasicBlock : public SExpr { unsigned addPredecessor(BasicBlock *Pred); // Reserve space for Nargs arguments. - void reserveArguments(unsigned Nargs) { Args.reserve(Nargs, Arena); } + void reserveArguments(unsigned Nargs) { Args.reserve(Nargs, Arena); } // Reserve space for Nins instructions. void reserveInstructions(unsigned Nins) { Instrs.reserve(Nins, Arena); } @@ -1619,8 +1589,8 @@ class BasicBlock : public SExpr { template typename V::R_BasicBlock traverse(V &Vs, typename V::R_Ctx Ctx) { - typename V::template Container Nas(Vs, Args.size()); - typename V::template Container Nis(Vs, Instrs.size()); + typename V::template Container Nas(Vs, Args.size()); + typename V::template Container Nis(Vs, Instrs.size()); // Entering the basic block should do any scope initialization. Vs.enterBasicBlock(*this); @@ -1701,7 +1671,7 @@ class SCFG : public SExpr { SCFG(MemRegionRef A, unsigned Nblocks) : SExpr(COP_SCFG), Arena(A), Blocks(A, Nblocks) { Entry = new (A) BasicBlock(A); - Exit = new (A) BasicBlock(A); + Exit = new (A) BasicBlock(A); auto *V = new (A) Phi(); Exit->addArgument(V); Exit->setTerminator(new (A) Return(V)); @@ -1755,7 +1725,7 @@ class SCFG : public SExpr { } void setEntry(BasicBlock *BB) { Entry = BB; } - void setExit(BasicBlock *BB) { Exit = BB; } + void setExit(BasicBlock *BB) { Exit = BB; } void computeNormalForm(); @@ -1765,14 +1735,13 @@ class SCFG : public SExpr { typename V::template Container Bbs(Vs, Blocks.size()); for (const auto *B : Blocks) { - Bbs.push_back( B->traverse(Vs, Vs.subExprCtx(Ctx)) ); + Bbs.push_back(B->traverse(Vs, Vs.subExprCtx(Ctx))); } Vs.exitCFG(*this); return Vs.reduceSCFG(*this, Bbs); } - template - typename C::CType compare(const SCFG *E, C &Cmp) const { + template typename C::CType compare(const SCFG *E, C &Cmp) const { // TODO: implement CFG comparisons return Cmp.comparePointers(this, E); } @@ -1793,7 +1762,7 @@ class SCFG : public SExpr { /// This is a pseduo-term; it will be lowered to a variable or projection. class Identifier : public SExpr { public: - Identifier(StringRef Id): SExpr(COP_Identifier), Name(Id) {} + Identifier(StringRef Id) : SExpr(COP_Identifier), Name(Id) {} Identifier(const Identifier &) = default; static bool classof(const SExpr *E) { return E->opcode() == COP_Identifier; } @@ -1806,7 +1775,7 @@ class Identifier : public SExpr { } template - typename C::CType compare(const Identifier* E, C& Cmp) const { + typename C::CType compare(const Identifier *E, C &Cmp) const { return Cmp.compareStrings(name(), E->name()); } @@ -1825,25 +1794,25 @@ class IfThenElse : public SExpr { static bool classof(const SExpr *E) { return E->opcode() == COP_IfThenElse; } - SExpr *condition() { return Condition; } // Address to store to + SExpr *condition() { return Condition; } // Address to store to const SExpr *condition() const { return Condition; } - SExpr *thenExpr() { return ThenExpr; } // Value to store + SExpr *thenExpr() { return ThenExpr; } // Value to store const SExpr *thenExpr() const { return ThenExpr; } - SExpr *elseExpr() { return ElseExpr; } // Value to store + SExpr *elseExpr() { return ElseExpr; } // Value to store const SExpr *elseExpr() const { return ElseExpr; } template typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) { auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx)); - auto Nt = Vs.traverse(ThenExpr, Vs.subExprCtx(Ctx)); - auto Ne = Vs.traverse(ElseExpr, Vs.subExprCtx(Ctx)); + auto Nt = Vs.traverse(ThenExpr, Vs.subExprCtx(Ctx)); + auto Ne = Vs.traverse(ElseExpr, Vs.subExprCtx(Ctx)); return Vs.reduceIfThenElse(*this, Nc, Nt, Ne); } template - typename C::CType compare(const IfThenElse* E, C& Cmp) const { + typename C::CType compare(const IfThenElse *E, C &Cmp) const { typename C::CType Ct = Cmp.compare(condition(), E->condition()); if (Cmp.notTrue(Ct)) return Ct; @@ -1854,9 +1823,9 @@ class IfThenElse : public SExpr { } private: - SExpr* Condition; - SExpr* ThenExpr; - SExpr* ElseExpr; + SExpr *Condition; + SExpr *ThenExpr; + SExpr *ElseExpr; }; /// A let-expression, e.g. let x=t; u. @@ -1873,7 +1842,7 @@ class Let : public SExpr { static bool classof(const SExpr *E) { return E->opcode() == COP_Let; } - Variable *variableDecl() { return VarDecl; } + Variable *variableDecl() { return VarDecl; } const Variable *variableDecl() const { return VarDecl; } SExpr *body() { return Body; } @@ -1890,10 +1859,9 @@ class Let : public SExpr { return Vs.reduceLet(*this, Nvd, E1); } - template - typename C::CType compare(const Let* E, C& Cmp) const { + template typename C::CType compare(const Let *E, C &Cmp) const { typename C::CType Ct = - Cmp.compare(VarDecl->definition(), E->VarDecl->definition()); + Cmp.compare(VarDecl->definition(), E->VarDecl->definition()); if (Cmp.notTrue(Ct)) return Ct; Cmp.enterScope(variableDecl(), E->variableDecl()); @@ -1904,11 +1872,11 @@ class Let : public SExpr { private: Variable *VarDecl; - SExpr* Body; + SExpr *Body; }; const SExpr *getCanonicalVal(const SExpr *E); -SExpr* simplifyToCanonicalVal(SExpr *E); +SExpr *simplifyToCanonicalVal(SExpr *E); void simplifyIncompleteArg(til::Phi *Ph); } // namespace til diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h index 6fc55130655a2..1b3b4bd10e3b1 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h @@ -54,8 +54,7 @@ namespace til { // They are defined in derived classes. // // Class R defines the basic interface types (R_SExpr). -template -class Traversal { +template class Traversal { public: Self *self() { return static_cast(this); } @@ -65,7 +64,7 @@ class Traversal { // E is a reference, so this can be use for in-place updates. // The type T must be a subclass of SExpr. template - typename R::R_SExpr traverse(T* &E, typename R::R_Ctx Ctx) { + typename R::R_SExpr traverse(T *&E, typename R::R_Ctx Ctx) { return traverseSExpr(E, Ctx); } @@ -78,9 +77,9 @@ class Traversal { // Helper method to call traverseX(e) on the appropriate type. typename R::R_SExpr traverseByCase(SExpr *E, typename R::R_Ctx Ctx) { switch (E->opcode()) { -#define TIL_OPCODE_DEF(X) \ - case COP_##X: \ - return self()->traverse##X(cast(E), Ctx); +#define TIL_OPCODE_DEF(X) \ + case COP_##X: \ + return self()->traverse##X(cast(E), Ctx); #include "ThreadSafetyOps.def" #undef TIL_OPCODE_DEF } @@ -89,9 +88,9 @@ class Traversal { // Traverse e, by static dispatch on the type "X" of e. // Override these methods to do something for a particular kind of term. -#define TIL_OPCODE_DEF(X) \ - typename R::R_SExpr traverse##X(X *e, typename R::R_Ctx Ctx) { \ - return e->traverse(*self(), Ctx); \ +#define TIL_OPCODE_DEF(X) \ + typename R::R_SExpr traverse##X(X *e, typename R::R_Ctx Ctx) { \ + return e->traverse(*self(), Ctx); \ } #include "ThreadSafetyOps.def" #undef TIL_OPCODE_DEF @@ -193,8 +192,7 @@ class VisitReducer : public Traversal, R_SExpr reduceWildcard(Wildcard &Orig) { return true; } R_SExpr reduceLiteral(Literal &Orig) { return true; } - template - R_SExpr reduceLiteralT(LiteralT &Orig) { return true; } + template R_SExpr reduceLiteralT(LiteralT &Orig) { return true; } R_SExpr reduceLiteralPtr(Literal &Orig) { return true; } R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) { @@ -205,17 +203,11 @@ class VisitReducer : public Traversal, return Nvd && E0; } - R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) { - return E0 && E1; - } + R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; } - R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) { - return E0 && E1; - } + R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; } - R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) { - return E0 && E1; - } + R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; } R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; @@ -252,33 +244,23 @@ class VisitReducer : public Traversal, return (As.Success && Is.Success && T); } - R_SExpr reducePhi(Phi &Orig, Container &As) { - return As.Success; - } + R_SExpr reducePhi(Phi &Orig, Container &As) { return As.Success; } - R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) { - return true; - } + R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) { return true; } R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) { return C; } - R_SExpr reduceReturn(Return &O, R_SExpr E) { - return E; - } + R_SExpr reduceReturn(Return &O, R_SExpr E) { return E; } - R_SExpr reduceIdentifier(Identifier &Orig) { - return true; - } + R_SExpr reduceIdentifier(Identifier &Orig) { return true; } R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) { return C && T && E; } - R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) { - return Nvd && B; - } + R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) { return Nvd && B; } Variable *enterScope(Variable &Orig, R_SExpr E0) { return &Orig; } void exitScope(const Variable &Orig) {} @@ -306,17 +288,16 @@ class VisitReducer : public Traversal, }; // Basic class for comparison operations over expressions. -template -class Comparator { +template class Comparator { protected: Self *self() { return reinterpret_cast(this); } public: - bool compareByCase(const SExpr *E1, const SExpr* E2) { + bool compareByCase(const SExpr *E1, const SExpr *E2) { switch (E1->opcode()) { -#define TIL_OPCODE_DEF(X) \ - case COP_##X: \ - return cast(E1)->compare(cast(E2), *self()); +#define TIL_OPCODE_DEF(X) \ + case COP_##X: \ + return cast(E1)->compare(cast(E2), *self()); #include "ThreadSafetyOps.def" #undef TIL_OPCODE_DEF } @@ -335,10 +316,10 @@ class EqualsComparator : public Comparator { bool notTrue(CType ct) { return !ct; } bool compareIntegers(unsigned i, unsigned j) { return i == j; } - bool compareStrings (StringRef s, StringRef r) { return s == r; } - bool comparePointers(const void* P, const void* Q) { return P == Q; } + bool compareStrings(StringRef s, StringRef r) { return s == r; } + bool comparePointers(const void *P, const void *Q) { return P == Q; } - bool compare(const SExpr *E1, const SExpr* E2) { + bool compare(const SExpr *E1, const SExpr *E2) { if (E1->opcode() != E2->opcode()) return false; return compareByCase(E1, E2); @@ -352,7 +333,7 @@ class EqualsComparator : public Comparator { return V1 == V2; } - static bool compareExprs(const SExpr *E1, const SExpr* E2) { + static bool compareExprs(const SExpr *E1, const SExpr *E2) { EqualsComparator Eq; return Eq.compare(E1, E2); } @@ -369,7 +350,7 @@ class MatchComparator : public Comparator { bool notTrue(CType ct) { return !ct; } bool compareIntegers(unsigned i, unsigned j) { return i == j; } - bool compareStrings (StringRef s, StringRef r) { return s == r; } + bool compareStrings(StringRef s, StringRef r) { return s == r; } bool comparePointers(const void *P, const void *Q) { return P == Q; } bool compare(const SExpr *E1, const SExpr *E2) { @@ -383,14 +364,14 @@ class MatchComparator : public Comparator { } // TODO -- handle alpha-renaming of variables - void enterScope(const Variable* V1, const Variable* V2) {} + void enterScope(const Variable *V1, const Variable *V2) {} void leaveScope() {} - bool compareVariableRefs(const Variable* V1, const Variable* V2) { + bool compareVariableRefs(const Variable *V1, const Variable *V2) { return V1 == V2; } - static bool compareExprs(const SExpr *E1, const SExpr* E2) { + static bool compareExprs(const SExpr *E1, const SExpr *E2) { MatchComparator Matcher; return Matcher.compare(E1, E2); } @@ -401,8 +382,7 @@ class MatchComparator : public Comparator { // } // Pretty printer for TIL expressions -template -class PrettyPrinter { +template class PrettyPrinter { private: // Print out additional information. bool Verbose; @@ -425,9 +405,7 @@ class PrettyPrinter { protected: Self *self() { return reinterpret_cast(this); } - void newline(StreamType &SS) { - SS << "\n"; - } + void newline(StreamType &SS) { SS << "\n"; } // TODO: further distinguish between binary operations. static const unsigned Prec_Atom = 0; @@ -441,48 +419,79 @@ class PrettyPrinter { // Return the precedence of a given node, for use in pretty printing. unsigned precedence(const SExpr *E) { switch (E->opcode()) { - case COP_Future: return Prec_Atom; - case COP_Undefined: return Prec_Atom; - case COP_Wildcard: return Prec_Atom; - - case COP_Literal: return Prec_Atom; - case COP_LiteralPtr: return Prec_Atom; - case COP_Variable: return Prec_Atom; - case COP_Function: return Prec_Decl; - case COP_SFunction: return Prec_Decl; - case COP_Code: return Prec_Decl; - case COP_Field: return Prec_Decl; - - case COP_Apply: return Prec_Postfix; - case COP_SApply: return Prec_Postfix; - case COP_Project: return Prec_Postfix; - - case COP_Call: return Prec_Postfix; - case COP_Alloc: return Prec_Other; - case COP_Load: return Prec_Postfix; - case COP_Store: return Prec_Other; - case COP_ArrayIndex: return Prec_Postfix; - case COP_ArrayAdd: return Prec_Postfix; - - case COP_UnaryOp: return Prec_Unary; - case COP_BinaryOp: return Prec_Binary; - case COP_Cast: return Prec_Atom; - - case COP_SCFG: return Prec_Decl; - case COP_BasicBlock: return Prec_MAX; - case COP_Phi: return Prec_Atom; - case COP_Goto: return Prec_Atom; - case COP_Branch: return Prec_Atom; - case COP_Return: return Prec_Other; - - case COP_Identifier: return Prec_Atom; - case COP_IfThenElse: return Prec_Other; - case COP_Let: return Prec_Decl; + case COP_Future: + return Prec_Atom; + case COP_Undefined: + return Prec_Atom; + case COP_Wildcard: + return Prec_Atom; + + case COP_Literal: + return Prec_Atom; + case COP_LiteralPtr: + return Prec_Atom; + case COP_Variable: + return Prec_Atom; + case COP_Function: + return Prec_Decl; + case COP_SFunction: + return Prec_Decl; + case COP_Code: + return Prec_Decl; + case COP_Field: + return Prec_Decl; + + case COP_Apply: + return Prec_Postfix; + case COP_SApply: + return Prec_Postfix; + case COP_Project: + return Prec_Postfix; + + case COP_Call: + return Prec_Postfix; + case COP_Alloc: + return Prec_Other; + case COP_Load: + return Prec_Postfix; + case COP_Store: + return Prec_Other; + case COP_ArrayIndex: + return Prec_Postfix; + case COP_ArrayAdd: + return Prec_Postfix; + + case COP_UnaryOp: + return Prec_Unary; + case COP_BinaryOp: + return Prec_Binary; + case COP_Cast: + return Prec_Atom; + + case COP_SCFG: + return Prec_Decl; + case COP_BasicBlock: + return Prec_MAX; + case COP_Phi: + return Prec_Atom; + case COP_Goto: + return Prec_Atom; + case COP_Branch: + return Prec_Atom; + case COP_Return: + return Prec_Other; + + case COP_Identifier: + return Prec_Atom; + case COP_IfThenElse: + return Prec_Other; + case COP_Let: + return Prec_Decl; } return Prec_MAX; } - void printBlockLabel(StreamType & SS, const BasicBlock *BB, int index) { + void printBlockLabel(StreamType &SS, const BasicBlock *BB, int index) { if (!BB) { SS << "BB_null"; return; @@ -495,7 +504,7 @@ class PrettyPrinter { } } - void printSExpr(const SExpr *E, StreamType &SS, unsigned P, bool Sub=true) { + void printSExpr(const SExpr *E, StreamType &SS, unsigned P, bool Sub = true) { if (!E) { self()->printNull(SS); return; @@ -513,18 +522,16 @@ class PrettyPrinter { } switch (E->opcode()) { -#define TIL_OPCODE_DEF(X) \ - case COP_##X: \ - self()->print##X(cast(E), SS); \ - return; +#define TIL_OPCODE_DEF(X) \ + case COP_##X: \ + self()->print##X(cast(E), SS); \ + return; #include "ThreadSafetyOps.def" #undef TIL_OPCODE_DEF } } - void printNull(StreamType &SS) { - SS << "#null"; - } + void printNull(StreamType &SS) { SS << "#null"; } void printFuture(const Future *E, StreamType &SS) { self()->printSExpr(E->maybeGetResult(), SS, Prec_Atom); @@ -534,12 +541,9 @@ class PrettyPrinter { SS << "#undefined"; } - void printWildcard(const Wildcard *E, StreamType &SS) { - SS << "*"; - } + void printWildcard(const Wildcard *E, StreamType &SS) { SS << "*"; } - template - void printLiteralT(const LiteralT *E, StreamType &SS) { + template void printLiteralT(const LiteralT *E, StreamType &SS) { SS << E->value(); } @@ -551,8 +555,7 @@ class PrettyPrinter { if (E->clangExpr()) { SS << getSourceLiteralString(E->clangExpr()); return; - } - else { + } else { ValueType VT = E->valueType(); switch (VT.Base) { case ValueType::BT_Void: @@ -629,7 +632,8 @@ class PrettyPrinter { SS << ""; } - void printVariable(const Variable *V, StreamType &SS, bool IsVarDecl=false) { + void printVariable(const Variable *V, StreamType &SS, + bool IsVarDecl = false) { if (CStyle && V->kind() == Variable::VK_SFun) SS << "this"; else @@ -638,15 +642,15 @@ class PrettyPrinter { void printFunction(const Function *E, StreamType &SS, unsigned sugared = 0) { switch (sugared) { - default: - SS << "\\("; // Lambda - break; - case 1: - SS << "("; // Slot declarations - break; - case 2: - SS << ", "; // Curried functions - break; + default: + SS << "\\("; // Lambda + break; + case 1: + SS << "("; // Slot declarations + break; + case 2: + SS << ", "; // Curried functions + break; } self()->printVariable(E->variableDecl(), SS, true); SS << ": "; @@ -670,14 +674,14 @@ class PrettyPrinter { void printCode(const Code *E, StreamType &SS) { SS << ": "; - self()->printSExpr(E->returnType(), SS, Prec_Decl-1); + self()->printSExpr(E->returnType(), SS, Prec_Decl - 1); SS << " -> "; self()->printSExpr(E->body(), SS, Prec_Decl); } void printField(const Field *E, StreamType &SS) { SS << ": "; - self()->printSExpr(E->range(), SS, Prec_Decl-1); + self()->printSExpr(E->range(), SS, Prec_Decl - 1); SS << " = "; self()->printSExpr(E->body(), SS, Prec_Decl); } @@ -736,8 +740,7 @@ class PrettyPrinter { if (T->opcode() == COP_Apply) { self()->printApply(cast(T), SS, true); SS << ")"; - } - else { + } else { self()->printSExpr(T, SS, Prec_Postfix); SS << "()"; } @@ -745,7 +748,7 @@ class PrettyPrinter { void printAlloc(const Alloc *E, StreamType &SS) { SS << "new "; - self()->printSExpr(E->dataType(), SS, Prec_Other-1); + self()->printSExpr(E->dataType(), SS, Prec_Other - 1); } void printLoad(const Load *E, StreamType &SS) { @@ -755,9 +758,9 @@ class PrettyPrinter { } void printStore(const Store *E, StreamType &SS) { - self()->printSExpr(E->destination(), SS, Prec_Other-1); + self()->printSExpr(E->destination(), SS, Prec_Other - 1); SS << " := "; - self()->printSExpr(E->source(), SS, Prec_Other-1); + self()->printSExpr(E->source(), SS, Prec_Other - 1); } void printArrayIndex(const ArrayIndex *E, StreamType &SS) { @@ -779,9 +782,9 @@ class PrettyPrinter { } void printBinaryOp(const BinaryOp *E, StreamType &SS) { - self()->printSExpr(E->expr0(), SS, Prec_Binary-1); + self()->printSExpr(E->expr0(), SS, Prec_Binary - 1); SS << " " << getBinaryOpcodeString(E->binaryOpcode()) << " "; - self()->printSExpr(E->expr1(), SS, Prec_Binary-1); + self()->printSExpr(E->expr1(), SS, Prec_Binary - 1); } void printCast(const Cast *E, StreamType &SS) { @@ -830,8 +833,7 @@ class PrettyPrinter { SS << "let " << V->name() << V->id() << " = "; E = V->definition(); Sub = true; - } - else if (E->opcode() != COP_Store) { + } else if (E->opcode() != COP_Store) { SS << "let _x" << E->id() << " = "; } self()->printSExpr(E, SS, Prec_MAX, Sub); @@ -894,9 +896,7 @@ class PrettyPrinter { self()->printSExpr(E->returnValue(), SS, Prec_Other); } - void printIdentifier(const Identifier *E, StreamType &SS) { - SS << E->name(); - } + void printIdentifier(const Identifier *E, StreamType &SS) { SS << E->name(); } void printIfThenElse(const IfThenElse *E, StreamType &SS) { if (CStyle) { @@ -919,9 +919,9 @@ class PrettyPrinter { SS << "let "; printVariable(E->variableDecl(), SS, true); SS << " = "; - printSExpr(E->variableDecl()->definition(), SS, Prec_Decl-1); + printSExpr(E->variableDecl()->definition(), SS, Prec_Decl - 1); SS << "; "; - printSExpr(E->body(), SS, Prec_Decl-1); + printSExpr(E->body(), SS, Prec_Decl - 1); } }; diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h index ac7b24cdb4a6c..c858961609f2d 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h @@ -186,7 +186,7 @@ template class SimpleArray { Size -= n; } - void setValues(unsigned Sz, const T& C) { + void setValues(unsigned Sz, const T &C) { assert(Sz <= Capacity); Size = Sz; for (unsigned i = 0; i < Sz; ++i) { @@ -223,7 +223,7 @@ template class SimpleArray { size_t Capacity = 0; }; -} // namespace til +} // namespace til // A copy on write vector. // The vector can be in one of three states: @@ -231,8 +231,7 @@ template class SimpleArray { // * read-only -- read operations are permitted. // * writable -- read and write operations are permitted. // The init(), destroy(), and makeWritable() methods will change state. -template -class CopyOnWriteVector { +template class CopyOnWriteVector { class VectorData { public: unsigned NumRefs = 1; @@ -264,7 +263,7 @@ class CopyOnWriteVector { ~CopyOnWriteVector() { destroy(); } // Returns true if this holds a valid vector. - bool valid() const { return Data; } + bool valid() const { return Data; } // Returns true if this vector is writable. bool writable() const { return Data && Data->NumRefs == 1; } @@ -294,7 +293,7 @@ class CopyOnWriteVector { return; } if (Data->NumRefs == 1) - return; // already writeable. + return; // already writeable. --Data->NumRefs; Data = new VectorData(*Data); } @@ -309,7 +308,7 @@ class CopyOnWriteVector { const_iterator begin() const { return elements().cbegin(); } const_iterator end() const { return elements().cend(); } - const T& operator[](unsigned i) const { return elements()[i]; } + const T &operator[](unsigned i) const { return elements()[i]; } unsigned size() const { return Data ? elements().size() : 0; } @@ -330,7 +329,7 @@ class CopyOnWriteVector { // Gets a mutable reference to the element at index(i). // The vector must be writable. - T& elem(unsigned i) { + T &elem(unsigned i) { assert(writable() && "Vector is not writable!"); return Data->Vect[i]; } @@ -351,7 +350,7 @@ class CopyOnWriteVector { VectorData *Data = nullptr; }; -inline std::ostream& operator<<(std::ostream& ss, const StringRef str) { +inline std::ostream &operator<<(std::ostream &ss, const StringRef str) { return ss.write(str.data(), str.size()); } diff --git a/clang/include/clang/Analysis/Analyses/UninitializedValues.h b/clang/include/clang/Analysis/Analyses/UninitializedValues.h index a2b37deddcec2..af6baf8f46184 100644 --- a/clang/include/clang/Analysis/Analyses/UninitializedValues.h +++ b/clang/include/clang/Analysis/Analyses/UninitializedValues.h @@ -55,9 +55,7 @@ class UninitUse { UninitUse(const Expr *User, bool AlwaysUninit) : User(User), AlwaysUninit(AlwaysUninit) {} - void addUninitBranch(Branch B) { - UninitBranches.push_back(B); - } + void addUninitBranch(Branch B) { UninitBranches.push_back(B); } void setUninitAfterCall() { UninitAfterCall = true; } void setUninitAfterDecl() { UninitAfterDecl = true; } @@ -87,10 +85,11 @@ class UninitUse { /// Get the kind of uninitialized use. Kind getKind() const { - return AlwaysUninit ? Always : - UninitAfterCall ? AfterCall : - UninitAfterDecl ? AfterDecl : - !branch_empty() ? Sometimes : Maybe; + return AlwaysUninit ? Always + : UninitAfterCall ? AfterCall + : UninitAfterDecl ? AfterDecl + : !branch_empty() ? Sometimes + : Maybe; } using branch_iterator = SmallVectorImpl::const_iterator; diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h index 5d16dcc824c50..d195e162b7110 100644 --- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h +++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h @@ -35,11 +35,11 @@ class VariableGroupsManager { /// `HasParm` is an optional argument that will be set to true if the set of /// variables, where `Var` is in, contains parameters. virtual VarGrpRef getGroupOfVar(const VarDecl *Var, - bool *HasParm = nullptr) const =0; + bool *HasParm = nullptr) const = 0; /// Returns the non-empty group of variables that include parameters of the /// analyzing function, if such a group exists. An empty group, otherwise. - virtual VarGrpRef getGroupOfParms() const =0; + virtual VarGrpRef getGroupOfParms() const = 0; }; // FixitStrategy is a map from variables to the way we plan to emit fixes for diff --git a/clang/include/clang/Analysis/AnyCall.h b/clang/include/clang/Analysis/AnyCall.h index 48abce062d133..1ff9bab54dfdc 100644 --- a/clang/include/clang/Analysis/AnyCall.h +++ b/clang/include/clang/Analysis/AnyCall.h @@ -100,12 +100,11 @@ class AnyCall { AnyCall(const FunctionDecl *D) : E(nullptr), D(D) { if (isa(D)) { K = Constructor; - } else if (isa (D)) { + } else if (isa(D)) { K = Destructor; } else { K = Function; } - } /// If @c E is a generic call (to ObjC method /function/block/etc), @@ -194,17 +193,11 @@ class AnyCall { return nullptr; } - const Decl *getDecl() const { - return D; - } + const Decl *getDecl() const { return D; } - const Expr *getExpr() const { - return E; - } + const Expr *getExpr() const { return E; } - Kind getKind() const { - return K; - } + Kind getKind() const { return K; } void dump() const { if (E) @@ -214,6 +207,6 @@ class AnyCall { } }; -} +} // namespace clang #endif // LLVM_CLANG_ANALYSIS_ANYCALL_H diff --git a/clang/include/clang/Analysis/CFG.h b/clang/include/clang/Analysis/CFG.h index a7ff38c786a8f..27784aff98ae7 100644 --- a/clang/include/clang/Analysis/CFG.h +++ b/clang/include/clang/Analysis/CFG.h @@ -85,8 +85,8 @@ class CFGElement { llvm::PointerIntPair Data2; CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr) - : Data1(const_cast(Ptr1), ((unsigned) kind) & 0x3), - Data2(const_cast(Ptr2), (((unsigned) kind) >> 2) & 0x3) { + : Data1(const_cast(Ptr1), ((unsigned)kind) & 0x3), + Data2(const_cast(Ptr2), (((unsigned)kind) >> 2) & 0x3) { assert(getKind() == kind); } @@ -95,11 +95,10 @@ class CFGElement { public: /// Convert to the specified CFGElement type, asserting that this /// CFGElement is of the desired type. - template - T castAs() const { + template T castAs() const { assert(T::isKind(*this)); T t; - CFGElement& e = t; + CFGElement &e = t; e = *this; return t; } @@ -110,7 +109,7 @@ class CFGElement { if (!T::isKind(*this)) return std::nullopt; T t; - CFGElement& e = t; + CFGElement &e = t; e = *this; return t; } @@ -119,14 +118,12 @@ class CFGElement { unsigned x = Data2.getInt(); x <<= 2; x |= Data1.getInt(); - return (Kind) x; + return (Kind)x; } void dumpToStream(llvm::raw_ostream &OS) const; - void dump() const { - dumpToStream(llvm::errs()); - } + void dump() const { dumpToStream(llvm::errs()); } }; class CFGStmt : public CFGElement { @@ -171,9 +168,7 @@ class CFGConstructor : public CFGStmt { CFGConstructor() = default; - static bool isKind(const CFGElement &E) { - return E.getKind() == Constructor; - } + static bool isKind(const CFGElement &E) { return E.getKind() == Constructor; } }; /// Represents a function call that returns a C++ object by value. This, like @@ -229,8 +224,8 @@ class CFGInitializer : public CFGElement { explicit CFGInitializer(const CXXCtorInitializer *initializer) : CFGElement(Initializer, initializer) {} - CXXCtorInitializer* getInitializer() const { - return static_cast(Data1.getPointer()); + CXXCtorInitializer *getInitializer() const { + return static_cast(Data1.getPointer()); } private: @@ -238,16 +233,13 @@ class CFGInitializer : public CFGElement { CFGInitializer() = default; - static bool isKind(const CFGElement &E) { - return E.getKind() == Initializer; - } + static bool isKind(const CFGElement &E) { return E.getKind() == Initializer; } }; /// Represents C++ allocator call. class CFGNewAllocator : public CFGElement { public: - explicit CFGNewAllocator(const CXXNewExpr *S) - : CFGElement(NewAllocator, S) {} + explicit CFGNewAllocator(const CXXNewExpr *S) : CFGElement(NewAllocator, S) {} // Get the new expression. const CXXNewExpr *getAllocatorExpr() const { @@ -322,7 +314,7 @@ class CFGScopeBegin : public CFGElement { // Get statement that triggered a new scope. const Stmt *getTriggerStmt() const { - return static_cast(Data2.getPointer()); + return static_cast(Data2.getPointer()); } // Get VD that triggered a new scope. @@ -368,7 +360,7 @@ class CFGImplicitDtor : public CFGElement { CFGImplicitDtor() = default; CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr) - : CFGElement(kind, data1, data2) { + : CFGElement(kind, data1, data2) { assert(kind >= DTOR_BEGIN && kind <= DTOR_END); } @@ -414,18 +406,18 @@ class CFGCleanupFunction final : public CFGElement { /// Represents C++ object destructor implicitly generated for automatic object /// or temporary bound to const reference at the point of leaving its local /// scope. -class CFGAutomaticObjDtor: public CFGImplicitDtor { +class CFGAutomaticObjDtor : public CFGImplicitDtor { public: CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt) : CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {} const VarDecl *getVarDecl() const { - return static_cast(Data1.getPointer()); + return static_cast(Data1.getPointer()); } // Get statement end of which triggered the destructor call. const Stmt *getTriggerStmt() const { - return static_cast(Data2.getPointer()); + return static_cast(Data2.getPointer()); } private: @@ -445,7 +437,7 @@ class CFGDeleteDtor : public CFGImplicitDtor { : CFGImplicitDtor(DeleteDtor, RD, DE) {} const CXXRecordDecl *getCXXRecordDecl() const { - return static_cast(Data1.getPointer()); + return static_cast(Data1.getPointer()); } // Get Delete expression which triggered the destructor call. @@ -467,11 +459,10 @@ class CFGDeleteDtor : public CFGImplicitDtor { /// destructor. class CFGBaseDtor : public CFGImplicitDtor { public: - CFGBaseDtor(const CXXBaseSpecifier *base) - : CFGImplicitDtor(BaseDtor, base) {} + CFGBaseDtor(const CXXBaseSpecifier *base) : CFGImplicitDtor(BaseDtor, base) {} const CXXBaseSpecifier *getBaseSpecifier() const { - return static_cast(Data1.getPointer()); + return static_cast(Data1.getPointer()); } private: @@ -479,9 +470,7 @@ class CFGBaseDtor : public CFGImplicitDtor { CFGBaseDtor() = default; - static bool isKind(const CFGElement &E) { - return E.getKind() == BaseDtor; - } + static bool isKind(const CFGElement &E) { return E.getKind() == BaseDtor; } }; /// Represents C++ object destructor implicitly generated for member object in @@ -492,7 +481,7 @@ class CFGMemberDtor : public CFGImplicitDtor { : CFGImplicitDtor(MemberDtor, field, nullptr) {} const FieldDecl *getFieldDecl() const { - return static_cast(Data1.getPointer()); + return static_cast(Data1.getPointer()); } private: @@ -500,9 +489,7 @@ class CFGMemberDtor : public CFGImplicitDtor { CFGMemberDtor() = default; - static bool isKind(const CFGElement &E) { - return E.getKind() == MemberDtor; - } + static bool isKind(const CFGElement &E) { return E.getKind() == MemberDtor; } }; /// Represents C++ object destructor implicitly generated at the end of full @@ -564,15 +551,11 @@ class CFGTerminator { const Stmt *getStmt() const { return Data.getPointer(); } Kind getKind() const { return static_cast(Data.getInt()); } - bool isStmtBranch() const { - return getKind() == StmtBranch; - } + bool isStmtBranch() const { return getKind() == StmtBranch; } bool isTemporaryDtorsBranch() const { return getKind() == TemporaryDtorsBranch; } - bool isVirtualBaseBranch() const { - return getKind() == VirtualBaseBranch; - } + bool isVirtualBaseBranch() const { return getKind() == VirtualBaseBranch; } }; /// Represents a single basic block in a source-level CFG. @@ -619,7 +602,7 @@ class CFGBlock { void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); } reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E, - BumpVectorContext &C) { + BumpVectorContext &C) { return Impl.insert(I, Cnt, E, C); } @@ -635,7 +618,7 @@ class CFGBlock { const_reverse_iterator rbegin() const { return Impl.begin(); } const_reverse_iterator rend() const { return Impl.end(); } - CFGElement operator[](size_t i) const { + CFGElement operator[](size_t i) const { assert(i < Impl.size()); return Impl[Impl.size() - 1 - i]; } @@ -692,9 +675,7 @@ class CFGBlock { (*this)->dumpToStream(OS); } - void dump() const { - dumpToStream(llvm::errs()); - } + void dump() const { dumpToStream(llvm::errs()); } }; template class ElementRefIterator { @@ -817,11 +798,7 @@ class CFGBlock { /// where a block was substituted because the original (now alternate) block /// is unreachable. class AdjacentBlock { - enum Kind { - AB_Normal, - AB_Unreachable, - AB_Alternate - }; + enum Kind { AB_Normal, AB_Unreachable, AB_Alternate }; CFGBlock *ReachableBlock; llvm::PointerIntPair UnreachableBlock; @@ -835,9 +812,7 @@ class CFGBlock { AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock); /// Get the reachable block, if one exists. - CFGBlock *getReachableBlock() const { - return ReachableBlock; - } + CFGBlock *getReachableBlock() const { return ReachableBlock; } /// Get the potentially unreachable block. CFGBlock *getPossiblyUnreachableBlock() const { @@ -846,20 +821,14 @@ class CFGBlock { /// Provide an implicit conversion to CFGBlock* so that /// AdjacentBlock can be substituted for CFGBlock*. - operator CFGBlock*() const { - return getReachableBlock(); - } + operator CFGBlock *() const { return getReachableBlock(); } - CFGBlock& operator *() const { - return *getReachableBlock(); - } + CFGBlock &operator*() const { return *getReachableBlock(); } - CFGBlock* operator ->() const { - return getReachableBlock(); - } + CFGBlock *operator->() const { return getReachableBlock(); } bool isReachable() const { - Kind K = (Kind) UnreachableBlock.getInt(); + Kind K = (Kind)UnreachableBlock.getInt(); return K == AB_Normal || K == AB_Alternate; } }; @@ -898,18 +867,18 @@ class CFGBlock { size_t getIndexInCFG() const; - CFGElement front() const { return Elements.front(); } - CFGElement back() const { return Elements.back(); } + CFGElement front() const { return Elements.front(); } + CFGElement back() const { return Elements.back(); } - iterator begin() { return Elements.begin(); } - iterator end() { return Elements.end(); } - const_iterator begin() const { return Elements.begin(); } - const_iterator end() const { return Elements.end(); } + iterator begin() { return Elements.begin(); } + iterator end() { return Elements.end(); } + const_iterator begin() const { return Elements.begin(); } + const_iterator end() const { return Elements.end(); } - reverse_iterator rbegin() { return Elements.rbegin(); } - reverse_iterator rend() { return Elements.rend(); } - const_reverse_iterator rbegin() const { return Elements.rbegin(); } - const_reverse_iterator rend() const { return Elements.rend(); } + reverse_iterator rbegin() { return Elements.rbegin(); } + reverse_iterator rend() { return Elements.rend(); } + const_reverse_iterator rbegin() const { return Elements.rbegin(); } + const_reverse_iterator rend() const { return Elements.rend(); } using CFGElementRef = ElementRefImpl; using ConstCFGElementRef = ElementRefImpl; @@ -943,10 +912,10 @@ class CFGBlock { return {rref_begin(), rref_end()}; } - unsigned size() const { return Elements.size(); } - bool empty() const { return Elements.empty(); } + unsigned size() const { return Elements.size(); } + bool empty() const { return Elements.empty(); } - CFGElement operator[](size_t i) const { return Elements[i]; } + CFGElement operator[](size_t i) const { return Elements[i]; } // CFG iterators using pred_iterator = AdjacentBlocks::iterator; @@ -963,48 +932,43 @@ class CFGBlock { using succ_range = llvm::iterator_range; using succ_const_range = llvm::iterator_range; - pred_iterator pred_begin() { return Preds.begin(); } - pred_iterator pred_end() { return Preds.end(); } - const_pred_iterator pred_begin() const { return Preds.begin(); } - const_pred_iterator pred_end() const { return Preds.end(); } + pred_iterator pred_begin() { return Preds.begin(); } + pred_iterator pred_end() { return Preds.end(); } + const_pred_iterator pred_begin() const { return Preds.begin(); } + const_pred_iterator pred_end() const { return Preds.end(); } - pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); } - pred_reverse_iterator pred_rend() { return Preds.rend(); } - const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); } - const_pred_reverse_iterator pred_rend() const { return Preds.rend(); } + pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); } + pred_reverse_iterator pred_rend() { return Preds.rend(); } + const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); } + const_pred_reverse_iterator pred_rend() const { return Preds.rend(); } - pred_range preds() { - return pred_range(pred_begin(), pred_end()); - } + pred_range preds() { return pred_range(pred_begin(), pred_end()); } pred_const_range preds() const { return pred_const_range(pred_begin(), pred_end()); } - succ_iterator succ_begin() { return Succs.begin(); } - succ_iterator succ_end() { return Succs.end(); } - const_succ_iterator succ_begin() const { return Succs.begin(); } - const_succ_iterator succ_end() const { return Succs.end(); } + succ_iterator succ_begin() { return Succs.begin(); } + succ_iterator succ_end() { return Succs.end(); } + const_succ_iterator succ_begin() const { return Succs.begin(); } + const_succ_iterator succ_end() const { return Succs.end(); } - succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); } - succ_reverse_iterator succ_rend() { return Succs.rend(); } - const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); } - const_succ_reverse_iterator succ_rend() const { return Succs.rend(); } + succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); } + succ_reverse_iterator succ_rend() { return Succs.rend(); } + const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); } + const_succ_reverse_iterator succ_rend() const { return Succs.rend(); } - succ_range succs() { - return succ_range(succ_begin(), succ_end()); - } + succ_range succs() { return succ_range(succ_begin(), succ_end()); } succ_const_range succs() const { return succ_const_range(succ_begin(), succ_end()); } - unsigned succ_size() const { return Succs.size(); } - bool succ_empty() const { return Succs.empty(); } - - unsigned pred_size() const { return Preds.size(); } - bool pred_empty() const { return Preds.empty(); } + unsigned succ_size() const { return Succs.size(); } + bool succ_empty() const { return Succs.empty(); } + unsigned pred_size() const { return Preds.size(); } + bool pred_empty() const { return Preds.empty(); } class FilterOptions { public: @@ -1018,10 +982,9 @@ class CFGBlock { }; static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, - const CFGBlock *Dst); + const CFGBlock *Dst); - template - class FilteredCFGBlockIterator { + template class FilteredCFGBlockIterator { private: IMPL I, E; const FilterOptions F; @@ -1039,7 +1002,9 @@ class CFGBlock { bool hasMore() const { return I != E; } FilteredCFGBlockIterator &operator++() { - do { ++I; } while (hasMore() && Filter(*I)); + do { + ++I; + } while (hasMore() && Filter(*I)); return *this; } @@ -1092,7 +1057,7 @@ class CFGBlock { Stmt *getTerminatorCondition(bool StripParens = true); const Stmt *getTerminatorCondition(bool StripParens = true) const { - return const_cast(this)->getTerminatorCondition(StripParens); + return const_cast(this)->getTerminatorCondition(StripParens); } const Stmt *getLoopTarget() const { return LoopTarget; } @@ -1108,8 +1073,9 @@ class CFGBlock { void dump() const; - void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const; - void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO, + void dump(const CFG *cfg, const LangOptions &LO, + bool ShowColors = false) const; + void print(raw_ostream &OS, const CFG *cfg, const LangOptions &LO, bool ShowColors) const; void printTerminator(raw_ostream &OS, const LangOptions &LO) const; @@ -1132,19 +1098,17 @@ class CFGBlock { Elements.push_back(CFGConstructor(CE, CC), C); } - void appendCXXRecordTypedCall(Expr *E, - const ConstructionContext *CC, + void appendCXXRecordTypedCall(Expr *E, const ConstructionContext *CC, BumpVectorContext &C) { Elements.push_back(CFGCXXRecordTypedCall(E, CC), C); } void appendInitializer(CXXCtorInitializer *initializer, - BumpVectorContext &C) { + BumpVectorContext &C) { Elements.push_back(CFGInitializer(initializer), C); } - void appendNewAllocator(CXXNewExpr *NE, - BumpVectorContext &C) { + void appendNewAllocator(CXXNewExpr *NE, BumpVectorContext &C) { Elements.push_back(CFGNewAllocator(NE), C); } @@ -1185,7 +1149,8 @@ class CFGBlock { Elements.push_back(CFGLoopExit(LoopStmt), C); } - void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) { + void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, + BumpVectorContext &C) { Elements.push_back(CFGDeleteDtor(RD, DE), C); } }; @@ -1288,13 +1253,13 @@ class CFG { using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - CFGBlock & front() { return *Blocks.front(); } - CFGBlock & back() { return *Blocks.back(); } + CFGBlock &front() { return *Blocks.front(); } + CFGBlock &back() { return *Blocks.back(); } - iterator begin() { return Blocks.begin(); } - iterator end() { return Blocks.end(); } - const_iterator begin() const { return Blocks.begin(); } - const_iterator end() const { return Blocks.end(); } + iterator begin() { return Blocks.begin(); } + iterator end() { return Blocks.end(); } + const_iterator begin() const { return Blocks.begin(); } + const_iterator end() const { return Blocks.end(); } iterator nodes_begin() { return iterator(Blocks.begin()); } iterator nodes_end() { return iterator(Blocks.end()); } @@ -1307,10 +1272,10 @@ class CFG { const_iterator nodes_begin() const { return const_iterator(Blocks.begin()); } const_iterator nodes_end() const { return const_iterator(Blocks.end()); } - reverse_iterator rbegin() { return Blocks.rbegin(); } - reverse_iterator rend() { return Blocks.rend(); } - const_reverse_iterator rbegin() const { return Blocks.rbegin(); } - const_reverse_iterator rend() const { return Blocks.rend(); } + reverse_iterator rbegin() { return Blocks.rbegin(); } + reverse_iterator rend() { return Blocks.rend(); } + const_reverse_iterator rbegin() const { return Blocks.rbegin(); } + const_reverse_iterator rend() const { return Blocks.rend(); } llvm::iterator_range reverse_nodes() { return {rbegin(), rend()}; @@ -1319,13 +1284,13 @@ class CFG { return {rbegin(), rend()}; } - CFGBlock & getEntry() { return *Entry; } - const CFGBlock & getEntry() const { return *Entry; } - CFGBlock & getExit() { return *Exit; } - const CFGBlock & getExit() const { return *Exit; } + CFGBlock &getEntry() { return *Entry; } + const CFGBlock &getEntry() const { return *Entry; } + CFGBlock &getExit() { return *Exit; } + const CFGBlock &getExit() const { return *Exit; } - CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; } - const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; } + CFGBlock *getIndirectGotoBlock() { return IndirectGotoBlock; } + const CFGBlock *getIndirectGotoBlock() const { return IndirectGotoBlock; } using try_block_iterator = std::vector::const_iterator; using try_block_range = llvm::iterator_range; @@ -1334,9 +1299,7 @@ class CFG { return TryDispatchBlocks.begin(); } - try_block_iterator try_blocks_end() const { - return TryDispatchBlocks.end(); - } + try_block_iterator try_blocks_end() const { return TryDispatchBlocks.end(); } try_block_range try_blocks() const { return try_block_range(try_blocks_begin(), try_blocks_end()); @@ -1350,8 +1313,7 @@ class CFG { /// /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains /// multiple decls. - void addSyntheticDeclStmt(const DeclStmt *Synthetic, - const DeclStmt *Source) { + void addSyntheticDeclStmt(const DeclStmt *Synthetic, const DeclStmt *Source) { assert(Synthetic->isSingleDecl() && "Can handle single declarations only"); assert(Synthetic != Source && "Don't include original DeclStmts in map"); assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map"); @@ -1426,22 +1388,18 @@ class CFG { CFG() : Blocks(BlkBVC, 10) {} - llvm::BumpPtrAllocator& getAllocator() { - return BlkBVC.getAllocator(); - } + llvm::BumpPtrAllocator &getAllocator() { return BlkBVC.getAllocator(); } - BumpVectorContext &getBumpVectorContext() { - return BlkBVC; - } + BumpVectorContext &getBumpVectorContext() { return BlkBVC; } private: CFGBlock *Entry = nullptr; CFGBlock *Exit = nullptr; // Special block to contain collective dispatch for indirect gotos - CFGBlock* IndirectGotoBlock = nullptr; + CFGBlock *IndirectGotoBlock = nullptr; - unsigned NumBlockIDs = 0; + unsigned NumBlockIDs = 0; BumpVectorContext BlkBVC; @@ -1468,7 +1426,7 @@ namespace llvm { /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from /// CFGTerminator to a specific Stmt class. -template <> struct simplify_type< ::clang::CFGTerminator> { +template <> struct simplify_type<::clang::CFGTerminator> { using SimpleType = ::clang::Stmt *; static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) { @@ -1478,7 +1436,7 @@ template <> struct simplify_type< ::clang::CFGTerminator> { // Traits for: CFGBlock -template <> struct GraphTraits< ::clang::CFGBlock *> { +template <> struct GraphTraits<::clang::CFGBlock *> { using NodeRef = ::clang::CFGBlock *; using ChildIteratorType = ::clang::CFGBlock::succ_iterator; @@ -1487,7 +1445,7 @@ template <> struct GraphTraits< ::clang::CFGBlock *> { static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } }; -template <> struct GraphTraits< const ::clang::CFGBlock *> { +template <> struct GraphTraits { using NodeRef = const ::clang::CFGBlock *; using ChildIteratorType = ::clang::CFGBlock::const_succ_iterator; @@ -1496,7 +1454,7 @@ template <> struct GraphTraits< const ::clang::CFGBlock *> { static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } }; -template <> struct GraphTraits> { +template <> struct GraphTraits> { using NodeRef = ::clang::CFGBlock *; using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator; @@ -1522,55 +1480,60 @@ template <> struct GraphTraits> { // Traits for: CFG -template <> struct GraphTraits< ::clang::CFG* > - : public GraphTraits< ::clang::CFGBlock *> { +template <> +struct GraphTraits<::clang::CFG *> : public GraphTraits<::clang::CFGBlock *> { using nodes_iterator = ::clang::CFG::iterator; static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); } - static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();} - static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); } - static unsigned size(::clang::CFG* F) { return F->size(); } + static nodes_iterator nodes_begin(::clang::CFG *F) { + return F->nodes_begin(); + } + static nodes_iterator nodes_end(::clang::CFG *F) { return F->nodes_end(); } + static unsigned size(::clang::CFG *F) { return F->size(); } }; -template <> struct GraphTraits - : public GraphTraits { +template <> +struct GraphTraits + : public GraphTraits { using nodes_iterator = ::clang::CFG::const_iterator; static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); } - static nodes_iterator nodes_begin( const ::clang::CFG* F) { + static nodes_iterator nodes_begin(const ::clang::CFG *F) { return F->nodes_begin(); } - static nodes_iterator nodes_end( const ::clang::CFG* F) { + static nodes_iterator nodes_end(const ::clang::CFG *F) { return F->nodes_end(); } - static unsigned size(const ::clang::CFG* F) { - return F->size(); - } + static unsigned size(const ::clang::CFG *F) { return F->size(); } }; -template <> struct GraphTraits> - : public GraphTraits> { +template <> +struct GraphTraits> + : public GraphTraits> { using nodes_iterator = ::clang::CFG::iterator; static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); } - static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();} - static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); } + static nodes_iterator nodes_begin(::clang::CFG *F) { + return F->nodes_begin(); + } + static nodes_iterator nodes_end(::clang::CFG *F) { return F->nodes_end(); } }; -template <> struct GraphTraits> - : public GraphTraits> { +template <> +struct GraphTraits> + : public GraphTraits> { using nodes_iterator = ::clang::CFG::const_iterator; static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); } - static nodes_iterator nodes_begin(const ::clang::CFG* F) { + static nodes_iterator nodes_begin(const ::clang::CFG *F) { return F->nodes_begin(); } - static nodes_iterator nodes_end(const ::clang::CFG* F) { + static nodes_iterator nodes_end(const ::clang::CFG *F) { return F->nodes_end(); } }; diff --git a/clang/include/clang/Analysis/CFGStmtMap.h b/clang/include/clang/Analysis/CFGStmtMap.h index 93cd9cfc5bdff..14ab2d47e24ba 100644 --- a/clang/include/clang/Analysis/CFGStmtMap.h +++ b/clang/include/clang/Analysis/CFGStmtMap.h @@ -34,18 +34,18 @@ class CFGStmtMap { /// Returns a new CFGMap for the given CFG. It is the caller's /// responsibility to 'delete' this object when done using it. - static CFGStmtMap *Build(CFG* C, ParentMap *PM); + static CFGStmtMap *Build(CFG *C, ParentMap *PM); /// Returns the CFGBlock the specified Stmt* appears in. For Stmt* that /// are terminators, the CFGBlock is the block they appear as a terminator, /// and not the block they appear as a block-level expression (e.g, '&&'). /// CaseStmts and LabelStmts map to the CFGBlock they label. - CFGBlock *getBlock(Stmt * S); + CFGBlock *getBlock(Stmt *S); - const CFGBlock *getBlock(const Stmt * S) const { - return const_cast(this)->getBlock(const_cast(S)); + const CFGBlock *getBlock(const Stmt *S) const { + return const_cast(this)->getBlock(const_cast(S)); } }; -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/Analysis/CallGraph.h b/clang/include/clang/Analysis/CallGraph.h index 78f8d11555017..65d6eb27bb308 100644 --- a/clang/include/clang/Analysis/CallGraph.h +++ b/clang/include/clang/Analysis/CallGraph.h @@ -59,9 +59,7 @@ class CallGraph : public RecursiveASTVisitor { /// declaration. /// /// Recursively walks the declaration to find all the dependent Decls as well. - void addToCallGraph(Decl *D) { - TraverseDecl(D); - } + void addToCallGraph(Decl *D) { TraverseDecl(D); } /// Determine if a declaration should be included in the graph. static bool includeInGraph(const Decl *D); @@ -84,9 +82,9 @@ class CallGraph : public RecursiveASTVisitor { /// Iterators through all the elements in the graph. Note, this gives /// non-deterministic order. iterator begin() { return FunctionMap.begin(); } - iterator end() { return FunctionMap.end(); } + iterator end() { return FunctionMap.end(); } const_iterator begin() const { return FunctionMap.begin(); } - const_iterator end() const { return FunctionMap.end(); } + const_iterator end() const { return FunctionMap.end(); } /// Get the number of nodes in the graph. unsigned size() const { return FunctionMap.size(); } @@ -240,30 +238,31 @@ template <> struct DenseMapInfo { }; // Graph traits for iteration, viewing. -template <> struct GraphTraits { +template <> struct GraphTraits { using NodeType = clang::CallGraphNode; using NodeRef = clang::CallGraphNode *; using ChildIteratorType = NodeType::iterator; static NodeType *getEntryNode(clang::CallGraphNode *CGN) { return CGN; } - static ChildIteratorType child_begin(NodeType *N) { return N->begin(); } + static ChildIteratorType child_begin(NodeType *N) { return N->begin(); } static ChildIteratorType child_end(NodeType *N) { return N->end(); } }; -template <> struct GraphTraits { +template <> struct GraphTraits { using NodeType = const clang::CallGraphNode; using NodeRef = const clang::CallGraphNode *; using ChildIteratorType = NodeType::const_iterator; static NodeType *getEntryNode(const clang::CallGraphNode *CGN) { return CGN; } - static ChildIteratorType child_begin(NodeType *N) { return N->begin();} + static ChildIteratorType child_begin(NodeType *N) { return N->begin(); } static ChildIteratorType child_end(NodeType *N) { return N->end(); } }; -template <> struct GraphTraits - : public GraphTraits { +template <> +struct GraphTraits + : public GraphTraits { static NodeType *getEntryNode(clang::CallGraph *CGN) { - return CGN->getRoot(); // Start at the external node! + return CGN->getRoot(); // Start at the external node! } static clang::CallGraphNode * @@ -279,15 +278,16 @@ template <> struct GraphTraits return nodes_iterator(CG->begin(), &CGGetValue); } - static nodes_iterator nodes_end (clang::CallGraph *CG) { + static nodes_iterator nodes_end(clang::CallGraph *CG) { return nodes_iterator(CG->end(), &CGGetValue); } static unsigned size(clang::CallGraph *CG) { return CG->size(); } }; -template <> struct GraphTraits : - public GraphTraits { +template <> +struct GraphTraits + : public GraphTraits { static NodeType *getEntryNode(const clang::CallGraph *CGN) { return CGN->getRoot(); } diff --git a/clang/include/clang/Analysis/CloneDetection.h b/clang/include/clang/Analysis/CloneDetection.h index 3385579584b5a..a6f44ea3e728f 100644 --- a/clang/include/clang/Analysis/CloneDetection.h +++ b/clang/include/clang/Analysis/CloneDetection.h @@ -325,8 +325,8 @@ struct FilenamePatternConstraint { FilenamePatternConstraint(StringRef IgnoredFilesPattern) : IgnoredFilesPattern(IgnoredFilesPattern) { - IgnoredFilesRegex = std::make_shared("^(" + - IgnoredFilesPattern.str() + "$)"); + IgnoredFilesRegex = + std::make_shared("^(" + IgnoredFilesPattern.str() + "$)"); } bool isAutoGenerated(const CloneDetector::CloneGroup &Group); diff --git a/clang/include/clang/Analysis/CodeInjector.h b/clang/include/clang/Analysis/CodeInjector.h index a59dc0a941590..16b04993c510d 100644 --- a/clang/include/clang/Analysis/CodeInjector.h +++ b/clang/include/clang/Analysis/CodeInjector.h @@ -40,6 +40,6 @@ class CodeInjector { virtual Stmt *getBody(const FunctionDecl *D) = 0; virtual Stmt *getBody(const ObjCMethodDecl *D) = 0; }; -} +} // namespace clang #endif diff --git a/clang/include/clang/Analysis/ConstructionContext.h b/clang/include/clang/Analysis/ConstructionContext.h index e19a205000959..f0789f1006d19 100644 --- a/clang/include/clang/Analysis/ConstructionContext.h +++ b/clang/include/clang/Analysis/ConstructionContext.h @@ -16,9 +16,9 @@ #ifndef LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H #define LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H -#include "clang/Analysis/Support/BumpVector.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/Analysis/Support/BumpVector.h" namespace clang { @@ -48,17 +48,26 @@ class ConstructionContextItem { LLVM_DUMP_METHOD static StringRef getKindAsString(ItemKind K) { switch (K) { - case VariableKind: return "construct into local variable"; - case NewAllocatorKind: return "construct into new-allocator"; - case ReturnKind: return "construct into return address"; - case MaterializationKind: return "materialize temporary"; - case TemporaryDestructorKind: return "destroy temporary"; - case ElidedDestructorKind: return "elide destructor"; - case ElidableConstructorKind: return "elide constructor"; - case ArgumentKind: return "construct into argument"; - case LambdaCaptureKind: - return "construct into lambda captured variable"; - case InitializerKind: return "construct into member variable"; + case VariableKind: + return "construct into local variable"; + case NewAllocatorKind: + return "construct into new-allocator"; + case ReturnKind: + return "construct into return address"; + case MaterializationKind: + return "materialize temporary"; + case TemporaryDestructorKind: + return "destroy temporary"; + case ElidedDestructorKind: + return "elide destructor"; + case ElidableConstructorKind: + return "elide constructor"; + case ArgumentKind: + return "construct into argument"; + case LambdaCaptureKind: + return "construct into lambda captured variable"; + case InitializerKind: + return "construct into member variable"; }; llvm_unreachable("Unknown ItemKind"); } @@ -69,8 +78,7 @@ class ConstructionContextItem { const unsigned Index = 0; bool hasStatement() const { - return Kind >= STATEMENT_KIND_BEGIN && - Kind <= STATEMENT_KIND_END; + return Kind >= STATEMENT_KIND_BEGIN && Kind <= STATEMENT_KIND_END; } bool hasIndex() const { @@ -79,22 +87,19 @@ class ConstructionContextItem { } bool hasInitializer() const { - return Kind >= INITIALIZER_KIND_BEGIN && - Kind <= INITIALIZER_KIND_END; + return Kind >= INITIALIZER_KIND_BEGIN && Kind <= INITIALIZER_KIND_END; } public: // ConstructionContextItem should be simple enough so that it was easy to // re-construct it from the AST node it captures. For that reason we provide // simple implicit conversions from all sorts of supported AST nodes. - ConstructionContextItem(const DeclStmt *DS) - : Data(DS), Kind(VariableKind) {} + ConstructionContextItem(const DeclStmt *DS) : Data(DS), Kind(VariableKind) {} ConstructionContextItem(const CXXNewExpr *NE) : Data(NE), Kind(NewAllocatorKind) {} - ConstructionContextItem(const ReturnStmt *RS) - : Data(RS), Kind(ReturnKind) {} + ConstructionContextItem(const ReturnStmt *RS) : Data(RS), Kind(ReturnKind) {} ConstructionContextItem(const MaterializeTemporaryExpr *MTE) : Data(MTE), Kind(MaterializationKind) {} @@ -235,7 +240,6 @@ class ConstructionContextLayer { bool isStrictlyMoreSpecificThan(const ConstructionContextLayer *Other) const; }; - /// ConstructionContext's subclasses describe different ways of constructing /// an object in C++. The context re-captures the essential parent AST nodes /// of the CXXConstructExpr it is assigned to and presents these nodes @@ -292,9 +296,9 @@ class ConstructionContext { // object also needs to be materialized and delegates to // createMaterializedTemporaryFromLayers() if necessary. static const ConstructionContext * - createBoundTemporaryFromLayers( - BumpVectorContext &C, const CXXBindTemporaryExpr *BTE, - const ConstructionContextLayer *ParentLayer); + createBoundTemporaryFromLayers(BumpVectorContext &C, + const CXXBindTemporaryExpr *BTE, + const ConstructionContextLayer *ParentLayer); public: /// Consume the construction context layer, together with its parent layers, @@ -333,8 +337,7 @@ class VariableConstructionContext : public ConstructionContext { } static bool classof(const ConstructionContext *CC) { - return CC->getKind() >= VARIABLE_BEGIN && - CC->getKind() <= VARIABLE_END; + return CC->getKind() >= VARIABLE_BEGIN && CC->getKind() <= VARIABLE_END; } }; @@ -501,9 +504,7 @@ class TemporaryObjectConstructionContext : public ConstructionContext { public: /// CXXBindTemporaryExpr here is non-null as long as the temporary has /// a non-trivial destructor. - const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { - return BTE; - } + const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; } /// MaterializeTemporaryExpr is non-null as long as the temporary is actually /// used after construction, eg. by binding to a reference (lifetime @@ -621,11 +622,12 @@ class SimpleReturnedValueConstructionContext /// Represents a temporary object that is being immediately returned from a /// function by value, eg. return t; or return T(123); in C++17. /// In C++17 there is not going to be an elidable copy constructor at the -/// return site. However, the usual temporary-related bureaucracy (CXXBindTemporaryExpr, -/// MaterializeTemporaryExpr) is normally located in the caller function's AST. -/// Note that if the object has trivial destructor, then this code is -/// indistinguishable from a simple returned value constructor on the AST level; -/// in this case we provide a simple returned value construction context. +/// return site. However, the usual temporary-related bureaucracy +/// (CXXBindTemporaryExpr, MaterializeTemporaryExpr) is normally located in the +/// caller function's AST. Note that if the object has trivial destructor, then +/// this code is indistinguishable from a simple returned value constructor on +/// the AST level; in this case we provide a simple returned value construction +/// context. class CXX17ElidedCopyReturnedValueConstructionContext : public ReturnedValueConstructionContext { const CXXBindTemporaryExpr *BTE; @@ -664,8 +666,7 @@ class ArgumentConstructionContext : public ConstructionContext { explicit ArgumentConstructionContext(const Expr *CE, unsigned Index, const CXXBindTemporaryExpr *BTE) - : ConstructionContext(ArgumentKind), CE(CE), - Index(Index), BTE(BTE) { + : ConstructionContext(ArgumentKind), CE(CE), Index(Index), BTE(BTE) { assert(isa(CE) || isa(CE) || isa(CE)); // BTE is optional. diff --git a/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h index 8531d17767ba5..05556a33795d9 100644 --- a/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h +++ b/clang/include/clang/Analysis/DomainSpecific/CocoaConventions.h @@ -23,19 +23,19 @@ class QualType; namespace ento { namespace cocoa { - bool isRefType(QualType RetTy, StringRef Prefix, - StringRef Name = StringRef()); +bool isRefType(QualType RetTy, StringRef Prefix, StringRef Name = StringRef()); - bool isCocoaObjectRef(QualType T); +bool isCocoaObjectRef(QualType T); -} +} // namespace cocoa namespace coreFoundation { - bool isCFObjectRef(QualType T); +bool isCFObjectRef(QualType T); - bool followsCreateRule(const FunctionDecl *FD); -} +bool followsCreateRule(const FunctionDecl *FD); +} // namespace coreFoundation -}} // end: "clang:ento" +} // namespace ento +} // namespace clang #endif diff --git a/clang/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h b/clang/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h index 80d7cb8e03a18..62afae9b8194f 100644 --- a/clang/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h +++ b/clang/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h @@ -40,6 +40,6 @@ class ObjCNoReturn { /// return. bool isImplicitNoReturn(const ObjCMessageExpr *ME); }; -} +} // namespace clang #endif diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index b95095d2184c0..f29efb9721507 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -138,8 +138,8 @@ class DataflowAnalysis : public TypeErasedDataflowAnalysis { // The first-choice implementation: use `widen` when it is available. template - static auto widenInternal(Rank0, T &Current, const T &Prev) - -> decltype(Current.widen(Prev)) { + static auto widenInternal(Rank0, T &Current, + const T &Prev) -> decltype(Current.widen(Prev)) { return Current.widen(Prev); } @@ -247,13 +247,13 @@ runDataflowAnalysis( // FIXME: Make all classes derived from `DataflowAnalysis` take an `Environment` // parameter in their constructor so that we can get rid of this abomination. template -auto createAnalysis(ASTContext &ASTCtx, Environment &Env) - -> decltype(AnalysisT(ASTCtx, Env)) { +auto createAnalysis(ASTContext &ASTCtx, + Environment &Env) -> decltype(AnalysisT(ASTCtx, Env)) { return AnalysisT(ASTCtx, Env); } template -auto createAnalysis(ASTContext &ASTCtx, Environment &Env) - -> decltype(AnalysisT(ASTCtx)) { +auto createAnalysis(ASTContext &ASTCtx, + Environment &Env) -> decltype(AnalysisT(ASTCtx)) { return AnalysisT(ASTCtx); } diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index b3dc940705f87..896141f9b3603 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -157,12 +157,12 @@ class Environment { // The default implementation reduces to just comparison, since comparison // is required by the API, even if no widening is performed. switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) { - case ComparisonResult::Same: - return &Prev; - case ComparisonResult::Different: - return &Current; - case ComparisonResult::Unknown: - return nullptr; + case ComparisonResult::Same: + return &Prev; + case ComparisonResult::Different: + return &Current; + case ComparisonResult::Unknown: + return nullptr; } llvm_unreachable("all cases in switch covered"); } @@ -542,22 +542,17 @@ class Environment { } /// Returns an atomic boolean value. - BoolValue &makeAtomicBoolValue() const { - return arena().makeAtomValue(); - } + BoolValue &makeAtomicBoolValue() const { return arena().makeAtomValue(); } /// Returns a unique instance of boolean Top. - BoolValue &makeTopBoolValue() const { - return arena().makeTopValue(); - } + BoolValue &makeTopBoolValue() const { return arena().makeTopValue(); } /// Returns a boolean value that represents the conjunction of `LHS` and /// `RHS`. Subsequent calls with the same arguments, regardless of their /// order, will return the same result. If the given boolean values represent /// the same value, the result will be the value itself. BoolValue &makeAnd(BoolValue &LHS, BoolValue &RHS) const { - return arena().makeBoolValue( - arena().makeAnd(LHS.formula(), RHS.formula())); + return arena().makeBoolValue(arena().makeAnd(LHS.formula(), RHS.formula())); } /// Returns a boolean value that represents the disjunction of `LHS` and @@ -565,8 +560,7 @@ class Environment { /// order, will return the same result. If the given boolean values represent /// the same value, the result will be the value itself. BoolValue &makeOr(BoolValue &LHS, BoolValue &RHS) const { - return arena().makeBoolValue( - arena().makeOr(LHS.formula(), RHS.formula())); + return arena().makeBoolValue(arena().makeOr(LHS.formula(), RHS.formula())); } /// Returns a boolean value that represents the negation of `Val`. Subsequent diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h b/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h index 2248bcdf3a512..661f9957890f2 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h @@ -28,8 +28,8 @@ namespace clang { //===----------------------------------------------------------------------===// namespace dataflow { - struct forward_analysis_tag {}; - struct backward_analysis_tag {}; +struct forward_analysis_tag {}; +struct backward_analysis_tag {}; } // end namespace dataflow //===----------------------------------------------------------------------===// @@ -37,7 +37,7 @@ namespace dataflow { //===----------------------------------------------------------------------===// template + typename _AnalysisDirTag = dataflow::forward_analysis_tag> class DataflowValues { //===--------------------------------------------------------------------===// @@ -45,12 +45,12 @@ class DataflowValues { //===--------------------------------------------------------------------===// public: - typedef typename ValueTypes::ValTy ValTy; - typedef typename ValueTypes::AnalysisDataTy AnalysisDataTy; - typedef _AnalysisDirTag AnalysisDirTag; - typedef llvm::DenseMap EdgeDataMapTy; - typedef llvm::DenseMap BlockDataMapTy; - typedef llvm::DenseMap StmtDataMapTy; + typedef typename ValueTypes::ValTy ValTy; + typedef typename ValueTypes::AnalysisDataTy AnalysisDataTy; + typedef _AnalysisDirTag AnalysisDirTag; + typedef llvm::DenseMap EdgeDataMapTy; + typedef llvm::DenseMap BlockDataMapTy; + typedef llvm::DenseMap StmtDataMapTy; //===--------------------------------------------------------------------===// // Predicates. @@ -66,7 +66,7 @@ class DataflowValues { bool isBackwardAnalysis() { return !isForwardAnalysis(); } private: - bool isForwardAnalysis(dataflow::forward_analysis_tag) { return true; } + bool isForwardAnalysis(dataflow::forward_analysis_tag) { return true; } bool isForwardAnalysis(dataflow::backward_analysis_tag) { return false; } //===--------------------------------------------------------------------===// @@ -79,33 +79,32 @@ class DataflowValues { /// InitializeValues - Invoked by the solver to initialize state needed for /// dataflow analysis. This method is usually specialized by subclasses. - void InitializeValues(const CFG& cfg) {} - + void InitializeValues(const CFG &cfg) {} /// getEdgeData - Retrieves the dataflow values associated with a /// CFG edge. - ValTy& getEdgeData(const BlockEdge &E) { + ValTy &getEdgeData(const BlockEdge &E) { typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E); - assert (I != EdgeDataMap.end() && "No data associated with Edge."); + assert(I != EdgeDataMap.end() && "No data associated with Edge."); return I->second; } - const ValTy& getEdgeData(const BlockEdge &E) const { - return reinterpret_cast(this)->getEdgeData(E); + const ValTy &getEdgeData(const BlockEdge &E) const { + return reinterpret_cast(this)->getEdgeData(E); } /// getBlockData - Retrieves the dataflow values associated with a /// specified CFGBlock. If the dataflow analysis is a forward analysis, /// this data is associated with the END of the block. If the analysis /// is a backwards analysis, it is associated with the ENTRY of the block. - ValTy& getBlockData(const CFGBlock *B) { + ValTy &getBlockData(const CFGBlock *B) { typename BlockDataMapTy::iterator I = BlockDataMap.find(B); - assert (I != BlockDataMap.end() && "No data associated with block."); + assert(I != BlockDataMap.end() && "No data associated with block."); return I->second; } - const ValTy& getBlockData(const CFGBlock *B) const { - return const_cast(this)->getBlockData(B); + const ValTy &getBlockData(const CFGBlock *B) const { + return const_cast(this)->getBlockData(B); } /// getStmtData - Retrieves the dataflow values associated with a @@ -114,58 +113,59 @@ class DataflowValues { /// If the analysis is a backwards analysis, it is associated with /// the point after a Stmt. This data is only computed for block-level /// expressions, and only when requested when the analysis is executed. - ValTy& getStmtData(const Stmt *S) { - assert (StmtDataMap && "Dataflow values were not computed for statements."); + ValTy &getStmtData(const Stmt *S) { + assert(StmtDataMap && "Dataflow values were not computed for statements."); typename StmtDataMapTy::iterator I = StmtDataMap->find(S); - assert (I != StmtDataMap->end() && "No data associated with statement."); + assert(I != StmtDataMap->end() && "No data associated with statement."); return I->second; } - const ValTy& getStmtData(const Stmt *S) const { - return const_cast(this)->getStmtData(S); + const ValTy &getStmtData(const Stmt *S) const { + return const_cast(this)->getStmtData(S); } /// getEdgeDataMap - Retrieves the internal map between CFG edges and /// dataflow values. Usually used by a dataflow solver to compute /// values for blocks. - EdgeDataMapTy& getEdgeDataMap() { return EdgeDataMap; } - const EdgeDataMapTy& getEdgeDataMap() const { return EdgeDataMap; } + EdgeDataMapTy &getEdgeDataMap() { return EdgeDataMap; } + const EdgeDataMapTy &getEdgeDataMap() const { return EdgeDataMap; } /// getBlockDataMap - Retrieves the internal map between CFGBlocks and /// dataflow values. If the dataflow analysis operates in the forward /// direction, the values correspond to the dataflow values at the start /// of the block. Otherwise, for a backward analysis, the values correspond /// to the dataflow values at the end of the block. - BlockDataMapTy& getBlockDataMap() { return BlockDataMap; } - const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; } + BlockDataMapTy &getBlockDataMap() { return BlockDataMap; } + const BlockDataMapTy &getBlockDataMap() const { return BlockDataMap; } /// getStmtDataMap - Retrieves the internal map between Stmts and /// dataflow values. - StmtDataMapTy& getStmtDataMap() { - if (!StmtDataMap) StmtDataMap = new StmtDataMapTy(); + StmtDataMapTy &getStmtDataMap() { + if (!StmtDataMap) + StmtDataMap = new StmtDataMapTy(); return *StmtDataMap; } - const StmtDataMapTy& getStmtDataMap() const { - return const_cast(this)->getStmtDataMap(); + const StmtDataMapTy &getStmtDataMap() const { + return const_cast(this)->getStmtDataMap(); } /// getAnalysisData - Retrieves the meta data associated with a /// dataflow analysis for analyzing a particular CFG. /// This is typically consumed by transfer function code (via the solver). /// This can also be used by subclasses to interpret the dataflow values. - AnalysisDataTy& getAnalysisData() { return AnalysisData; } - const AnalysisDataTy& getAnalysisData() const { return AnalysisData; } + AnalysisDataTy &getAnalysisData() { return AnalysisData; } + const AnalysisDataTy &getAnalysisData() const { return AnalysisData; } //===--------------------------------------------------------------------===// // Internal data. //===--------------------------------------------------------------------===// protected: - EdgeDataMapTy EdgeDataMap; - BlockDataMapTy BlockDataMap; - StmtDataMapTy* StmtDataMap; - AnalysisDataTy AnalysisData; + EdgeDataMapTy EdgeDataMap; + BlockDataMapTy BlockDataMap; + StmtDataMapTy *StmtDataMap; + AnalysisDataTy AnalysisData; }; } // end namespace clang diff --git a/clang/include/clang/Analysis/PathDiagnostic.h b/clang/include/clang/Analysis/PathDiagnostic.h index 90559e7efb06f..db5d42a69c904 100644 --- a/clang/include/clang/Analysis/PathDiagnostic.h +++ b/clang/include/clang/Analysis/PathDiagnostic.h @@ -116,8 +116,7 @@ class PathDiagnosticConsumer { bool empty() const { return Set.empty(); } - void addDiagnostic(const PathDiagnostic &PD, - StringRef ConsumerName, + void addDiagnostic(const PathDiagnostic &PD, StringRef ConsumerName, StringRef fileName); PDFileEntry::ConsumerFiles *getFiles(const PathDiagnostic &PD); @@ -245,8 +244,7 @@ class PathDiagnosticLocation { } /// Create a location corresponding to the given declaration. - static PathDiagnosticLocation create(const Decl *D, - const SourceManager &SM) { + static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM) { return PathDiagnosticLocation(D, SM); } @@ -264,25 +262,25 @@ class PathDiagnosticLocation { } /// Create a location for the beginning of the statement. - static PathDiagnosticLocation createBegin(const Stmt *S, - const SourceManager &SM, - const LocationOrAnalysisDeclContext LAC); + static PathDiagnosticLocation + createBegin(const Stmt *S, const SourceManager &SM, + const LocationOrAnalysisDeclContext LAC); /// Create a location for the end of the statement. /// /// If the statement is a CompoundStatement, the location will point to the /// closing brace instead of following it. - static PathDiagnosticLocation createEnd(const Stmt *S, - const SourceManager &SM, - const LocationOrAnalysisDeclContext LAC); + static PathDiagnosticLocation + createEnd(const Stmt *S, const SourceManager &SM, + const LocationOrAnalysisDeclContext LAC); /// Create the location for the operator of the binary expression. /// Assumes the statement has a valid location. static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO, const SourceManager &SM); - static PathDiagnosticLocation createConditionalColonLoc( - const ConditionalOperator *CO, - const SourceManager &SM); + static PathDiagnosticLocation + createConditionalColonLoc(const ConditionalOperator *CO, + const SourceManager &SM); /// For member expressions, return the location of the '.' or '->'. /// Assumes the statement has a valid location. @@ -307,15 +305,15 @@ class PathDiagnosticLocation { /// Constructs a location for the end of the enclosing declaration body. /// Defaults to the end of brace. static PathDiagnosticLocation createDeclEnd(const LocationContext *LC, - const SourceManager &SM); + const SourceManager &SM); /// Create a location corresponding to the given valid ProgramPoint. static PathDiagnosticLocation create(const ProgramPoint &P, const SourceManager &SMng); /// Convert the given location into a single kind location. - static PathDiagnosticLocation createSingleLocation( - const PathDiagnosticLocation &PDL); + static PathDiagnosticLocation + createSingleLocation(const PathDiagnosticLocation &PDL); /// Construct a source location that corresponds to either the beginning /// or the end of the given statement, or a nearby valid source location @@ -332,38 +330,39 @@ class PathDiagnosticLocation { return !(*this == X); } - bool isValid() const { - return SM != nullptr; - } + bool isValid() const { return SM != nullptr; } - FullSourceLoc asLocation() const { - return Loc; - } + FullSourceLoc asLocation() const { return Loc; } - PathDiagnosticRange asRange() const { - return Range; - } + PathDiagnosticRange asRange() const { return Range; } - const Stmt *asStmt() const { assert(isValid()); return S; } + const Stmt *asStmt() const { + assert(isValid()); + return S; + } const Stmt *getStmtOrNull() const { if (!isValid()) return nullptr; return asStmt(); } - const Decl *asDecl() const { assert(isValid()); return D; } + const Decl *asDecl() const { + assert(isValid()); + return D; + } bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; } bool hasValidLocation() const { return asLocation().isValid(); } - void invalidate() { - *this = PathDiagnosticLocation(); - } + void invalidate() { *this = PathDiagnosticLocation(); } void flatten(); - const SourceManager& getManager() const { assert(isValid()); return *SM; } + const SourceManager &getManager() const { + assert(isValid()); + return *SM; + } void Profile(llvm::FoldingSetNodeID &ID) const; @@ -400,7 +399,7 @@ class PathDiagnosticLocationPair { // Path "pieces" for path-sensitive diagnostics. //===----------------------------------------------------------------------===// -class PathDiagnosticPiece: public llvm::FoldingSetNode { +class PathDiagnosticPiece : public llvm::FoldingSetNode { public: enum Kind { ControlFlow, Event, Macro, Call, Note, PopUp }; enum DisplayHint { Above, Below }; @@ -463,12 +462,10 @@ class PathDiagnosticPiece: public llvm::FoldingSetNode { void addRange(SourceLocation B, SourceLocation E) { if (!B.isValid() || !E.isValid()) return; - ranges.push_back(SourceRange(B,E)); + ranges.push_back(SourceRange(B, E)); } - void addFixit(FixItHint F) { - fixits.push_back(F); - } + void addFixit(FixItHint F) { fixits.push_back(F); } /// Return the SourceRanges associated with this PathDiagnosticPiece. ArrayRef getRanges() const { return ranges; } @@ -478,13 +475,9 @@ class PathDiagnosticPiece: public llvm::FoldingSetNode { virtual void Profile(llvm::FoldingSetNodeID &ID) const; - void setAsLastInMainSourceFile() { - LastInMainSourceFile = true; - } + void setAsLastInMainSourceFile() { LastInMainSourceFile = true; } - bool isLastInMainSourceFile() const { - return LastInMainSourceFile; - } + bool isLastInMainSourceFile() const { return LastInMainSourceFile; } virtual void dump() const = 0; }; @@ -510,14 +503,13 @@ class PathDiagnosticSpotPiece : public PathDiagnosticPiece { PathDiagnosticLocation Pos; public: - PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos, - StringRef s, - PathDiagnosticPiece::Kind k, - bool addPosRange = true) + PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos, StringRef s, + PathDiagnosticPiece::Kind k, bool addPosRange = true) : PathDiagnosticPiece(s, k), Pos(pos) { assert(Pos.isValid() && Pos.hasValidLocation() && "PathDiagnosticSpotPiece's must have a valid location."); - if (addPosRange && Pos.hasRange()) addRange(Pos.asRange()); + if (addPosRange && Pos.hasRange()) + addRange(Pos.asRange()); } PathDiagnosticLocation getLocation() const override { return Pos; } @@ -535,8 +527,8 @@ class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece { std::optional IsPrunable; public: - PathDiagnosticEventPiece(const PathDiagnosticLocation &pos, - StringRef s, bool addPosRange = true) + PathDiagnosticEventPiece(const PathDiagnosticLocation &pos, StringRef s, + bool addPosRange = true) : PathDiagnosticSpotPiece(pos, s, Event, addPosRange) {} ~PathDiagnosticEventPiece() override; @@ -580,8 +572,8 @@ class PathDiagnosticCallPiece : public PathDiagnosticPiece { : PathDiagnosticPiece(Call), Caller(callerD), NoExit(false), callReturn(callReturnPos) {} PathDiagnosticCallPiece(PathPieces &oldPath, const Decl *caller) - : PathDiagnosticPiece(Call), Caller(caller), NoExit(true), - path(oldPath) {} + : PathDiagnosticPiece(Call), Caller(caller), NoExit(true), path(oldPath) { + } public: PathDiagnosticLocation callEnter; @@ -614,8 +606,7 @@ class PathDiagnosticCallPiece : public PathDiagnosticPiece { } static std::shared_ptr - construct(const CallExitEnd &CE, - const SourceManager &SM); + construct(const CallExitEnd &CE, const SourceManager &SM); static PathDiagnosticCallPiece *construct(PathPieces &pieces, const Decl *caller); @@ -664,9 +655,7 @@ class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece { LPairs[0].setStart(L); } - void setEndLocation(const PathDiagnosticLocation &L) { - LPairs[0].setEnd(L); - } + void setEndLocation(const PathDiagnosticLocation &L) { LPairs[0].setEnd(L); } void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); } @@ -722,7 +711,7 @@ class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece { void Profile(llvm::FoldingSetNodeID &ID) const override; }; -class PathDiagnosticNotePiece: public PathDiagnosticSpotPiece { +class PathDiagnosticNotePiece : public PathDiagnosticSpotPiece { public: PathDiagnosticNotePiece(const PathDiagnosticLocation &Pos, StringRef S, bool AddPosRange = true) @@ -738,7 +727,7 @@ class PathDiagnosticNotePiece: public PathDiagnosticSpotPiece { void Profile(llvm::FoldingSetNodeID &ID) const override; }; -class PathDiagnosticPopUpPiece: public PathDiagnosticSpotPiece { +class PathDiagnosticPopUpPiece : public PathDiagnosticSpotPiece { public: PathDiagnosticPopUpPiece(const PathDiagnosticLocation &Pos, StringRef S, bool AddPosRange = true) @@ -803,15 +792,16 @@ class PathDiagnostic : public llvm::FoldingSetNode { } /// Return a mutable version of 'path'. - PathPieces &getMutablePieces() { - return pathImpl; - } + PathPieces &getMutablePieces() { return pathImpl; } /// Return the unrolled size of the path. unsigned full_size(); void pushActivePath(PathPieces *p) { pathStack.push_back(p); } - void popActivePath() { if (!pathStack.empty()) pathStack.pop_back(); } + void popActivePath() { + if (!pathStack.empty()) + pathStack.pop_back(); + } bool isWithinCall() const { return !pathStack.empty(); } @@ -844,40 +834,26 @@ class PathDiagnostic : public llvm::FoldingSetNode { meta_iterator meta_end() const { return OtherDesc.end(); } void addMeta(StringRef s) { OtherDesc.push_back(std::string(s)); } - const FilesToLineNumsMap &getExecutedLines() const { - return *ExecutedLines; - } + const FilesToLineNumsMap &getExecutedLines() const { return *ExecutedLines; } - FilesToLineNumsMap &getExecutedLines() { - return *ExecutedLines; - } + FilesToLineNumsMap &getExecutedLines() { return *ExecutedLines; } /// Return the semantic context where an issue occurred. If the /// issue occurs along a path, this represents the "central" area /// where the bug manifests. const Decl *getDeclWithIssue() const { return DeclWithIssue; } - void setDeclWithIssue(const Decl *D) { - DeclWithIssue = D; - } + void setDeclWithIssue(const Decl *D) { DeclWithIssue = D; } - PathDiagnosticLocation getLocation() const { - return Loc; - } + PathDiagnosticLocation getLocation() const { return Loc; } - void setLocation(PathDiagnosticLocation NewLoc) { - Loc = NewLoc; - } + void setLocation(PathDiagnosticLocation NewLoc) { Loc = NewLoc; } /// Get the location on which the report should be uniqued. - PathDiagnosticLocation getUniqueingLoc() const { - return UniqueingLoc; - } + PathDiagnosticLocation getUniqueingLoc() const { return UniqueingLoc; } /// Get the declaration containing the uniqueing location. - const Decl *getUniqueingDecl() const { - return UniqueingDecl; - } + const Decl *getUniqueingDecl() const { return UniqueingDecl; } void flattenLocations() { Loc.flatten(); diff --git a/clang/include/clang/Analysis/ProgramPoint.h b/clang/include/clang/Analysis/ProgramPoint.h index b9339570e1ae7..0b2d2cd550302 100644 --- a/clang/include/clang/Analysis/ProgramPoint.h +++ b/clang/include/clang/Analysis/ProgramPoint.h @@ -50,6 +50,7 @@ class ProgramPointTag { class SimpleProgramPointTag : public ProgramPointTag { std::string Desc; + public: SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg); StringRef getTagDescription() const override; @@ -57,33 +58,35 @@ class SimpleProgramPointTag : public ProgramPointTag { class ProgramPoint { public: - enum Kind { BlockEdgeKind, - BlockEntranceKind, - BlockExitKind, - PreStmtKind, - PreStmtPurgeDeadSymbolsKind, - PostStmtPurgeDeadSymbolsKind, - PostStmtKind, - PreLoadKind, - PostLoadKind, - PreStoreKind, - PostStoreKind, - PostConditionKind, - PostLValueKind, - PostAllocatorCallKind, - MinPostStmtKind = PostStmtKind, - MaxPostStmtKind = PostAllocatorCallKind, - PostInitializerKind, - CallEnterKind, - CallExitBeginKind, - CallExitEndKind, - FunctionExitKind, - PreImplicitCallKind, - PostImplicitCallKind, - MinImplicitCallKind = PreImplicitCallKind, - MaxImplicitCallKind = PostImplicitCallKind, - LoopExitKind, - EpsilonKind}; + enum Kind { + BlockEdgeKind, + BlockEntranceKind, + BlockExitKind, + PreStmtKind, + PreStmtPurgeDeadSymbolsKind, + PostStmtPurgeDeadSymbolsKind, + PostStmtKind, + PreLoadKind, + PostLoadKind, + PreStoreKind, + PostStoreKind, + PostConditionKind, + PostLValueKind, + PostAllocatorCallKind, + MinPostStmtKind = PostStmtKind, + MaxPostStmtKind = PostAllocatorCallKind, + PostInitializerKind, + CallEnterKind, + CallExitBeginKind, + CallExitEndKind, + FunctionExitKind, + PreImplicitCallKind, + PostImplicitCallKind, + MinImplicitCallKind = PreImplicitCallKind, + MaxImplicitCallKind = PostImplicitCallKind, + LoopExitKind, + EpsilonKind + }; private: const void *Data1; @@ -127,17 +130,16 @@ class ProgramPoint { /// Create a new ProgramPoint object that is the same as the original /// except for using the specified tag value. ProgramPoint withTag(const ProgramPointTag *tag) const { - return ProgramPoint(getData1(), getData2(), getKind(), - getLocationContext(), tag); + return ProgramPoint(getData1(), getData2(), getKind(), getLocationContext(), + tag); } /// Convert to the specified ProgramPoint type, asserting that this /// ProgramPoint is of the desired type. - template - T castAs() const { + template T castAs() const { assert(T::isKind(*this)); T t; - ProgramPoint& PP = t; + ProgramPoint &PP = t; PP = *this; return t; } @@ -148,7 +150,7 @@ class ProgramPoint { if (!T::isKind(*this)) return std::nullopt; T t; - ProgramPoint& PP = t; + ProgramPoint &PP = t; PP = *this; return t; } @@ -159,7 +161,7 @@ class ProgramPoint { x |= L.getInt(); x <<= 2; x |= Data2.getInt(); - return (Kind) x; + return (Kind)x; } /// Is this a program point corresponding to purge/removal of dead @@ -172,9 +174,7 @@ class ProgramPoint { const ProgramPointTag *getTag() const { return Tag.getPointer(); } - const LocationContext *getLocationContext() const { - return L.getPointer(); - } + const LocationContext *getLocationContext() const { return L.getPointer(); } const StackFrameContext *getStackFrame() const { return getLocationContext()->getStackFrame(); @@ -187,7 +187,7 @@ class ProgramPoint { return ID.ComputeHash(); } - bool operator==(const ProgramPoint & RHS) const { + bool operator==(const ProgramPoint &RHS) const { return Data1 == RHS.Data1 && Data2 == RHS.Data2 && L == RHS.L && Tag == RHS.Tag && ElemRef == RHS.ElemRef; } @@ -197,8 +197,8 @@ class ProgramPoint { Tag != RHS.Tag || ElemRef != RHS.ElemRef; } - void Profile(llvm::FoldingSetNodeID& ID) const { - ID.AddInteger((unsigned) getKind()); + void Profile(llvm::FoldingSetNodeID &ID) const { + ID.AddInteger((unsigned)getKind()); ID.AddPointer(getData1()); ID.AddPointer(getData2()); ID.AddPointer(getLocationContext()); @@ -220,12 +220,12 @@ class BlockEntrance : public ProgramPoint { public: BlockEntrance(const CFGBlock *B, const LocationContext *L, const ProgramPointTag *tag = nullptr) - : ProgramPoint(B, BlockEntranceKind, L, tag) { + : ProgramPoint(B, BlockEntranceKind, L, tag) { assert(B && "BlockEntrance requires non-null block"); } const CFGBlock *getBlock() const { - return reinterpret_cast(getData1()); + return reinterpret_cast(getData1()); } std::optional getFirstElement() const { @@ -244,15 +244,13 @@ class BlockEntrance : public ProgramPoint { class BlockExit : public ProgramPoint { public: BlockExit(const CFGBlock *B, const LocationContext *L) - : ProgramPoint(B, BlockExitKind, L) {} + : ProgramPoint(B, BlockExitKind, L) {} const CFGBlock *getBlock() const { - return reinterpret_cast(getData1()); + return reinterpret_cast(getData1()); } - const Stmt *getTerminator() const { - return getBlock()->getTerminatorStmt(); - } + const Stmt *getTerminator() const { return getBlock()->getTerminatorStmt(); } private: friend class ProgramPoint; @@ -267,17 +265,19 @@ class StmtPoint : public ProgramPoint { public: StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L, const ProgramPointTag *tag) - : ProgramPoint(S, p2, k, L, tag) { + : ProgramPoint(S, p2, k, L, tag) { assert(S); } - const Stmt *getStmt() const { return (const Stmt*) getData1(); } + const Stmt *getStmt() const { return (const Stmt *)getData1(); } - template - const T* getStmtAs() const { return dyn_cast(getStmt()); } + template const T *getStmtAs() const { + return dyn_cast(getStmt()); + } protected: StmtPoint() = default; + private: friend class ProgramPoint; static bool isKind(const ProgramPoint &Location) { @@ -286,14 +286,13 @@ class StmtPoint : public ProgramPoint { } }; - class PreStmt : public StmtPoint { public: PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag, const Stmt *SubStmt = nullptr) - : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {} + : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {} - const Stmt *getSubStmt() const { return (const Stmt*) getData2(); } + const Stmt *getSubStmt() const { return (const Stmt *)getData2(); } private: friend class ProgramPoint; @@ -308,16 +307,16 @@ class PostStmt : public StmtPoint { PostStmt() = default; PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L, const ProgramPointTag *tag = nullptr) - : StmtPoint(S, data, k, L, tag) {} + : StmtPoint(S, data, k, L, tag) {} public: explicit PostStmt(const Stmt *S, Kind k, const LocationContext *L, const ProgramPointTag *tag = nullptr) - : StmtPoint(S, nullptr, k, L, tag) {} + : StmtPoint(S, nullptr, k, L, tag) {} explicit PostStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag = nullptr) - : StmtPoint(S, nullptr, PostStmtKind, L, tag) {} + : StmtPoint(S, nullptr, PostStmtKind, L, tag) {} private: friend class ProgramPoint; @@ -329,8 +328,7 @@ class PostStmt : public StmtPoint { class FunctionExitPoint : public ProgramPoint { public: - explicit FunctionExitPoint(const ReturnStmt *S, - const LocationContext *LC, + explicit FunctionExitPoint(const ReturnStmt *S, const LocationContext *LC, const ProgramPointTag *tag = nullptr) : ProgramPoint(S, FunctionExitKind, LC, tag) {} @@ -355,7 +353,7 @@ class PostCondition : public PostStmt { public: PostCondition(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag = nullptr) - : PostStmt(S, PostConditionKind, L, tag) {} + : PostStmt(S, PostConditionKind, L, tag) {} private: friend class ProgramPoint; @@ -368,9 +366,9 @@ class PostCondition : public PostStmt { class LocationCheck : public StmtPoint { protected: LocationCheck() = default; - LocationCheck(const Stmt *S, const LocationContext *L, - ProgramPoint::Kind K, const ProgramPointTag *tag) - : StmtPoint(S, nullptr, K, L, tag) {} + LocationCheck(const Stmt *S, const LocationContext *L, ProgramPoint::Kind K, + const ProgramPointTag *tag) + : StmtPoint(S, nullptr, K, L, tag) {} private: friend class ProgramPoint; @@ -384,7 +382,7 @@ class PreLoad : public LocationCheck { public: PreLoad(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag = nullptr) - : LocationCheck(S, L, PreLoadKind, tag) {} + : LocationCheck(S, L, PreLoadKind, tag) {} private: friend class ProgramPoint; @@ -398,7 +396,7 @@ class PreStore : public LocationCheck { public: PreStore(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag = nullptr) - : LocationCheck(S, L, PreStoreKind, tag) {} + : LocationCheck(S, L, PreStoreKind, tag) {} private: friend class ProgramPoint; @@ -412,7 +410,7 @@ class PostLoad : public PostStmt { public: PostLoad(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag = nullptr) - : PostStmt(S, PostLoadKind, L, tag) {} + : PostStmt(S, PostLoadKind, L, tag) {} private: friend class ProgramPoint; @@ -430,16 +428,14 @@ class PostStore : public PostStmt { /// used in the form it was uttered in the code. PostStore(const Stmt *S, const LocationContext *L, const void *Loc, const ProgramPointTag *tag = nullptr) - : PostStmt(S, PostStoreKind, L, tag) { + : PostStmt(S, PostStoreKind, L, tag) { assert(getData2() == nullptr); setData2(Loc); } /// Returns the information about the location used in the store, /// how it was uttered in the code. - const void *getLocationValue() const { - return getData2(); - } + const void *getLocationValue() const { return getData2(); } private: friend class ProgramPoint; @@ -453,7 +449,7 @@ class PostLValue : public PostStmt { public: PostLValue(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag = nullptr) - : PostStmt(S, PostLValueKind, L, tag) {} + : PostStmt(S, PostLValueKind, L, tag) {} private: friend class ProgramPoint; @@ -468,8 +464,8 @@ class PostLValue : public PostStmt { class PreStmtPurgeDeadSymbols : public StmtPoint { public: PreStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L, - const ProgramPointTag *tag = nullptr) - : StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) { } + const ProgramPointTag *tag = nullptr) + : StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) {} private: friend class ProgramPoint; @@ -484,8 +480,8 @@ class PreStmtPurgeDeadSymbols : public StmtPoint { class PostStmtPurgeDeadSymbols : public StmtPoint { public: PostStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L, - const ProgramPointTag *tag = nullptr) - : StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) { } + const ProgramPointTag *tag = nullptr) + : StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) {} private: friend class ProgramPoint; @@ -498,17 +494,17 @@ class PostStmtPurgeDeadSymbols : public StmtPoint { class BlockEdge : public ProgramPoint { public: BlockEdge(const CFGBlock *B1, const CFGBlock *B2, const LocationContext *L) - : ProgramPoint(B1, B2, BlockEdgeKind, L) { + : ProgramPoint(B1, B2, BlockEdgeKind, L) { assert(B1 && "BlockEdge: source block must be non-null"); assert(B2 && "BlockEdge: destination block must be non-null"); } const CFGBlock *getSrc() const { - return static_cast(getData1()); + return static_cast(getData1()); } const CFGBlock *getDst() const { - return static_cast(getData2()); + return static_cast(getData2()); } private: @@ -526,19 +522,16 @@ class PostInitializer : public ProgramPoint { /// /// \param I The initializer. /// \param Loc The location of the field being initialized. - PostInitializer(const CXXCtorInitializer *I, - const void *Loc, + PostInitializer(const CXXCtorInitializer *I, const void *Loc, const LocationContext *L) - : ProgramPoint(I, Loc, PostInitializerKind, L) {} + : ProgramPoint(I, Loc, PostInitializerKind, L) {} const CXXCtorInitializer *getInitializer() const { return static_cast(getData1()); } /// Returns the location of the field. - const void *getLocationValue() const { - return getData2(); - } + const void *getLocationValue() const { return getData2(); } private: friend class ProgramPoint; @@ -565,6 +558,7 @@ class ImplicitCallPoint : public ProgramPoint { protected: ImplicitCallPoint() = default; + private: friend class ProgramPoint; static bool isKind(const ProgramPoint &Location) { @@ -629,7 +623,7 @@ class CallEnter : public ProgramPoint { public: CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, const LocationContext *callerCtx) - : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {} + : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {} const Stmt *getCallExpr() const { return static_cast(getData1()); @@ -667,7 +661,7 @@ class CallExitBegin : public ProgramPoint { public: // CallExitBegin uses the callee's location context. CallExitBegin(const StackFrameContext *L, const ReturnStmt *RS) - : ProgramPoint(RS, CallExitBeginKind, L, nullptr) { } + : ProgramPoint(RS, CallExitBeginKind, L, nullptr) {} const ReturnStmt *getReturnStmt() const { return static_cast(getData1()); @@ -688,7 +682,7 @@ class CallExitEnd : public ProgramPoint { // CallExitEnd uses the caller's location context. CallExitEnd(const StackFrameContext *CalleeCtx, const LocationContext *CallerCtx) - : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {} + : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {} const StackFrameContext *getCalleeContext() const { return static_cast(getData1()); @@ -710,19 +704,19 @@ class CallExitEnd : public ProgramPoint { /// result in a LoopExit program point. class LoopExit : public ProgramPoint { public: - LoopExit(const Stmt *LoopStmt, const LocationContext *LC) - : ProgramPoint(LoopStmt, nullptr, LoopExitKind, LC) {} + LoopExit(const Stmt *LoopStmt, const LocationContext *LC) + : ProgramPoint(LoopStmt, nullptr, LoopExitKind, LC) {} - const Stmt *getLoopStmt() const { - return static_cast(getData1()); - } + const Stmt *getLoopStmt() const { + return static_cast(getData1()); + } private: - friend class ProgramPoint; - LoopExit() = default; - static bool isKind(const ProgramPoint &Location) { - return Location.getKind() == LoopExitKind; - } + friend class ProgramPoint; + LoopExit() = default; + static bool isKind(const ProgramPoint &Location) { + return Location.getKind() == LoopExitKind; + } }; /// This is a meta program point, which should be skipped by all the diagnostic @@ -732,7 +726,7 @@ class EpsilonPoint : public ProgramPoint { EpsilonPoint(const LocationContext *L, const void *Data1, const void *Data2 = nullptr, const ProgramPointTag *tag = nullptr) - : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {} + : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {} const void *getData() const { return getData1(); } @@ -746,32 +740,33 @@ class EpsilonPoint : public ProgramPoint { } // end namespace clang - namespace llvm { // Traits specialization for DenseMap template <> struct DenseMapInfo { -static inline clang::ProgramPoint getEmptyKey() { - uintptr_t x = - reinterpret_cast(DenseMapInfo::getEmptyKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast(x), nullptr); -} - -static inline clang::ProgramPoint getTombstoneKey() { - uintptr_t x = - reinterpret_cast(DenseMapInfo::getTombstoneKey()) & ~0x7; - return clang::BlockEntrance(reinterpret_cast(x), nullptr); -} + static inline clang::ProgramPoint getEmptyKey() { + uintptr_t x = + reinterpret_cast(DenseMapInfo::getEmptyKey()) & ~0x7; + return clang::BlockEntrance(reinterpret_cast(x), + nullptr); + } -static unsigned getHashValue(const clang::ProgramPoint &Loc) { - return Loc.getHashValue(); -} + static inline clang::ProgramPoint getTombstoneKey() { + uintptr_t x = + reinterpret_cast(DenseMapInfo::getTombstoneKey()) & + ~0x7; + return clang::BlockEntrance(reinterpret_cast(x), + nullptr); + } -static bool isEqual(const clang::ProgramPoint &L, - const clang::ProgramPoint &R) { - return L == R; -} + static unsigned getHashValue(const clang::ProgramPoint &Loc) { + return Loc.getHashValue(); + } + static bool isEqual(const clang::ProgramPoint &L, + const clang::ProgramPoint &R) { + return L == R; + } }; } // end namespace llvm diff --git a/clang/include/clang/Analysis/RetainSummaryManager.h b/clang/include/clang/Analysis/RetainSummaryManager.h index 86865b9da4214..797daba7c2447 100644 --- a/clang/include/clang/Analysis/RetainSummaryManager.h +++ b/clang/include/clang/Analysis/RetainSummaryManager.h @@ -15,15 +15,15 @@ #ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARYMANAGER_H #define LLVM_CLANG_ANALYSIS_RETAINSUMMARYMANAGER_H -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/ImmutableMap.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ParentMap.h" #include "clang/Analysis/AnyCall.h" #include "clang/Analysis/SelectorExtras.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/ImmutableMap.h" #include "llvm/ADT/STLExtras.h" #include @@ -119,6 +119,7 @@ enum ArgEffectKind { class ArgEffect { ArgEffectKind K; ObjKind O; + public: explicit ArgEffect(ArgEffectKind K = DoNothing, ObjKind O = ObjKind::AnyObj) : K(K), O(O) {} @@ -126,9 +127,7 @@ class ArgEffect { ArgEffectKind getKind() const { return K; } ObjKind getObjKind() const { return O; } - ArgEffect withKind(ArgEffectKind NewK) { - return ArgEffect(NewK, O); - } + ArgEffect withKind(ArgEffectKind NewK) { return ArgEffect(NewK, O); } bool operator==(const ArgEffect &Other) const { return K == Other.K && O == Other.O; @@ -178,9 +177,7 @@ class RetEffect { return K == OwnedSymbol || K == OwnedWhenTrackedReceiver; } - bool notOwned() const { - return K == NotOwnedSymbol; - } + bool notOwned() const { return K == NotOwnedSymbol; } bool operator==(const RetEffect &Other) const { return K == Other.K && O == Other.O; @@ -190,33 +187,26 @@ class RetEffect { return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC); } - static RetEffect MakeOwned(ObjKind o) { - return RetEffect(OwnedSymbol, o); - } + static RetEffect MakeOwned(ObjKind o) { return RetEffect(OwnedSymbol, o); } static RetEffect MakeNotOwned(ObjKind o) { return RetEffect(NotOwnedSymbol, o); } - static RetEffect MakeNoRet() { - return RetEffect(NoRet); - } - static RetEffect MakeNoRetHard() { - return RetEffect(NoRetHard); - } + static RetEffect MakeNoRet() { return RetEffect(NoRet); } + static RetEffect MakeNoRetHard() { return RetEffect(NoRetHard); } }; /// A key identifying a summary. class ObjCSummaryKey { - IdentifierInfo* II; + IdentifierInfo *II; Selector S; + public: - ObjCSummaryKey(IdentifierInfo* ii, Selector s) - : II(ii), S(s) {} + ObjCSummaryKey(IdentifierInfo *ii, Selector s) : II(ii), S(s) {} ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s) - : II(d ? d->getIdentifier() : nullptr), S(s) {} + : II(d ? d->getIdentifier() : nullptr), S(s) {} - ObjCSummaryKey(Selector s) - : II(nullptr), S(s) {} + ObjCSummaryKey(Selector s) : II(nullptr), S(s) {} IdentifierInfo *getIdentifier() const { return II; } Selector getSelector() const { return S; } @@ -233,44 +223,42 @@ namespace llvm { // Adapters for FoldingSet. //===----------------------------------------------------------------------===// template <> struct FoldingSetTrait { -static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) { - ID.AddInteger((unsigned) X.getKind()); - ID.AddInteger((unsigned) X.getObjKind()); -} + static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) { + ID.AddInteger((unsigned)X.getKind()); + ID.AddInteger((unsigned)X.getObjKind()); + } }; template <> struct FoldingSetTrait { static inline void Profile(const RetEffect &X, FoldingSetNodeID &ID) { - ID.AddInteger((unsigned) X.getKind()); - ID.AddInteger((unsigned) X.getObjKind()); -} + ID.AddInteger((unsigned)X.getKind()); + ID.AddInteger((unsigned)X.getObjKind()); + } }; template <> struct DenseMapInfo { static inline ObjCSummaryKey getEmptyKey() { - return ObjCSummaryKey(DenseMapInfo::getEmptyKey(), + return ObjCSummaryKey(DenseMapInfo::getEmptyKey(), DenseMapInfo::getEmptyKey()); } static inline ObjCSummaryKey getTombstoneKey() { - return ObjCSummaryKey(DenseMapInfo::getTombstoneKey(), + return ObjCSummaryKey(DenseMapInfo::getTombstoneKey(), DenseMapInfo::getTombstoneKey()); } static unsigned getHashValue(const ObjCSummaryKey &V) { - typedef std::pair PairTy; - return DenseMapInfo::getHashValue(PairTy(V.getIdentifier(), - V.getSelector())); + typedef std::pair PairTy; + return DenseMapInfo::getHashValue( + PairTy(V.getIdentifier(), V.getSelector())); } - static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) { + static bool isEqual(const ObjCSummaryKey &LHS, const ObjCSummaryKey &RHS) { return LHS.getIdentifier() == RHS.getIdentifier() && LHS.getSelector() == RHS.getSelector(); } - }; -} // end llvm namespace - +} // namespace llvm namespace clang { namespace ento { @@ -302,13 +290,10 @@ class RetainSummary { RetEffect Ret; public: - RetainSummary(ArgEffects A, - RetEffect R, - ArgEffect defaultEff, - ArgEffect ReceiverEff, - ArgEffect ThisEff) - : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), - This(ThisEff), Ret(R) {} + RetainSummary(ArgEffects A, RetEffect R, ArgEffect defaultEff, + ArgEffect ReceiverEff, ArgEffect ThisEff) + : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), + This(ThisEff), Ret(R) {} /// getArg - Return the argument effect on the argument specified by /// idx (starting from 0). @@ -324,9 +309,7 @@ class RetainSummary { } /// setDefaultArgEffect - Set the default argument effect. - void setDefaultArgEffect(ArgEffect E) { - DefaultArgEffect = E; - } + void setDefaultArgEffect(ArgEffect E) { DefaultArgEffect = E; } /// getRetEffect - Returns the effect on the return value of the call. RetEffect getRetEffect() const { return Ret; } @@ -334,7 +317,6 @@ class RetainSummary { /// setRetEffect - Set the effect of the return value of the call. void setRetEffect(RetEffect E) { Ret = E; } - /// Sets the effect on the receiver of the message. void setReceiverEffect(ArgEffect e) { Receiver = e; } @@ -352,9 +334,9 @@ class RetainSummary { void setThisEffect(ArgEffect e) { This = e; } bool isNoop() const { - return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing - && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing - && Args.isEmpty(); + return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing && + DefaultArgEffect.getKind() == MayEscape && + This.getKind() == DoNothing && Args.isEmpty(); } /// Test if two retain summaries are identical. Note that merely equivalent @@ -366,7 +348,7 @@ class RetainSummary { } /// Profile this summary for inclusion in a FoldingSet. - void Profile(llvm::FoldingSetNodeID& ID) const { + void Profile(llvm::FoldingSetNodeID &ID) const { ID.Add(Args); ID.Add(DefaultArgEffect); ID.Add(Receiver); @@ -375,9 +357,7 @@ class RetainSummary { } /// A retain summary is simple if it has no ArgEffects other than the default. - bool isSimple() const { - return Args.isEmpty(); - } + bool isSimple() const { return Args.isEmpty(); } ArgEffects getArgEffects() const { return Args; } @@ -390,10 +370,11 @@ class RetainSummary { class ObjCSummaryCache { typedef llvm::DenseMap MapTy; MapTy M; + public: ObjCSummaryCache() {} - const RetainSummary * find(const ObjCInterfaceDecl *D, Selector S) { + const RetainSummary *find(const ObjCInterfaceDecl *D, Selector S) { // Do a lookup with the (D,S) pair. If we find a match return // the iterator. ObjCSummaryKey K(D, S); @@ -410,7 +391,7 @@ class ObjCSummaryCache { // generate initial summaries without having to worry about NSObject // being declared. // FIXME: We may change this at some point. - for (ObjCInterfaceDecl *C=D->getSuperClass() ;; C=C->getSuperClass()) { + for (ObjCInterfaceDecl *C = D->getSuperClass();; C = C->getSuperClass()) { if ((I = M.find(ObjCSummaryKey(C, S))) != M.end()) break; @@ -425,7 +406,7 @@ class ObjCSummaryCache { return Summ; } - const RetainSummary *find(IdentifierInfo* II, Selector S) { + const RetainSummary *find(IdentifierInfo *II, Selector S) { // FIXME: Class method lookup. Right now we don't have a good way // of going between IdentifierInfo* and the class hierarchy. MapTy::iterator I = M.find(ObjCSummaryKey(II, S)); @@ -436,20 +417,16 @@ class ObjCSummaryCache { return I == M.end() ? nullptr : I->second; } - const RetainSummary *& operator[](ObjCSummaryKey K) { - return M[K]; - } + const RetainSummary *&operator[](ObjCSummaryKey K) { return M[K]; } - const RetainSummary *& operator[](Selector S) { - return M[ ObjCSummaryKey(S) ]; - } + const RetainSummary *&operator[](Selector S) { return M[ObjCSummaryKey(S)]; } }; class RetainSummaryTemplate; class RetainSummaryManager { - typedef llvm::DenseMap - FuncSummariesTy; + typedef llvm::DenseMap + FuncSummariesTy; typedef ObjCSummaryCache ObjCMethodSummariesTy; @@ -511,7 +488,7 @@ class RetainSummaryManager { /// Free the OS object. const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD); - const RetainSummary *getUnarySummary(const FunctionType* FT, + const RetainSummary *getUnarySummary(const FunctionType *FT, ArgEffectKind AE); const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD); @@ -558,61 +535,60 @@ class RetainSummaryManager { ObjCMethodSummaries[S] = Summ; } - void addClassMethSummary(const char* Cls, const char* name, + void addClassMethSummary(const char *Cls, const char *name, const RetainSummary *Summ, bool isNullary = true) { - IdentifierInfo* ClsII = &Ctx.Idents.get(Cls); - Selector S = isNullary ? GetNullarySelector(name, Ctx) - : GetUnarySelector(name, Ctx); - ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ; + IdentifierInfo *ClsII = &Ctx.Idents.get(Cls); + Selector S = + isNullary ? GetNullarySelector(name, Ctx) : GetUnarySelector(name, Ctx); + ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ; } - void addInstMethSummary(const char* Cls, const char* nullaryName, + void addInstMethSummary(const char *Cls, const char *nullaryName, const RetainSummary *Summ) { - IdentifierInfo* ClsII = &Ctx.Idents.get(Cls); + IdentifierInfo *ClsII = &Ctx.Idents.get(Cls); Selector S = GetNullarySelector(nullaryName, Ctx); - ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ; + ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ; } template void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries, - const RetainSummary *Summ, Keywords *... Kws) { + const RetainSummary *Summ, Keywords *...Kws) { Selector S = getKeywordSelector(Ctx, Kws...); Summaries[ObjCSummaryKey(ClsII, S)] = Summ; } template void addInstMethSummary(const char *Cls, const RetainSummary *Summ, - Keywords *... Kws) { + Keywords *...Kws) { addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, Kws...); } template void addClsMethSummary(const char *Cls, const RetainSummary *Summ, - Keywords *... Kws) { + Keywords *...Kws) { addMethodSummary(&Ctx.Idents.get(Cls), ObjCClassMethodSummaries, Summ, Kws...); } template void addClsMethSummary(IdentifierInfo *II, const RetainSummary *Summ, - Keywords *... Kws) { + Keywords *...Kws) { addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...); } - const RetainSummary * generateSummary(const FunctionDecl *FD, - bool &AllowAnnotations); + const RetainSummary *generateSummary(const FunctionDecl *FD, + bool &AllowAnnotations); /// Return a summary for OSObject, or nullptr if not found. const RetainSummary *getSummaryForOSObject(const FunctionDecl *FD, StringRef FName, QualType RetTy); /// Return a summary for Objective-C or CF object, or nullptr if not found. - const RetainSummary *getSummaryForObjCOrCFObject( - const FunctionDecl *FD, - StringRef FName, - QualType RetTy, - const FunctionType *FT, - bool &AllowAnnotations); + const RetainSummary *getSummaryForObjCOrCFObject(const FunctionDecl *FD, + StringRef FName, + QualType RetTy, + const FunctionType *FT, + bool &AllowAnnotations); /// Apply the annotation of @c pd in function @c FD /// to the resulting summary stored in out-parameter @c Template. @@ -659,15 +635,13 @@ class RetainSummaryManager { bool isTrustedReferenceCountImplementation(const Decl *FD); - const RetainSummary *getSummary(AnyCall C, - bool HasNonZeroCallbackArg=false, - bool IsReceiverUnconsumedSelf=false, - QualType ReceiverType={}); + const RetainSummary *getSummary(AnyCall C, bool HasNonZeroCallbackArg = false, + bool IsReceiverUnconsumedSelf = false, + QualType ReceiverType = {}); RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; } private: - /// getMethodSummary - This version of getMethodSummary is used to query /// the summary for the current method being analyzed. const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD); @@ -679,8 +653,8 @@ class RetainSummaryManager { QualType RetTy, ObjCMethodSummariesTy &CachedSummaries); - const RetainSummary * - getInstanceMethodSummary(const ObjCMessageExpr *ME, QualType ReceiverType); + const RetainSummary *getInstanceMethodSummary(const ObjCMessageExpr *ME, + QualType ReceiverType); const RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME); @@ -697,8 +671,8 @@ class RetainSummaryManager { void updateSummaryFromAnnotations(const RetainSummary *&Summ, const FunctionDecl *FD); - const RetainSummary *updateSummaryForNonZeroCallbackArg(const RetainSummary *S, - AnyCall &C); + const RetainSummary * + updateSummaryForNonZeroCallbackArg(const RetainSummary *S, AnyCall &C); /// Special case '[super init];' and '[self init];' /// @@ -715,7 +689,8 @@ class RetainSummaryManager { void updateSummaryForReceiverUnconsumedSelf(const RetainSummary *&S); /// Set argument types for arguments which are not doing anything. - void updateSummaryForArgumentTypes(const AnyCall &C, const RetainSummary *&RS); + void updateSummaryForArgumentTypes(const AnyCall &C, + const RetainSummary *&RS); /// Determine whether a declaration @c D of correspondent type (return /// type for functions/methods) @c QT has any of the given attributes, @@ -733,7 +708,6 @@ class RetainSummaryManager { friend class RetainSummaryTemplate; }; - // Used to avoid allocating long-term (BPAlloc'd) memory for default retain // summaries. If a function or method looks like it has a default summary, but // it has annotations, the annotations are added to the stack-based template @@ -743,9 +717,11 @@ class RetainSummaryTemplate { const RetainSummary *&RealSummary; RetainSummary ScratchSummary; bool Accessed; + public: RetainSummaryTemplate(const RetainSummary *&real, RetainSummaryManager &mgr) - : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(false) {} + : Manager(mgr), RealSummary(real), ScratchSummary(*real), + Accessed(false) {} ~RetainSummaryTemplate() { if (Accessed) diff --git a/clang/include/clang/Analysis/SelectorExtras.h b/clang/include/clang/Analysis/SelectorExtras.h index 1e1daf5706bbf..c41717632f595 100644 --- a/clang/include/clang/Analysis/SelectorExtras.h +++ b/clang/include/clang/Analysis/SelectorExtras.h @@ -15,7 +15,7 @@ namespace clang { template static inline Selector getKeywordSelector(ASTContext &Ctx, - IdentifierInfos *... IIs) { + IdentifierInfos *...IIs) { static_assert(sizeof...(IdentifierInfos) > 0, "keyword selectors must have at least one argument"); SmallVector II({&Ctx.Idents.get(IIs)...}); @@ -25,7 +25,7 @@ static inline Selector getKeywordSelector(ASTContext &Ctx, template static inline void lazyInitKeywordSelector(Selector &Sel, ASTContext &Ctx, - IdentifierInfos *... IIs) { + IdentifierInfos *...IIs) { if (!Sel.isNull()) return; Sel = getKeywordSelector(Ctx, IIs...); diff --git a/clang/include/clang/Analysis/Support/BumpVector.h b/clang/include/clang/Analysis/Support/BumpVector.h index 6c3f11e993067..f65331e5d3fb8 100644 --- a/clang/include/clang/Analysis/Support/BumpVector.h +++ b/clang/include/clang/Analysis/Support/BumpVector.h @@ -30,7 +30,7 @@ namespace clang { class BumpVectorContext { - llvm::PointerIntPair Alloc; + llvm::PointerIntPair Alloc; public: /// Construct a new BumpVectorContext that creates a new BumpPtrAllocator @@ -64,17 +64,14 @@ class BumpVectorContext { llvm::BumpPtrAllocator &getAllocator() { return *Alloc.getPointer(); } }; -template -class BumpVector { +template class BumpVector { T *Begin = nullptr; T *End = nullptr; T *Capacity = nullptr; public: // Default ctor - Initialize to empty. - explicit BumpVector(BumpVectorContext &C, unsigned N) { - reserve(C, N); - } + explicit BumpVector(BumpVectorContext &C, unsigned N) { reserve(C, N); } ~BumpVector() { if (std::is_class::value) { @@ -105,14 +102,16 @@ class BumpVector { // reverse iterator creation methods. reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } bool empty() const { return Begin == End; } - size_type size() const { return End-Begin; } + size_type size() const { return End - Begin; } reference operator[](unsigned idx) { assert(Begin + idx < End); @@ -123,19 +122,11 @@ class BumpVector { return Begin[idx]; } - reference front() { - return begin()[0]; - } - const_reference front() const { - return begin()[0]; - } + reference front() { return begin()[0]; } + const_reference front() const { return begin()[0]; } - reference back() { - return end()[-1]; - } - const_reference back() const { - return end()[-1]; - } + reference back() { return end()[-1]; } + const_reference back() const { return end()[-1]; } void pop_back() { --End; @@ -156,14 +147,10 @@ class BumpVector { } /// data - Return a pointer to the vector's buffer, even if empty(). - pointer data() { - return pointer(Begin); - } + pointer data() { return pointer(Begin); } /// data - Return a pointer to the vector's buffer, even if empty(). - const_pointer data() const { - return const_pointer(Begin); - } + const_pointer data() const { return const_pointer(Begin); } void push_back(const_reference Elt, BumpVectorContext &C) { if (End < Capacity) { @@ -179,7 +166,7 @@ class BumpVector { /// insert - Insert some number of copies of element into a position. Return /// iterator to position after last inserted copy. iterator insert(iterator I, size_t Cnt, const_reference E, - BumpVectorContext &C) { + BumpVectorContext &C) { assert(I >= Begin && I <= End && "Iterator out of bounds."); if (End + Cnt <= Capacity) { Retry: @@ -195,7 +182,7 @@ class BumpVector { } void reserve(BumpVectorContext &C, unsigned N) { - if (unsigned(Capacity-Begin) < N) + if (unsigned(Capacity - Begin) < N) grow(C, N); } @@ -232,9 +219,9 @@ class BumpVector { // Define this out-of-line to dissuade the C++ compiler from inlining it. template void BumpVector::grow(BumpVectorContext &C, size_t MinSize) { - size_t CurCapacity = Capacity-Begin; + size_t CurCapacity = Capacity - Begin; size_t CurSize = size(); - size_t NewCapacity = 2*CurCapacity; + size_t NewCapacity = 2 * CurCapacity; if (NewCapacity < MinSize) NewCapacity = MinSize; @@ -256,8 +243,8 @@ void BumpVector::grow(BumpVectorContext &C, size_t MinSize) { // For now, leak 'Begin'. We can add it back to a freelist in // BumpVectorContext. Begin = NewElts; - End = NewElts+CurSize; - Capacity = Begin+NewCapacity; + End = NewElts + CurSize; + Capacity = Begin + NewCapacity; } } // namespace clang diff --git a/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h b/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h index bdfe3901c5b80..c3a1c1612b516 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h +++ b/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h @@ -29,8 +29,8 @@ class CheckerManager; #undef CHECKER #undef GET_CHECKERS -} // end ento namespace +} // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h b/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h index 6243bbd5d53bc..5b19925f3cf6a 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h +++ b/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h @@ -68,29 +68,40 @@ class MPIFunctionClassifier { // point-to-point functions IdentifierInfo *IdentInfo_MPI_Send = nullptr, *IdentInfo_MPI_Isend = nullptr, - *IdentInfo_MPI_Ssend = nullptr, *IdentInfo_MPI_Issend = nullptr, - *IdentInfo_MPI_Bsend = nullptr, *IdentInfo_MPI_Ibsend = nullptr, - *IdentInfo_MPI_Rsend = nullptr, *IdentInfo_MPI_Irsend = nullptr, - *IdentInfo_MPI_Recv = nullptr, *IdentInfo_MPI_Irecv = nullptr; + *IdentInfo_MPI_Ssend = nullptr, + *IdentInfo_MPI_Issend = nullptr, + *IdentInfo_MPI_Bsend = nullptr, + *IdentInfo_MPI_Ibsend = nullptr, + *IdentInfo_MPI_Rsend = nullptr, + *IdentInfo_MPI_Irsend = nullptr, *IdentInfo_MPI_Recv = nullptr, + *IdentInfo_MPI_Irecv = nullptr; // collective functions IdentifierInfo *IdentInfo_MPI_Scatter = nullptr, - *IdentInfo_MPI_Iscatter = nullptr, *IdentInfo_MPI_Gather = nullptr, - *IdentInfo_MPI_Igather = nullptr, *IdentInfo_MPI_Allgather = nullptr, - *IdentInfo_MPI_Iallgather = nullptr, *IdentInfo_MPI_Bcast = nullptr, - *IdentInfo_MPI_Ibcast = nullptr, *IdentInfo_MPI_Reduce = nullptr, - *IdentInfo_MPI_Ireduce = nullptr, *IdentInfo_MPI_Allreduce = nullptr, - *IdentInfo_MPI_Iallreduce = nullptr, *IdentInfo_MPI_Alltoall = nullptr, - *IdentInfo_MPI_Ialltoall = nullptr, *IdentInfo_MPI_Barrier = nullptr; + *IdentInfo_MPI_Iscatter = nullptr, + *IdentInfo_MPI_Gather = nullptr, + *IdentInfo_MPI_Igather = nullptr, + *IdentInfo_MPI_Allgather = nullptr, + *IdentInfo_MPI_Iallgather = nullptr, + *IdentInfo_MPI_Bcast = nullptr, + *IdentInfo_MPI_Ibcast = nullptr, + *IdentInfo_MPI_Reduce = nullptr, + *IdentInfo_MPI_Ireduce = nullptr, + *IdentInfo_MPI_Allreduce = nullptr, + *IdentInfo_MPI_Iallreduce = nullptr, + *IdentInfo_MPI_Alltoall = nullptr, + *IdentInfo_MPI_Ialltoall = nullptr, + *IdentInfo_MPI_Barrier = nullptr; // additional functions IdentifierInfo *IdentInfo_MPI_Comm_rank = nullptr, - *IdentInfo_MPI_Comm_size = nullptr, *IdentInfo_MPI_Wait = nullptr, - *IdentInfo_MPI_Waitall = nullptr; + *IdentInfo_MPI_Comm_size = nullptr, + *IdentInfo_MPI_Wait = nullptr, + *IdentInfo_MPI_Waitall = nullptr; }; -} // end of namespace: mpi -} // end of namespace: ento -} // end of namespace: clang +} // namespace mpi +} // namespace ento +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h b/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h index 43a70f596a4da..0305180064546 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h +++ b/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h @@ -57,13 +57,9 @@ class SValExplainer : public FullSValVisitor { public: SValExplainer(ASTContext &Ctx) : ACtx(Ctx) {} - std::string VisitUnknownVal(UnknownVal V) { - return "unknown value"; - } + std::string VisitUnknownVal(UnknownVal V) { return "unknown value"; } - std::string VisitUndefinedVal(UndefinedVal V) { - return "undefined value"; - } + std::string VisitUndefinedVal(UndefinedVal V) { return "undefined value"; } std::string VisitMemRegionVal(loc::MemRegionVal V) { const MemRegion *R = V.getRegion(); @@ -116,8 +112,8 @@ class SValExplainer : public FullSValVisitor { } std::string VisitSymbolDerived(const SymbolDerived *S) { - return "value derived from (" + Visit(S->getParentSymbol()) + - ") for " + Visit(S->getRegion()); + return "value derived from (" + Visit(S->getParentSymbol()) + ") for " + + Visit(S->getRegion()); } std::string VisitSymbolExtent(const SymbolExtent *S) { @@ -143,8 +139,8 @@ class SValExplainer : public FullSValVisitor { std::string VisitSymSymExpr(const SymSymExpr *S) { return "(" + Visit(S->getLHS()) + ") " + - std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) + - " (" + Visit(S->getRHS()) + ")"; + std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) + " (" + + Visit(S->getRHS()) + ")"; } std::string VisitUnarySymExpr(const UnarySymExpr *S) { @@ -162,8 +158,10 @@ class SValExplainer : public FullSValVisitor { return "'this' object"; // Objective-C objects are not normal symbolic regions. At least, // they're always on the heap. - if (R->getSymbol()->getType() - .getCanonicalType()->getAs()) + if (R->getSymbol() + ->getType() + .getCanonicalType() + ->getAs()) return "object at " + Visit(R->getSymbol()); // Other heap-based symbolic regions are also special. if (isa(R->getMemorySpace())) @@ -277,8 +275,8 @@ class SValExplainer : public FullSValVisitor { std::string Str; llvm::raw_string_ostream OS(Str); OS << V; - return "a value unsupported by the explainer: (" + - std::string(OS.str()) + ")"; + return "a value unsupported by the explainer: (" + std::string(OS.str()) + + ")"; } std::string VisitSymExpr(SymbolRef S) { diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index 276d11e80a5b2..80eb04e7d5f73 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -35,7 +35,7 @@ class CheckerBase; enum AnalysisConstraints { #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model, #include "clang/StaticAnalyzer/Core/Analyses.def" -NumConstraints + NumConstraints }; /// AnalysisDiagClients - Set of available diagnostic clients for rendering @@ -43,22 +43,23 @@ NumConstraints enum AnalysisDiagClients { #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME, #include "clang/StaticAnalyzer/Core/Analyses.def" -PD_NONE, -NUM_ANALYSIS_DIAG_CLIENTS + PD_NONE, + NUM_ANALYSIS_DIAG_CLIENTS }; /// AnalysisPurgeModes - Set of available strategies for dead symbol removal. enum AnalysisPurgeMode { #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME, #include "clang/StaticAnalyzer/Core/Analyses.def" -NumPurgeModes + NumPurgeModes }; -/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics. +/// AnalysisInlineFunctionSelection - Set of inlining function selection +/// heuristics. enum AnalysisInliningMode { #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME, #include "clang/StaticAnalyzer/Core/Analyses.def" -NumInliningModes + NumInliningModes }; /// Describes the different kinds of C++ member functions which can be @@ -253,8 +254,7 @@ class AnalyzerOptions : public RefCountedBase { SHALLOW_VAL, DEEP_VAL) \ ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL) -#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ - TYPE NAME; +#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) TYPE NAME; #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" #undef ANALYZER_OPTION @@ -373,17 +373,14 @@ class AnalyzerOptions : public RefCountedBase { bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const; ento::PathDiagnosticConsumerOptions getDiagOpts() const { - return {FullCompilerInvocation, - ShouldDisplayMacroExpansions, + return {FullCompilerInvocation, ShouldDisplayMacroExpansions, ShouldSerializeStats, // The stable report filename option is deprecated because // file names are now always stable. Now the old option acts as // an alias to the new verbose filename option because this // closely mimics the behavior under the old option. ShouldWriteStableReportFilename || ShouldWriteVerboseReportFilename, - AnalyzerWerror, - ShouldApplyFixIts, - ShouldDisplayCheckerNameForText}; + AnalyzerWerror, ShouldApplyFixIts, ShouldDisplayCheckerNameForText}; } }; diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index e762f7548e0b5..5ffb95e1385d3 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -109,9 +109,7 @@ class StackHintGeneratorForSymbol : public StackHintGenerator { return Msg; } - virtual std::string getMessageForSymbolNotFound() { - return Msg; - } + virtual std::string getMessageForSymbolNotFound() { return Msg; } }; /// This class provides an interface through which checkers can create @@ -125,7 +123,7 @@ class BugReport { friend class BugReporter; Kind K; - const BugType& BT; + const BugType &BT; std::string ShortDescription; std::string Description; @@ -146,7 +144,7 @@ class BugReport { Kind getKind() const { return K; } - const BugType& getBugType() const { return BT; } + const BugType &getBugType() const { return BT; } /// A verbose warning message that is appropriate for displaying next to /// the source code that introduces the problem. The description should be @@ -157,8 +155,8 @@ class BugReport { StringRef getDescription() const { return Description; } /// A short general warning message that is appropriate for displaying in - /// the list of all reported bugs. It should describe what kind of bug is found - /// but does not need to try to go into details of that specific bug. + /// the list of all reported bugs. It should describe what kind of bug is + /// found but does not need to try to go into details of that specific bug. /// Grammatical conventions of getDescription() apply here as well. StringRef getShortDescription(bool UseFallback = true) const { if (ShortDescription.empty() && UseFallback) @@ -220,15 +218,14 @@ class BugReport { /// node will be used; add a single invalid range to specify absence of /// ranges. void addRange(SourceRange R) { - assert((R.isValid() || Ranges.empty()) && "Invalid range can only be used " - "to specify that the report does not have a range."); + assert((R.isValid() || Ranges.empty()) && + "Invalid range can only be used " + "to specify that the report does not have a range."); Ranges.push_back(R); } /// Get the SourceRanges associated with the report. - virtual ArrayRef getRanges() const { - return Ranges; - } + virtual ArrayRef getRanges() const { return Ranges; } /// Add a fix-it hint to the bug report. /// @@ -237,15 +234,13 @@ class BugReport { /// as conservative as possible because it is not uncommon for the user /// to blindly apply all fixits to their project. Note that it is very hard /// to produce a good fix-it hint for most path-sensitive warnings. - void addFixItHint(const FixItHint &F) { - Fixits.push_back(F); - } + void addFixItHint(const FixItHint &F) { Fixits.push_back(F); } llvm::ArrayRef getFixits() const { return Fixits; } /// Reports are uniqued to ensure that we do not emit multiple diagnostics /// for each bug. - virtual void Profile(llvm::FoldingSetNodeID& hash) const = 0; + virtual void Profile(llvm::FoldingSetNodeID &hash) const = 0; }; class BasicBugReport : public BugReport { @@ -265,17 +260,13 @@ class BasicBugReport : public BugReport { return Location; } - const Decl *getDeclWithIssue() const override { - return DeclWithIssue; - } + const Decl *getDeclWithIssue() const override { return DeclWithIssue; } PathDiagnosticLocation getUniqueingLocation() const override { return getLocation(); } - const Decl *getUniqueingDecl() const override { - return getDeclWithIssue(); - } + const Decl *getUniqueingDecl() const override { return getDeclWithIssue(); } /// Specifically set the Decl where an issue occurred. This isn't necessary /// for BugReports that cover a path as it will be automatically inferred. @@ -283,7 +274,7 @@ class BasicBugReport : public BugReport { DeclWithIssue = declWithIssue; } - void Profile(llvm::FoldingSetNodeID& hash) const override; + void Profile(llvm::FoldingSetNodeID &hash) const override; }; class PathSensitiveBugReport : public BugReport { @@ -414,9 +405,7 @@ class PathSensitiveBugReport : public BugReport { } /// Get the declaration containing the uniqueing location. - const Decl *getUniqueingDecl() const override { - return UniqueingDecl; - } + const Decl *getUniqueingDecl() const override { return UniqueingDecl; } const Decl *getDeclWithIssue() const override; @@ -465,9 +454,7 @@ class PathSensitiveBugReport : public BugReport { /// /// Invalid reports are those that have been classified as likely false /// positives after the fact. - bool isValid() const { - return Invalidations.empty(); - } + bool isValid() const { return Invalidations.empty(); } /// Marks the current report as invalid, meaning that it is probably a false /// positive and should not be reported to the user. @@ -495,7 +482,7 @@ class PathSensitiveBugReport : public BugReport { void addVisitor(std::unique_ptr visitor); template - void addVisitor(Args &&... ConstructorArgs) { + void addVisitor(Args &&...ConstructorArgs) { addVisitor( std::make_unique(std::forward(ConstructorArgs)...)); } @@ -527,9 +514,8 @@ class PathSensitiveBugReport : public BugReport { /// Produce the hint for the given node. The node contains /// information about the call for which the diagnostic can be generated. - std::string - getCallStackMessage(PathDiagnosticPieceRef Piece, - const ExplodedNode *N) const { + std::string getCallStackMessage(PathDiagnosticPieceRef Piece, + const ExplodedNode *N) const { auto I = StackHints.find(Piece); if (I != StackHints.end()) return I->second->getMessage(N); @@ -556,7 +542,7 @@ class BugReportEquivClass : public llvm::FoldingSetNode { ArrayRef> getReports() const { return Reports; } - void Profile(llvm::FoldingSetNodeID& ID) const { + void Profile(llvm::FoldingSetNodeID &ID) const { assert(!Reports.empty()); Reports.front()->Profile(ID); } @@ -570,7 +556,7 @@ class BugReporterData { public: virtual ~BugReporterData() = default; - virtual ArrayRef getPathDiagnosticConsumers() = 0; + virtual ArrayRef getPathDiagnosticConsumers() = 0; virtual ASTContext &getASTContext() = 0; virtual SourceManager &getSourceManager() = 0; virtual AnalyzerOptions &getAnalyzerOptions() = 0; @@ -584,10 +570,10 @@ class BugReporterData { /// The base class is used for generating path-insensitive class BugReporter { private: - BugReporterData& D; + BugReporterData &D; /// Generate and flush the diagnostics for the given bug report. - void FlushReport(BugReportEquivClass& EQ); + void FlushReport(BugReportEquivClass &EQ); /// The set of bug reports tracked by the BugReporter. llvm::FoldingSet EQClasses; @@ -605,7 +591,7 @@ class BugReporter { /// Generate and flush diagnostics for all bug reports. void FlushReports(); - ArrayRef getPathDiagnosticConsumers() { + ArrayRef getPathDiagnosticConsumers() { return D.getPathDiagnosticConsumers(); } @@ -666,7 +652,7 @@ class BugReporter { /// GRBugReporter is used for generating path-sensitive reports. class PathSensitiveBugReporter final : public BugReporter { - ExprEngine& Eng; + ExprEngine &Eng; BugReport *findReportInEquivalenceClass( BugReportEquivClass &eqClass, @@ -677,8 +663,9 @@ class PathSensitiveBugReporter final : public BugReporter { generateDiagnosticForConsumerMap(BugReport *exampleReport, ArrayRef consumers, ArrayRef bugReports) override; + public: - PathSensitiveBugReporter(BugReporterData& d, ExprEngine& eng) + PathSensitiveBugReporter(BugReporterData &d, ExprEngine &eng) : BugReporter(d), Eng(eng) {} /// getGraph - Get the exploded graph created by the analysis engine @@ -694,14 +681,13 @@ class PathSensitiveBugReporter final : public BugReporter { /// \return A mapping from consumers to the corresponding diagnostics. /// Iterates through the bug reports within a single equivalence class, /// stops at a first non-invalidated report. - std::unique_ptr generatePathDiagnostics( - ArrayRef consumers, - ArrayRef &bugReports); + std::unique_ptr + generatePathDiagnostics(ArrayRef consumers, + ArrayRef &bugReports); void emitReport(std::unique_ptr R) override; }; - class BugReporterContext { PathSensitiveBugReporter &BR; @@ -712,17 +698,13 @@ class BugReporterContext { virtual ~BugReporterContext() = default; - PathSensitiveBugReporter& getBugReporter() { return BR; } + PathSensitiveBugReporter &getBugReporter() { return BR; } - ProgramStateManager& getStateManager() const { - return BR.getStateManager(); - } + ProgramStateManager &getStateManager() const { return BR.getStateManager(); } - ASTContext &getASTContext() const { - return BR.getContext(); - } + ASTContext &getASTContext() const { return BR.getContext(); } - const SourceManager& getSourceManager() const { + const SourceManager &getSourceManager() const { return BR.getSourceManager(); } @@ -749,7 +731,7 @@ class DataTag : public ProgramPointTag { public: template - const DataTagType *make(Args &&... ConstructorArgs) { + const DataTagType *make(Args &&...ConstructorArgs) { // We cannot use std::make_unique because we cannot access the private // constructor from inside it. Tags.emplace_back( diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h index d9b3d9352d322..653d4632f20c6 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h @@ -280,7 +280,7 @@ class Tracker : public llvm::RefCountedBase { /// /// See other overloads for explanation. template - void addHighPriorityHandler(Args &&... ConstructorArgs) { + void addHighPriorityHandler(Args &&...ConstructorArgs) { addHighPriorityHandler(std::make_unique( *this, std::forward(ConstructorArgs)...)); } @@ -289,7 +289,7 @@ class Tracker : public llvm::RefCountedBase { /// /// See other overloads for explanation. template - void addLowPriorityHandler(Args &&... ConstructorArgs) { + void addLowPriorityHandler(Args &&...ConstructorArgs) { addLowPriorityHandler(std::make_unique( *this, std::forward(ConstructorArgs)...)); } diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h index e50afd6d0da7e..3fd3a5f5e6510 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h @@ -66,5 +66,5 @@ class BugType { } // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/Checker.h b/clang/include/clang/StaticAnalyzer/Core/Checker.h index 2ec54a837c42c..1212816ed952a 100644 --- a/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -21,33 +21,31 @@ namespace clang { namespace ento { - class BugReporter; +class BugReporter; namespace check { -template -class ASTDecl { +template class ASTDecl { template - static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr, + static void _checkDecl(void *checker, const Decl *D, AnalysisManager &mgr, BugReporter &BR) { ((const CHECKER *)checker)->checkASTDecl(cast(D), mgr, BR); } - static bool _handlesDecl(const Decl *D) { - return isa(D); - } + static bool _handlesDecl(const Decl *D) { return isa(D); } + public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker, - _checkDecl), - _handlesDecl); + mgr._registerForDecl( + CheckerManager::CheckDeclFunc(checker, _checkDecl), + _handlesDecl); } }; class ASTCodeBody { template - static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr, + static void _checkBody(void *checker, const Decl *D, AnalysisManager &mgr, BugReporter &BR) { ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR); } @@ -55,64 +53,59 @@ class ASTCodeBody { public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForBody(CheckerManager::CheckDeclFunc(checker, - _checkBody)); + mgr._registerForBody( + CheckerManager::CheckDeclFunc(checker, _checkBody)); } }; class EndOfTranslationUnit { template - static void _checkEndOfTranslationUnit(void *checker, - const TranslationUnitDecl *TU, - AnalysisManager& mgr, - BugReporter &BR) { + static void + _checkEndOfTranslationUnit(void *checker, const TranslationUnitDecl *TU, + AnalysisManager &mgr, BugReporter &BR) { ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR); } public: template - static void _register(CHECKER *checker, CheckerManager &mgr){ + static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForEndOfTranslationUnit( - CheckerManager::CheckEndOfTranslationUnit(checker, - _checkEndOfTranslationUnit)); + CheckerManager::CheckEndOfTranslationUnit( + checker, _checkEndOfTranslationUnit)); } }; -template -class PreStmt { +template class PreStmt { template static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) { ((const CHECKER *)checker)->checkPreStmt(cast(S), C); } - static bool _handlesStmt(const Stmt *S) { - return isa(S); - } + static bool _handlesStmt(const Stmt *S) { return isa(S); } + public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker, - _checkStmt), - _handlesStmt); + mgr._registerForPreStmt( + CheckerManager::CheckStmtFunc(checker, _checkStmt), + _handlesStmt); } }; -template -class PostStmt { +template class PostStmt { template static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) { ((const CHECKER *)checker)->checkPostStmt(cast(S), C); } - static bool _handlesStmt(const Stmt *S) { - return isa(S); - } + static bool _handlesStmt(const Stmt *S) { return isa(S); } + public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker, - _checkStmt), - _handlesStmt); + mgr._registerForPostStmt( + CheckerManager::CheckStmtFunc(checker, _checkStmt), + _handlesStmt); } }; @@ -126,8 +119,8 @@ class PreObjCMessage { public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForPreObjCMessage( - CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage)); + mgr._registerForPreObjCMessage(CheckerManager::CheckObjCMessageFunc( + checker, _checkObjCMessage)); } }; @@ -141,8 +134,8 @@ class ObjCMessageNil { public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForObjCMessageNil( - CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage)); + mgr._registerForObjCMessageNil(CheckerManager::CheckObjCMessageFunc( + checker, _checkObjCMessage)); } }; @@ -156,8 +149,8 @@ class PostObjCMessage { public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForPostObjCMessage( - CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage)); + mgr._registerForPostObjCMessage(CheckerManager::CheckObjCMessageFunc( + checker, _checkObjCMessage)); } }; @@ -172,7 +165,7 @@ class PreCall { template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForPreCall( - CheckerManager::CheckCallFunc(checker, _checkCall)); + CheckerManager::CheckCallFunc(checker, _checkCall)); } }; @@ -187,7 +180,7 @@ class PostCall { template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForPostCall( - CheckerManager::CheckCallFunc(checker, _checkCall)); + CheckerManager::CheckCallFunc(checker, _checkCall)); } }; @@ -202,7 +195,7 @@ class Location { template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForLocation( - CheckerManager::CheckLocationFunc(checker, _checkLocation)); + CheckerManager::CheckLocationFunc(checker, _checkLocation)); } }; @@ -217,7 +210,7 @@ class Bind { template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForBind( - CheckerManager::CheckBindFunc(checker, _checkBind)); + CheckerManager::CheckBindFunc(checker, _checkBind)); } }; @@ -231,8 +224,8 @@ class EndAnalysis { public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForEndAnalysis( - CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis)); + mgr._registerForEndAnalysis(CheckerManager::CheckEndAnalysisFunc( + checker, _checkEndAnalysis)); } }; @@ -260,24 +253,23 @@ class EndFunction { public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForEndFunction( - CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction)); + mgr._registerForEndFunction(CheckerManager::CheckEndFunctionFunc( + checker, _checkEndFunction)); } }; class BranchCondition { template static void _checkBranchCondition(void *checker, const Stmt *Condition, - CheckerContext & C) { + CheckerContext &C) { ((const CHECKER *)checker)->checkBranchCondition(Condition, C); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForBranchCondition( - CheckerManager::CheckBranchConditionFunc(checker, - _checkBranchCondition)); + mgr._registerForBranchCondition(CheckerManager::CheckBranchConditionFunc( + checker, _checkBranchCondition)); } }; @@ -291,9 +283,8 @@ class NewAllocator { public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForNewAllocator( - CheckerManager::CheckNewAllocatorFunc(checker, - _checkNewAllocator)); + mgr._registerForNewAllocator(CheckerManager::CheckNewAllocatorFunc( + checker, _checkNewAllocator)); } }; @@ -307,65 +298,58 @@ class LiveSymbols { public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForLiveSymbols( - CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols)); + mgr._registerForLiveSymbols(CheckerManager::CheckLiveSymbolsFunc( + checker, _checkLiveSymbols)); } }; class DeadSymbols { template - static void _checkDeadSymbols(void *checker, - SymbolReaper &SR, CheckerContext &C) { + static void _checkDeadSymbols(void *checker, SymbolReaper &SR, + CheckerContext &C) { ((const CHECKER *)checker)->checkDeadSymbols(SR, C); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForDeadSymbols( - CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols)); + mgr._registerForDeadSymbols(CheckerManager::CheckDeadSymbolsFunc( + checker, _checkDeadSymbols)); } }; class RegionChanges { template static ProgramStateRef - _checkRegionChanges(void *checker, - ProgramStateRef state, + _checkRegionChanges(void *checker, ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef Explicits, ArrayRef Regions, - const LocationContext *LCtx, - const CallEvent *Call) { - return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated, - Explicits, Regions, - LCtx, Call); + const LocationContext *LCtx, const CallEvent *Call) { + return ((const CHECKER *)checker) + ->checkRegionChanges(state, invalidated, Explicits, Regions, LCtx, + Call); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForRegionChanges( - CheckerManager::CheckRegionChangesFunc(checker, - _checkRegionChanges)); + mgr._registerForRegionChanges(CheckerManager::CheckRegionChangesFunc( + checker, _checkRegionChanges)); } }; class PointerEscape { template static ProgramStateRef - _checkPointerEscape(void *Checker, - ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind, - RegionAndSymbolInvalidationTraits *ETraits) { + _checkPointerEscape(void *Checker, ProgramStateRef State, + const InvalidatedSymbols &Escaped, const CallEvent *Call, + PointerEscapeKind Kind, + RegionAndSymbolInvalidationTraits *ETraits) { if (!ETraits) - return ((const CHECKER *)Checker)->checkPointerEscape(State, - Escaped, - Call, - Kind); + return ((const CHECKER *)Checker) + ->checkPointerEscape(State, Escaped, Call, Kind); InvalidatedSymbols RegularEscape; for (SymbolRef Sym : Escaped) @@ -378,30 +362,25 @@ class PointerEscape { if (RegularEscape.empty()) return State; - return ((const CHECKER *)Checker)->checkPointerEscape(State, - RegularEscape, - Call, - Kind); + return ((const CHECKER *)Checker) + ->checkPointerEscape(State, RegularEscape, Call, Kind); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForPointerEscape( - CheckerManager::CheckPointerEscapeFunc(checker, - _checkPointerEscape)); + mgr._registerForPointerEscape(CheckerManager::CheckPointerEscapeFunc( + checker, _checkPointerEscape)); } }; class ConstPointerEscape { template static ProgramStateRef - _checkConstPointerEscape(void *Checker, - ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind, - RegionAndSymbolInvalidationTraits *ETraits) { + _checkConstPointerEscape(void *Checker, ProgramStateRef State, + const InvalidatedSymbols &Escaped, + const CallEvent *Call, PointerEscapeKind Kind, + RegionAndSymbolInvalidationTraits *ETraits) { if (!ETraits) return State; @@ -418,37 +397,33 @@ class ConstPointerEscape { if (ConstEscape.empty()) return State; - return ((const CHECKER *)Checker)->checkConstPointerEscape(State, - ConstEscape, - Call, - Kind); + return ((const CHECKER *)Checker) + ->checkConstPointerEscape(State, ConstEscape, Call, Kind); } public: template static void _register(CHECKER *checker, CheckerManager &mgr) { - mgr._registerForPointerEscape( - CheckerManager::CheckPointerEscapeFunc(checker, - _checkConstPointerEscape)); + mgr._registerForPointerEscape(CheckerManager::CheckPointerEscapeFunc( + checker, _checkConstPointerEscape)); } }; - -template -class Event { +template class Event { template static void _checkEvent(void *checker, const void *event) { ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event); } + public: template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerListenerForEvent( - CheckerManager::CheckEventFunc(checker, _checkEvent)); + CheckerManager::CheckEventFunc(checker, _checkEvent)); } }; -} // end check namespace +} // namespace check namespace eval { @@ -463,7 +438,7 @@ class Assume { template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForEvalAssume( - CheckerManager::EvalAssumeFunc(checker, _evalAssume)); + CheckerManager::EvalAssumeFunc(checker, _evalAssume)); } }; @@ -478,11 +453,11 @@ class Call { template static void _register(CHECKER *checker, CheckerManager &mgr) { mgr._registerForEvalCall( - CheckerManager::EvalCallFunc(checker, _evalCall)); + CheckerManager::EvalCallFunc(checker, _evalCall)); } }; -} // end eval namespace +} // namespace eval class CheckerBase : public ProgramPointTag { CheckerNameRef Name; @@ -494,11 +469,11 @@ class CheckerBase : public ProgramPointTag { /// See CheckerManager::runCheckersForPrintState. virtual void printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep) const { } + const char *NL, const char *Sep) const {} }; /// Dump checker name to stream. -raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker); +raw_ostream &operator<<(raw_ostream &Out, const CheckerBase &Checker); /// Tag that can use a checker name as a message provider /// (see SimpleProgramPointTag). @@ -527,9 +502,9 @@ class Checker : public CHECK1, public CheckerBase { } }; -template -class EventDispatcher { +template class EventDispatcher { CheckerManager *Mgr = nullptr; + public: EventDispatcher() = default; @@ -539,9 +514,7 @@ class EventDispatcher { static_cast *>(checker)->Mgr = &mgr; } - void dispatchEvent(const EVENT &event) const { - Mgr->_dispatchEvent(event); - } + void dispatchEvent(const EVENT &event) const { Mgr->_dispatchEvent(event); } }; /// We dereferenced a location that may be null. @@ -558,8 +531,8 @@ struct ImplicitNullDerefEvent { static int Tag; }; -} // end ento namespace +} // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index a45ba1bc573e1..3e22a3b4ec7d5 100644 --- a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -57,8 +57,7 @@ class SymbolReaper; template class CheckerFn; -template -class CheckerFn { +template class CheckerFn { using Func = RET (*)(void *, Ps...); Func Fn; @@ -68,9 +67,7 @@ class CheckerFn { CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) {} - RET operator()(Ps... ps) const { - return Fn(Checker, ps...); - } + RET operator()(Ps... ps) const { return Fn(Checker, ps...); } }; /// Describes the different reasons a pointer escapes @@ -88,7 +85,6 @@ enum PointerEscapeKind { /// argument to a function. PSK_IndirectEscapeOnCall, - /// Escape for a new symbol that was generated into a region /// that the analyzer cannot follow during a conservative call. PSK_EscapeOutParameters, @@ -117,11 +113,7 @@ class CheckerNameRef { operator StringRef() const { return Name; } }; -enum class ObjCMessageVisitKind { - Pre, - Post, - MessageNil -}; +enum class ObjCMessageVisitKind { Pre, Post, MessageNil }; class CheckerManager { ASTContext *Context = nullptr; @@ -189,11 +181,11 @@ class CheckerManager { using CheckerRef = CheckerBase *; using CheckerTag = const void *; - using CheckerDtor = CheckerFn; + using CheckerDtor = CheckerFn; -//===----------------------------------------------------------------------===// -// Checker registration. -//===----------------------------------------------------------------------===// + //===----------------------------------------------------------------------===// + // Checker registration. + //===----------------------------------------------------------------------===// /// Used to register checkers. /// All arguments are automatically passed through to the checker @@ -201,7 +193,7 @@ class CheckerManager { /// /// \returns a pointer to the checker object. template - CHECKER *registerChecker(AT &&... Args) { + CHECKER *registerChecker(AT &&...Args) { CheckerTag tag = getTag(); CheckerRef &ref = CheckerTags[tag]; assert(!ref && "Checker already registered, use getChecker!"); @@ -214,8 +206,7 @@ class CheckerManager { return checker; } - template - CHECKER *getChecker() { + template CHECKER *getChecker() { CheckerTag tag = getTag(); assert(CheckerTags.count(tag) != 0 && "Requested checker is not registered! Maybe you should add it as a " @@ -223,21 +214,21 @@ class CheckerManager { return static_cast(CheckerTags[tag]); } -//===----------------------------------------------------------------------===// -// Functions for running checkers for AST traversing. -//===----------------------------------------------------------------------===// + //===----------------------------------------------------------------------===// + // Functions for running checkers for AST traversing. + //===----------------------------------------------------------------------===// /// Run checkers handling Decls. - void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, + void runCheckersOnASTDecl(const Decl *D, AnalysisManager &mgr, BugReporter &BR); /// Run checkers handling Decls containing a Stmt body. - void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, + void runCheckersOnASTBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR); -//===----------------------------------------------------------------------===// -// Functions for running checkers for path-sensitive checking. -//===----------------------------------------------------------------------===// + //===----------------------------------------------------------------------===// + // Functions for running checkers for path-sensitive checking. + //===----------------------------------------------------------------------===// /// Run checkers for pre-visiting Stmts. /// @@ -245,10 +236,8 @@ class CheckerManager { /// not include the control flow statements such as IfStmt. /// /// \sa runCheckersForBranchCondition, runCheckersForPostStmt - void runCheckersForPreStmt(ExplodedNodeSet &Dst, - const ExplodedNodeSet &Src, - const Stmt *S, - ExprEngine &Eng) { + void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, + const Stmt *S, ExprEngine &Eng) { runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng); } @@ -258,19 +247,16 @@ class CheckerManager { /// not include the control flow statements such as IfStmt. /// /// \sa runCheckersForBranchCondition, runCheckersForPreStmt - void runCheckersForPostStmt(ExplodedNodeSet &Dst, - const ExplodedNodeSet &Src, - const Stmt *S, - ExprEngine &Eng, + void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, + const Stmt *S, ExprEngine &Eng, bool wasInlined = false) { runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined); } /// Run checkers for visiting Stmts. - void runCheckersForStmt(bool isPreVisit, - ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, - const Stmt *S, ExprEngine &Eng, - bool wasInlined = false); + void runCheckersForStmt(bool isPreVisit, ExplodedNodeSet &Dst, + const ExplodedNodeSet &Src, const Stmt *S, + ExprEngine &Eng, bool wasInlined = false); /// Run checkers for pre-visiting obj-c messages. void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, @@ -283,8 +269,7 @@ class CheckerManager { /// Run checkers for post-visiting obj-c messages. void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, - const ObjCMethodCall &msg, - ExprEngine &Eng, + const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined = false) { runCheckersForObjCMessage(ObjCMessageVisitKind::Post, Dst, Src, msg, Eng, wasInlined); @@ -327,36 +312,26 @@ class CheckerManager { bool wasInlined = false); /// Run checkers for load/store of a location. - void runCheckersForLocation(ExplodedNodeSet &Dst, - const ExplodedNodeSet &Src, - SVal location, - bool isLoad, - const Stmt *NodeEx, - const Stmt *BoundEx, - ExprEngine &Eng); + void runCheckersForLocation(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, + SVal location, bool isLoad, const Stmt *NodeEx, + const Stmt *BoundEx, ExprEngine &Eng); /// Run checkers for binding of a value to a location. - void runCheckersForBind(ExplodedNodeSet &Dst, - const ExplodedNodeSet &Src, - SVal location, SVal val, - const Stmt *S, ExprEngine &Eng, - const ProgramPoint &PP); + void runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, + SVal location, SVal val, const Stmt *S, + ExprEngine &Eng, const ProgramPoint &PP); /// Run checkers for end of analysis. void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng); /// Run checkers on beginning of function. - void runCheckersForBeginFunction(ExplodedNodeSet &Dst, - const BlockEdge &L, - ExplodedNode *Pred, - ExprEngine &Eng); + void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, + ExplodedNode *Pred, ExprEngine &Eng); /// Run checkers on end of function. - void runCheckersForEndFunction(NodeBuilderContext &BC, - ExplodedNodeSet &Dst, - ExplodedNode *Pred, - ExprEngine &Eng, + void runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, + ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS); /// Run checkers for branch condition. @@ -385,8 +360,7 @@ class CheckerManager { void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, - ExprEngine &Eng, - ProgramPoint::Kind K); + ExprEngine &Eng, ProgramPoint::Kind K); /// Run checkers for region changes. /// @@ -399,13 +373,11 @@ class CheckerManager { /// i.e. all regions that may have been touched by this change. /// \param Call The call expression wrapper if the regions are invalidated /// by a call. - ProgramStateRef - runCheckersForRegionChanges(ProgramStateRef state, - const InvalidatedSymbols *invalidated, - ArrayRef ExplicitRegions, - ArrayRef Regions, - const LocationContext *LCtx, - const CallEvent *Call); + ProgramStateRef runCheckersForRegionChanges( + ProgramStateRef state, const InvalidatedSymbols *invalidated, + ArrayRef ExplicitRegions, + ArrayRef Regions, const LocationContext *LCtx, + const CallEvent *Call); /// Run checkers when pointers escape. /// @@ -425,13 +397,12 @@ class CheckerManager { ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind, + const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits); /// Run checkers for handling assumptions on symbolic values. - ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, - SVal Cond, bool Assumption); + ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, + bool Assumption); /// Run checkers for evaluating a call. /// @@ -442,8 +413,7 @@ class CheckerManager { /// Run checkers for the entire Translation Unit. void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, - AnalysisManager &mgr, - BugReporter &BR); + AnalysisManager &mgr, BugReporter &BR); /// Run checkers for debug-printing a ProgramState. /// @@ -468,7 +438,7 @@ class CheckerManager { // these directly. using CheckDeclFunc = - CheckerFn; + CheckerFn; using HandlesDeclFunc = bool (*)(const Decl *D); @@ -476,17 +446,16 @@ class CheckerManager { void _registerForBody(CheckDeclFunc checkfn); -//===----------------------------------------------------------------------===// -// Internal registration functions for path-sensitive checking. -//===----------------------------------------------------------------------===// + //===----------------------------------------------------------------------===// + // Internal registration functions for path-sensitive checking. + //===----------------------------------------------------------------------===// - using CheckStmtFunc = CheckerFn; + using CheckStmtFunc = CheckerFn; using CheckObjCMessageFunc = - CheckerFn; + CheckerFn; - using CheckCallFunc = - CheckerFn; + using CheckCallFunc = CheckerFn; using CheckLocationFunc = CheckerFn; @@ -495,53 +464,46 @@ class CheckerManager { CheckerFn; using CheckEndAnalysisFunc = - CheckerFn; + CheckerFn; - using CheckBeginFunctionFunc = CheckerFn; + using CheckBeginFunctionFunc = CheckerFn; using CheckEndFunctionFunc = - CheckerFn; + CheckerFn; using CheckBranchConditionFunc = - CheckerFn; + CheckerFn; using CheckNewAllocatorFunc = CheckerFn; using CheckDeadSymbolsFunc = - CheckerFn; + CheckerFn; - using CheckLiveSymbolsFunc = CheckerFn; + using CheckLiveSymbolsFunc = CheckerFn; - using CheckRegionChangesFunc = - CheckerFn ExplicitRegions, - ArrayRef Regions, - const LocationContext *LCtx, - const CallEvent *Call)>; + using CheckRegionChangesFunc = CheckerFn ExplicitRegions, + ArrayRef Regions, const LocationContext *LCtx, + const CallEvent *Call)>; - using CheckPointerEscapeFunc = - CheckerFn; + using CheckPointerEscapeFunc = CheckerFn; using EvalAssumeFunc = CheckerFn; - using EvalCallFunc = CheckerFn; + using EvalCallFunc = CheckerFn; - using CheckEndOfTranslationUnit = - CheckerFn; + using CheckEndOfTranslationUnit = CheckerFn; using HandlesStmtFunc = bool (*)(const Stmt *D); - void _registerForPreStmt(CheckStmtFunc checkfn, - HandlesStmtFunc isForStmtFn); - void _registerForPostStmt(CheckStmtFunc checkfn, - HandlesStmtFunc isForStmtFn); + void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn); + void _registerForPostStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn); void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); @@ -580,12 +542,12 @@ class CheckerManager { void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn); -//===----------------------------------------------------------------------===// -// Internal registration functions for events. -//===----------------------------------------------------------------------===// + //===----------------------------------------------------------------------===// + // Internal registration functions for events. + //===----------------------------------------------------------------------===// using EventTag = void *; - using CheckEventFunc = CheckerFn; + using CheckEventFunc = CheckerFn; template void _registerListenerForEvent(CheckEventFunc checkfn) { @@ -593,14 +555,12 @@ class CheckerManager { info.Checkers.push_back(checkfn); } - template - void _registerDispatcherForEvent() { + template void _registerDispatcherForEvent() { EventInfo &info = Events[&EVENT::Tag]; info.HasDispatcher = true; } - template - void _dispatchEvent(const EVENT &event) const { + template void _dispatchEvent(const EVENT &event) const { EventsTy::const_iterator I = Events.find(&EVENT::Tag); if (I == Events.end()) return; @@ -609,16 +569,19 @@ class CheckerManager { Checker(&event); } -//===----------------------------------------------------------------------===// -// Implementation details. -//===----------------------------------------------------------------------===// + //===----------------------------------------------------------------------===// + // Implementation details. + //===----------------------------------------------------------------------===// private: - template - static void destruct(void *obj) { delete static_cast(obj); } + template static void destruct(void *obj) { + delete static_cast(obj); + } - template - static void *getTag() { static int tag; return &tag; } + template static void *getTag() { + static int tag; + return &tag; + } llvm::DenseMap CheckerTags; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h index 2694aac478cd4..05f797a53f2b7 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h @@ -1,4 +1,5 @@ -//===--- PathDiagnosticConsumers.h - Path Diagnostic Clients ------*- C++ -*-===// +//===--- PathDiagnosticConsumers.h - Path Diagnostic Clients ------*- C++ +//-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,7 +31,7 @@ class CrossTranslationUnitContext; namespace ento { class PathDiagnosticConsumer; -typedef std::vector PathDiagnosticConsumers; +typedef std::vector PathDiagnosticConsumers; #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \ void CREATEFN(PathDiagnosticConsumerOptions Diagopts, \ @@ -40,7 +41,7 @@ typedef std::vector PathDiagnosticConsumers; const MacroExpansionContext &MacroExpansions); #include "clang/StaticAnalyzer/Core/Analyses.def" -} // end 'ento' namespace -} // end 'clang' namespace +} // namespace ento +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h index f1c50e721937b..2b3627877c32e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h @@ -25,7 +25,7 @@ class APSIntType { : BitWidth(Width), IsUnsigned(Unsigned) {} /* implicit */ APSIntType(const llvm::APSInt &Value) - : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {} + : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {} uint32_t getBitWidth() const { return BitWidth; } bool isUnsigned() const { return IsUnsigned; } @@ -102,7 +102,7 @@ class APSIntType { } }; -} // end ento namespace -} // end clang namespace +} // namespace ento +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index c76e9c0326afe..344ebae082218 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -26,7 +26,7 @@ namespace clang { class CodeInjector; namespace ento { - class CheckerManager; +class CheckerManager; class AnalysisManager : public BugReporterData { virtual void anchor(); @@ -55,23 +55,17 @@ class AnalysisManager : public BugReporterData { ~AnalysisManager() override; - void ClearContexts() { - AnaCtxMgr.clear(); - } + void ClearContexts() { AnaCtxMgr.clear(); } - AnalysisDeclContextManager& getAnalysisDeclContextManager() { + AnalysisDeclContextManager &getAnalysisDeclContextManager() { return AnaCtxMgr; } Preprocessor &getPreprocessor() override { return PP; } - StoreManagerCreator getStoreManagerCreator() { - return CreateStoreMgr; - } + StoreManagerCreator getStoreManagerCreator() { return CreateStoreMgr; } - AnalyzerOptions& getAnalyzerOptions() override { - return options; - } + AnalyzerOptions &getAnalyzerOptions() override { return options; } ConstraintManagerCreator getConstraintManagerCreator() { return CreateConstraintMgr; @@ -79,19 +73,15 @@ class AnalysisManager : public BugReporterData { CheckerManager *getCheckerManager() const { return CheckerMgr; } - ASTContext &getASTContext() override { - return Ctx; - } + ASTContext &getASTContext() override { return Ctx; } SourceManager &getSourceManager() override { return getASTContext().getSourceManager(); } - const LangOptions &getLangOpts() const { - return LangOpts; - } + const LangOptions &getLangOpts() const { return LangOpts; } - ArrayRef getPathDiagnosticConsumers() override { + ArrayRef getPathDiagnosticConsumers() override { return PathConsumers; } @@ -101,16 +91,11 @@ class AnalysisManager : public BugReporterData { return options.visualizeExplodedGraphWithGraphViz; } - bool shouldInlineCall() const { - return options.getIPAMode() != IPAK_None; - } + bool shouldInlineCall() const { return options.getIPAMode() != IPAK_None; } - CFG *getCFG(Decl const *D) { - return AnaCtxMgr.getContext(D)->getCFG(); - } + CFG *getCFG(Decl const *D) { return AnaCtxMgr.getContext(D)->getCFG(); } - template - T *getAnalysis(Decl const *D) { + template T *getAnalysis(Decl const *D) { return AnaCtxMgr.getContext(D)->getAnalysis(); } @@ -153,8 +138,8 @@ class AnalysisManager : public BugReporterData { } }; -} // enAnaCtxMgrspace +} // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index ec503b41b381a..dfd43a528f028 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -19,9 +19,9 @@ #include "clang/AST/Expr.h" #include "clang/AST/Type.h" #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ImmutableList.h" @@ -53,10 +53,10 @@ class CompoundValData : public llvm::FoldingSetNode { QualType getType() const { return T; } - static void Profile(llvm::FoldingSetNodeID& ID, QualType T, + static void Profile(llvm::FoldingSetNodeID &ID, QualType T, llvm::ImmutableList L); - void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, T, L); } }; class LazyCompoundValData : public llvm::FoldingSetNode { @@ -76,11 +76,10 @@ class LazyCompoundValData : public llvm::FoldingSetNode { LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion *getRegion() const { return region; } - static void Profile(llvm::FoldingSetNodeID& ID, - const StoreRef &store, + static void Profile(llvm::FoldingSetNodeID &ID, const StoreRef &store, const TypedValueRegion *region); - void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, store, region); } }; class PointerToMemberData : public llvm::FoldingSetNode { @@ -115,7 +114,7 @@ class BasicValueFactory { llvm::FoldingSet>; ASTContext &Ctx; - llvm::BumpPtrAllocator& BPAlloc; + llvm::BumpPtrAllocator &BPAlloc; APSIntSetTy APSIntSet; void *PersistentSVals = nullptr; @@ -123,13 +122,13 @@ class BasicValueFactory { llvm::ImmutableList::Factory SValListFactory; llvm::ImmutableList::Factory CXXBaseListFactory; - llvm::FoldingSet CompoundValDataSet; + llvm::FoldingSet CompoundValDataSet; llvm::FoldingSet LazyCompoundValDataSet; llvm::FoldingSet PointerToMemberDataSet; // This is private because external clients should use the factory // method that takes a QualType. - const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned); + const llvm::APSInt &getValue(uint64_t X, unsigned BitWidth, bool isUnsigned); public: BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc) @@ -140,9 +139,9 @@ class BasicValueFactory { ASTContext &getContext() const { return Ctx; } - const llvm::APSInt& getValue(const llvm::APSInt& X); - const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned); - const llvm::APSInt& getValue(uint64_t X, QualType T); + const llvm::APSInt &getValue(const llvm::APSInt &X); + const llvm::APSInt &getValue(const llvm::APInt &X, bool isUnsigned); + const llvm::APSInt &getValue(uint64_t X, QualType T); /// Returns the type of the APSInt used to store values of the given QualType. APSIntType getAPSIntType(QualType T) const { @@ -165,8 +164,8 @@ class BasicValueFactory { /// Convert - Create a new persistent APSInt with the same value as 'From' /// but with the bitwidth and signedness of 'To'. - const llvm::APSInt &Convert(const llvm::APSInt& To, - const llvm::APSInt& From) { + const llvm::APSInt &Convert(const llvm::APSInt &To, + const llvm::APSInt &From) { APSIntType TargetType(To); if (TargetType == APSIntType(From)) return From; @@ -244,8 +243,8 @@ class BasicValueFactory { const CompoundValData *getCompoundValData(QualType T, llvm::ImmutableList Vals); - const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store, - const TypedValueRegion *region); + const LazyCompoundValData * + getLazyCompoundValData(const StoreRef &store, const TypedValueRegion *region); const PointerToMemberData * getPointerToMemberData(const NamedDecl *ND, @@ -263,9 +262,9 @@ class BasicValueFactory { return CXXBaseListFactory.getEmptyList(); } - llvm::ImmutableList prependCXXBase( - const CXXBaseSpecifier *CBS, - llvm::ImmutableList L) { + llvm::ImmutableList + prependCXXBase(const CXXBaseSpecifier *CBS, + llvm::ImmutableList L) { return CXXBaseListFactory.add(CBS, L); } @@ -273,17 +272,17 @@ class BasicValueFactory { accumCXXBase(llvm::iterator_range PathRange, const nonloc::PointerToMember &PTM, const clang::CastKind &kind); - const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op, - const llvm::APSInt& V1, - const llvm::APSInt& V2); + const llvm::APSInt *evalAPSInt(BinaryOperator::Opcode Op, + const llvm::APSInt &V1, + const llvm::APSInt &V2); - const std::pair& - getPersistentSValWithData(const SVal& V, uintptr_t Data); + const std::pair &getPersistentSValWithData(const SVal &V, + uintptr_t Data); - const std::pair& - getPersistentSValPair(const SVal& V1, const SVal& V2); + const std::pair &getPersistentSValPair(const SVal &V1, + const SVal &V2); - const SVal* getPersistentSVal(SVal X); + const SVal *getPersistentSVal(SVal X); }; } // namespace ento diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h index 46ff69e0c3968..7ea9f453fec10 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h @@ -39,21 +39,22 @@ class BlockCounter { class Factory { void *F; + public: - Factory(llvm::BumpPtrAllocator& Alloc); + Factory(llvm::BumpPtrAllocator &Alloc); ~Factory(); BlockCounter GetEmptyCounter(); BlockCounter IncrementCount(BlockCounter BC, - const StackFrameContext *CallSite, - unsigned BlockID); + const StackFrameContext *CallSite, + unsigned BlockID); }; friend class Factory; }; -} // end GR namespace +} // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h index 965838a4408c2..822799dbab3aa 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h @@ -107,7 +107,8 @@ class CallDescription { return CD1.matches(Call); } - /// \copydoc clang::ento::CallDescription::matchesAny(const CallEvent &, const CallDescription &) + /// \copydoc clang::ento::CallDescription::matchesAny(const CallEvent &, const + /// CallDescription &) template friend bool matchesAny(const CallEvent &Call, const CallDescription &CD1, const Ts &...CDs) { @@ -145,7 +146,8 @@ class CallDescription { return CD1.matchesAsWritten(CE); } - /// \copydoc clang::ento::CallDescription::matchesAnyAsWritten(const CallExpr &, const CallDescription &) + /// \copydoc clang::ento::CallDescription::matchesAnyAsWritten(const CallExpr + /// &, const CallDescription &) template friend bool matchesAnyAsWritten(const CallExpr &CE, const CallDescription &CD1, diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index 9923c41e6ad2d..338f3066fcdcb 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -38,32 +38,21 @@ class CheckerContext { /// call was inlined. In all other cases it will be false. const bool wasInlined; - CheckerContext(NodeBuilder &builder, - ExprEngine &eng, - ExplodedNode *pred, - const ProgramPoint &loc, - bool wasInlined = false) - : Eng(eng), - Pred(pred), - Changed(false), - Location(loc), - NB(builder), - wasInlined(wasInlined) { + CheckerContext(NodeBuilder &builder, ExprEngine &eng, ExplodedNode *pred, + const ProgramPoint &loc, bool wasInlined = false) + : Eng(eng), Pred(pred), Changed(false), Location(loc), NB(builder), + wasInlined(wasInlined) { assert(Pred->getState() && "We should not call the checkers on an empty state."); } - AnalysisManager &getAnalysisManager() { - return Eng.getAnalysisManager(); - } + AnalysisManager &getAnalysisManager() { return Eng.getAnalysisManager(); } ConstraintManager &getConstraintManager() { return Eng.getConstraintManager(); } - StoreManager &getStoreManager() { - return Eng.getStoreManager(); - } + StoreManager &getStoreManager() { return Eng.getStoreManager(); } /// Returns the previous node in the exploded graph, which includes /// the state of the program before the checker ran. Note, checkers should @@ -77,13 +66,9 @@ class CheckerContext { /// Returns the number of times the current block has been visited /// along the analyzed path. - unsigned blockCount() const { - return NB.getContext().blockCount(); - } + unsigned blockCount() const { return NB.getContext().blockCount(); } - ASTContext &getASTContext() { - return Eng.getContext(); - } + ASTContext &getASTContext() { return Eng.getContext(); } const ASTContext &getASTContext() const { return Eng.getContext(); } @@ -100,11 +85,9 @@ class CheckerContext { } /// Return true if the current LocationContext has no caller context. - bool inTopFrame() const { return getLocationContext()->inTopFrame(); } + bool inTopFrame() const { return getLocationContext()->inTopFrame(); } - BugReporter &getBugReporter() { - return Eng.getBugReporter(); - } + BugReporter &getBugReporter() { return Eng.getBugReporter(); } const SourceManager &getSourceManager() { return getBugReporter().getSourceManager(); @@ -112,17 +95,13 @@ class CheckerContext { Preprocessor &getPreprocessor() { return getBugReporter().getPreprocessor(); } - SValBuilder &getSValBuilder() { - return Eng.getSValBuilder(); - } + SValBuilder &getSValBuilder() { return Eng.getSValBuilder(); } SymbolManager &getSymbolManager() { return getSValBuilder().getSymbolManager(); } - ProgramStateManager &getStateManager() { - return Eng.getStateManager(); - } + ProgramStateManager &getStateManager() { return Eng.getStateManager(); } AnalysisDeclContext *getCurrentAnalysisDeclContext() const { return Pred->getLocationContext()->getAnalysisDeclContext(); @@ -141,14 +120,12 @@ class CheckerContext { static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) { ProgramPoint L = N->getLocation(); if (std::optional PSL = L.getAs()) - return reinterpret_cast(PSL->getLocationValue()); + return reinterpret_cast(PSL->getLocationValue()); return nullptr; } /// Get the value of arbitrary expressions at this point in the path. - SVal getSVal(const Stmt *S) const { - return Pred->getSVal(S); - } + SVal getSVal(const Stmt *S) const { return Pred->getSVal(S); } /// Returns true if the value of \p E is greater than or equal to \p /// Val under unsigned comparison @@ -208,8 +185,7 @@ class CheckerContext { /// the default tag for the checker will be used. ExplodedNode *generateErrorNode(ProgramStateRef State = nullptr, const ProgramPointTag *Tag = nullptr) { - return generateSink(State, Pred, - (Tag ? Tag : Location.getTag())); + return generateSink(State, Pred, (Tag ? Tag : Location.getTag())); } /// Generate a transition to a node that will be used to report @@ -221,11 +197,9 @@ class CheckerContext { /// to the newly generated node. /// @param Tag The tag to uniquely identify the creation site. If null, /// the default tag for the checker will be used. - ExplodedNode *generateErrorNode(ProgramStateRef State, - ExplodedNode *Pred, + ExplodedNode *generateErrorNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag = nullptr) { - return generateSink(State, Pred, - (Tag ? Tag : Location.getTag())); + return generateSink(State, Pred, (Tag ? Tag : Location.getTag())); } /// Generate a transition to a node that will be used to report @@ -251,8 +225,7 @@ class CheckerContext { /// @param Tag The tag to uniquely identify the creation site. If null, /// the default tag for the checker will be used. ExplodedNode * - generateNonFatalErrorNode(ProgramStateRef State, - ExplodedNode *Pred, + generateNonFatalErrorNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag = nullptr) { return addTransition(State, Pred, (Tag ? Tag : Location.getTag())); } @@ -285,13 +258,12 @@ class CheckerContext { /// @param IsPrunable Whether the note is prunable. It allows BugReporter /// to omit the note from the report if it would make the displayed /// bug path significantly shorter. - const NoteTag - *getNoteTag(std::function &&Cb, - bool IsPrunable = false) { - return getNoteTag( - [Cb](BugReporterContext &, - PathSensitiveBugReport &BR) { return Cb(BR); }, - IsPrunable); + const NoteTag * + getNoteTag(std::function &&Cb, + bool IsPrunable = false) { + return getNoteTag([Cb](BugReporterContext &, + PathSensitiveBugReport &BR) { return Cb(BR); }, + IsPrunable); } /// A shorthand version of getNoteTag that doesn't require you to accept @@ -303,9 +275,9 @@ class CheckerContext { /// bug path significantly shorter. const NoteTag *getNoteTag(std::function &&Cb, bool IsPrunable = false) { - return getNoteTag([Cb](BugReporterContext &, - PathSensitiveBugReport &) { return Cb(); }, - IsPrunable); + return getNoteTag( + [Cb](BugReporterContext &, PathSensitiveBugReport &) { return Cb(); }, + IsPrunable); } /// A shorthand version of getNoteTag that accepts a plain note. @@ -317,7 +289,7 @@ class CheckerContext { const NoteTag *getNoteTag(StringRef Note, bool IsPrunable = false) { return getNoteTag( [Note = std::string(Note)](BugReporterContext &, - PathSensitiveBugReport &) { return Note; }, + PathSensitiveBugReport &) { return Note; }, IsPrunable); } @@ -328,9 +300,9 @@ class CheckerContext { /// @param IsPrunable Whether the note is prunable. It allows BugReporter /// to omit the note from the report if it would make the displayed /// bug path significantly shorter. - const NoteTag *getNoteTag( - std::function &&Cb, - bool IsPrunable = false) { + const NoteTag *getNoteTag(std::function &&Cb, + bool IsPrunable = false) { return getNoteTag( [Cb](PathSensitiveBugReport &BR) -> std::string { llvm::SmallString<128> Str; @@ -391,10 +363,9 @@ class CheckerContext { StringRef getMacroNameOrSpelling(SourceLocation &Loc); private: - ExplodedNode *addTransitionImpl(ProgramStateRef State, - bool MarkAsSink, - ExplodedNode *P = nullptr, - const ProgramPointTag *Tag = nullptr) { + ExplodedNode *addTransitionImpl(ProgramStateRef State, bool MarkAsSink, + ExplodedNode *P = nullptr, + const ProgramPointTag *Tag = nullptr) { // The analyzer may stop exploring if it sees a state it has previously // visited ("cache out"). The early return here is a defensive check to // prevent accidental caching out by checker API clients. Unless there is a @@ -424,8 +395,8 @@ class CheckerContext { } }; -} // end GR namespace +} // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h index 65982457ad839..6abfa58f8cf79 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h @@ -34,7 +34,7 @@ bool containsStaticLocal(const Stmt *S); bool containsBuiltinOffsetOf(const Stmt *S); template bool containsStmt(const Stmt *S) { if (isa(S)) - return true; + return true; for (const Stmt *Child : S->children()) if (Child && containsStmt(Child)) diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h index 4de04bc4d397a..f8f26ae6a731f 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h @@ -48,9 +48,7 @@ class ConditionTruthVal { /// \return Stored value, assuming that the value is known. /// Crashes otherwise. - bool getValue() const { - return *Val; - } + bool getValue() const { return *Val; } /// Return true if the constraint is perfectly constrained to 'true'. bool isConstrainedTrue() const { return Val && *Val; } @@ -105,7 +103,7 @@ class ConstraintManager { /// Note that a ConstraintManager is not obligated to return a concretized /// value for a symbol, even if it is perfectly constrained. /// It might return null. - virtual const llvm::APSInt* getSymVal(ProgramStateRef state, + virtual const llvm::APSInt *getSymVal(ProgramStateRef state, SymbolRef sym) const { return nullptr; } @@ -129,7 +127,7 @@ class ConstraintManager { /// Scan all symbols referenced by the constraints. If the symbol is not /// alive, remove it. virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, - SymbolReaper& SymReaper) = 0; + SymbolReaper &SymReaper) = 0; virtual void printJson(raw_ostream &Out, ProgramStateRef State, const char *NL, unsigned int Space, diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 8dbe767cef9d7..3be961e39b086 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -105,8 +105,7 @@ class CoreEngine { void setBlockCounter(BlockCounter C); - void generateNode(const ProgramPoint &Loc, - ProgramStateRef State, + void generateNode(const ProgramPoint &Loc, ProgramStateRef State, ExplodedNode *Pred); void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred); @@ -134,8 +133,7 @@ class CoreEngine { public: /// Construct a CoreEngine object to analyze the provided CFG. - CoreEngine(ExprEngine &exprengine, - FunctionSummariesTy *FS, + CoreEngine(ExprEngine &exprengine, FunctionSummariesTy *FS, AnalyzerOptions &Opts); CoreEngine(const CoreEngine &) = delete; @@ -150,22 +148,21 @@ class CoreEngine { ProgramStateRef InitState); /// Returns true if there is still simulation state on the worklist. - bool ExecuteWorkListWithInitialState(const LocationContext *L, - unsigned Steps, + bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, ProgramStateRef InitState, ExplodedNodeSet &Dst); /// Dispatch the work list item based on the given location information. /// Use Pred parameter as the predecessor state. - void dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc, - const WorkListUnit& WU); + void dispatchWorkItem(ExplodedNode *Pred, ProgramPoint Loc, + const WorkListUnit &WU); // Functions for external checking of whether we have unfinished work bool wasBlockAborted() const { return !blocksAborted.empty(); } bool wasBlocksExhausted() const { return !blocksExhausted.empty(); } - bool hasWorkRemaining() const { return wasBlocksExhausted() || - WList->hasWork() || - wasBlockAborted(); } + bool hasWorkRemaining() const { + return wasBlocksExhausted() || WList->hasWork() || wasBlockAborted(); + } /// Inform the CoreEngine that a basic block was aborted because /// it could not be completely analyzed. @@ -220,9 +217,8 @@ struct NodeBuilderContext { /// Returns the number of times the current basic block has been /// visited on the exploded graph path. unsigned blockCount() const { - return Eng.WList->getBlockCounter().getNumVisited( - LC->getStackFrame(), - Block->getBlockID()); + return Eng.WList->getBlockCounter().getNumVisited(LC->getStackFrame(), + Block->getBlockID()); } }; @@ -252,12 +248,10 @@ class NodeBuilder { ExplodedNodeSet &Frontier; /// Checks if the results are ready. - virtual bool checkResults() { - return Finalized; - } + virtual bool checkResults() { return Finalized; } bool hasNoSinksInFrontier() { - for (const auto I : Frontier) + for (const auto I : Frontier) if (I->isSink()) return false; return true; @@ -266,10 +260,8 @@ class NodeBuilder { /// Allow subclasses to finalize results before result_begin() is executed. virtual void finalizeResults() {} - ExplodedNode *generateNodeImpl(const ProgramPoint &PP, - ProgramStateRef State, - ExplodedNode *Pred, - bool MarkAsSink = false); + ExplodedNode *generateNodeImpl(const ProgramPoint &PP, ProgramStateRef State, + ExplodedNode *Pred, bool MarkAsSink = false); public: NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, @@ -288,8 +280,7 @@ class NodeBuilder { virtual ~NodeBuilder() = default; /// Generates a node in the ExplodedGraph. - ExplodedNode *generateNode(const ProgramPoint &PP, - ProgramStateRef State, + ExplodedNode *generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred) { return generateNodeImpl( PP, State, Pred, @@ -301,8 +292,7 @@ class NodeBuilder { /// When a node is marked as sink, the exploration from the node is stopped - /// the node becomes the last node on the path and certain kinds of bugs are /// suppressed. - ExplodedNode *generateSink(const ProgramPoint &PP, - ProgramStateRef State, + ExplodedNode *generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred) { return generateNodeImpl(PP, State, Pred, true); } @@ -342,11 +332,11 @@ class NodeBuilder { /// \class NodeBuilderWithSinks /// This node builder keeps track of the generated sink nodes. -class NodeBuilderWithSinks: public NodeBuilder { +class NodeBuilderWithSinks : public NodeBuilder { void anchor() override; protected: - SmallVector sinksGenerated; + SmallVector sinksGenerated; ProgramPoint &Location; public: @@ -354,8 +344,7 @@ class NodeBuilderWithSinks: public NodeBuilder { const NodeBuilderContext &Ctx, ProgramPoint &L) : NodeBuilder(Pred, DstSet, Ctx), Location(L) {} - ExplodedNode *generateNode(ProgramStateRef State, - ExplodedNode *Pred, + ExplodedNode *generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag = nullptr) { const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location); return NodeBuilder::generateNode(LocalLoc, State, Pred); @@ -370,7 +359,7 @@ class NodeBuilderWithSinks: public NodeBuilder { return N; } - const SmallVectorImpl &getSinks() const { + const SmallVectorImpl &getSinks() const { return sinksGenerated; } }; @@ -379,7 +368,7 @@ class NodeBuilderWithSinks: public NodeBuilder { /// This builder class is useful for generating nodes that resulted from /// visiting a statement. The main difference from its parent NodeBuilder is /// that it creates a statement specific ProgramPoint. -class StmtNodeBuilder: public NodeBuilder { +class StmtNodeBuilder : public NodeBuilder { NodeBuilder *EnclosingBldr; public: @@ -408,30 +397,28 @@ class StmtNodeBuilder: public NodeBuilder { using NodeBuilder::generateNode; using NodeBuilder::generateSink; - ExplodedNode *generateNode(const Stmt *S, - ExplodedNode *Pred, - ProgramStateRef St, - const ProgramPointTag *tag = nullptr, - ProgramPoint::Kind K = ProgramPoint::PostStmtKind){ - const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, - Pred->getLocationContext(), tag); + ExplodedNode * + generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, + const ProgramPointTag *tag = nullptr, + ProgramPoint::Kind K = ProgramPoint::PostStmtKind) { + const ProgramPoint &L = + ProgramPoint::getProgramPoint(S, K, Pred->getLocationContext(), tag); return NodeBuilder::generateNode(L, St, Pred); } - ExplodedNode *generateSink(const Stmt *S, - ExplodedNode *Pred, - ProgramStateRef St, - const ProgramPointTag *tag = nullptr, - ProgramPoint::Kind K = ProgramPoint::PostStmtKind){ - const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, - Pred->getLocationContext(), tag); + ExplodedNode * + generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, + const ProgramPointTag *tag = nullptr, + ProgramPoint::Kind K = ProgramPoint::PostStmtKind) { + const ProgramPoint &L = + ProgramPoint::getProgramPoint(S, K, Pred->getLocationContext(), tag); return NodeBuilder::generateSink(L, St, Pred); } }; /// BranchNodeBuilder is responsible for constructing the nodes /// corresponding to the two branches of the if statement - true and false. -class BranchNodeBuilder: public NodeBuilder { +class BranchNodeBuilder : public NodeBuilder { const CFGBlock *DstT; const CFGBlock *DstF; @@ -442,8 +429,8 @@ class BranchNodeBuilder: public NodeBuilder { public: BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, - const NodeBuilderContext &C, - const CFGBlock *dstT, const CFGBlock *dstF) + const NodeBuilderContext &C, const CFGBlock *dstT, + const CFGBlock *dstF) : NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF), InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) { // The branch node builder does not generate autotransitions. @@ -452,8 +439,8 @@ class BranchNodeBuilder: public NodeBuilder { } BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, - const NodeBuilderContext &C, - const CFGBlock *dstT, const CFGBlock *dstF) + const NodeBuilderContext &C, const CFGBlock *dstT, + const CFGBlock *dstF) : NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF), InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) { takeNodes(SrcSet); @@ -479,7 +466,7 @@ class BranchNodeBuilder: public NodeBuilder { }; class IndirectGotoNodeBuilder { - CoreEngine& Eng; + CoreEngine &Eng; const CFGBlock *Src; const CFGBlock &DispatchBlock; const Expr *E; @@ -487,7 +474,8 @@ class IndirectGotoNodeBuilder { public: IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src, - const Expr *e, const CFGBlock *dispatch, CoreEngine* eng) + const Expr *e, const CFGBlock *dispatch, + CoreEngine *eng) : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {} class iterator { @@ -503,23 +491,23 @@ class IndirectGotoNodeBuilder { // loops work. const iterator &operator*() const { return *this; } - iterator &operator++() { ++I; return *this; } + iterator &operator++() { + ++I; + return *this; + } bool operator!=(const iterator &X) const { return I != X.I; } const LabelDecl *getLabel() const { return cast((*I)->getLabel())->getDecl(); } - const CFGBlock *getBlock() const { - return *I; - } + const CFGBlock *getBlock() const { return *I; } }; iterator begin() { return iterator(DispatchBlock.succ_begin()); } iterator end() { return iterator(DispatchBlock.succ_end()); } - ExplodedNode *generateNode(const iterator &I, - ProgramStateRef State, + ExplodedNode *generateNode(const iterator &I, ProgramStateRef State, bool isSink = false); const Expr *getTarget() const { return E; } @@ -532,14 +520,14 @@ class IndirectGotoNodeBuilder { }; class SwitchNodeBuilder { - CoreEngine& Eng; + CoreEngine &Eng; const CFGBlock *Src; const Expr *Condition; ExplodedNode *Pred; public: SwitchNodeBuilder(ExplodedNode *pred, const CFGBlock *src, - const Expr *condition, CoreEngine* eng) + const Expr *condition, CoreEngine *eng) : Eng(*eng), Src(src), Condition(condition), Pred(pred) {} class iterator { @@ -550,28 +538,26 @@ class SwitchNodeBuilder { iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {} public: - iterator &operator++() { ++I; return *this; } + iterator &operator++() { + ++I; + return *this; + } bool operator!=(const iterator &X) const { return I != X.I; } bool operator==(const iterator &X) const { return I == X.I; } - const CaseStmt *getCase() const { - return cast((*I)->getLabel()); - } + const CaseStmt *getCase() const { return cast((*I)->getLabel()); } - const CFGBlock *getBlock() const { - return *I; - } + const CFGBlock *getBlock() const { return *I; } }; - iterator begin() { return iterator(Src->succ_rbegin()+1); } + iterator begin() { return iterator(Src->succ_rbegin() + 1); } iterator end() { return iterator(Src->succ_rend()); } const SwitchStmt *getSwitch() const { return cast(Src->getTerminator()); } - ExplodedNode *generateCaseStmtNode(const iterator &I, - ProgramStateRef State); + ExplodedNode *generateCaseStmtNode(const iterator &I, ProgramStateRef State); ExplodedNode *generateDefaultCaseNode(ProgramStateRef State, bool isSink = false); diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h index 498e36e1431fa..78ab7231ad133 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h @@ -32,8 +32,8 @@ class SymbolReaper; /// This allows the environment to manage context-sensitive bindings, /// which is essentially for modeling recursive function analysis, among /// other things. -class EnvironmentEntry : public std::pair { +class EnvironmentEntry + : public std::pair { public: EnvironmentEntry(const Stmt *s, const LocationContext *L); @@ -41,15 +41,12 @@ class EnvironmentEntry : public std::pairExprBindings.Profile(ID); } /// Profile - Used to profile the contents of this object for inclusion /// in a FoldingSet. - void Profile(llvm::FoldingSetNodeID& ID) const { - Profile(ID, this); - } + void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, this); } - bool operator==(const Environment& RHS) const { + bool operator==(const Environment &RHS) const { return ExprBindings == RHS.ExprBindings; } @@ -105,16 +100,13 @@ class EnvironmentManager { public: EnvironmentManager(llvm::BumpPtrAllocator &Allocator) : F(Allocator) {} - Environment getInitialEnvironment() { - return Environment(F.getEmptyMap()); - } + Environment getInitialEnvironment() { return Environment(F.getEmptyMap()); } /// Bind a symbolic value to the given environment entry. Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, bool Invalidate); - Environment removeDeadBindings(Environment Env, - SymbolReaper &SymReaper, + Environment removeDeadBindings(Environment Env, SymbolReaper &SymReaper, ProgramStateRef state); }; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index 2fb05ac46e8fa..57434f31f1f9d 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -89,13 +89,11 @@ class ExplodedNode : public llvm::FoldingSetNode { uintptr_t P; public: - NodeGroup(bool Flag = false) : P(Flag) { - assert(getFlag() == Flag); - } + NodeGroup(bool Flag = false) : P(Flag) { assert(getFlag() == Flag); } - ExplodedNode * const *begin() const; + ExplodedNode *const *begin() const; - ExplodedNode * const *end() const; + ExplodedNode *const *end() const; unsigned size() const; @@ -114,9 +112,7 @@ class ExplodedNode : public llvm::FoldingSetNode { void replaceNode(ExplodedNode *node); /// Returns whether this group was created with its flag set. - bool getFlag() const { - return (P & 1); - } + bool getFlag() const { return (P & 1); } }; /// Location - The program location (within a function body) associated @@ -177,16 +173,14 @@ class ExplodedNode : public llvm::FoldingSetNode { return getState()->getSVal(S, getLocationContext()); } - static void Profile(llvm::FoldingSetNodeID &ID, - const ProgramPoint &Loc, - const ProgramStateRef &state, - bool IsSink) { + static void Profile(llvm::FoldingSetNodeID &ID, const ProgramPoint &Loc, + const ProgramStateRef &state, bool IsSink) { ID.Add(Loc); ID.AddPointer(state.get()); ID.AddBoolean(IsSink); } - void Profile(llvm::FoldingSetNodeID& ID) const { + void Profile(llvm::FoldingSetNodeID &ID) const { // We avoid copy constructors by not using accessors. Profile(ID, Location, State, isSink()); } @@ -202,16 +196,14 @@ class ExplodedNode : public llvm::FoldingSetNode { bool isSink() const { return Succs.getFlag(); } - bool hasSinglePred() const { - return (pred_size() == 1); - } + bool hasSinglePred() const { return (pred_size() == 1); } ExplodedNode *getFirstPred() { return pred_empty() ? nullptr : *(pred_begin()); } const ExplodedNode *getFirstPred() const { - return const_cast(this)->getFirstPred(); + return const_cast(this)->getFirstPred(); } ExplodedNode *getFirstSucc() { @@ -219,20 +211,20 @@ class ExplodedNode : public llvm::FoldingSetNode { } const ExplodedNode *getFirstSucc() const { - return const_cast(this)->getFirstSucc(); + return const_cast(this)->getFirstSucc(); } // Iterators over successor and predecessor vertices. - using succ_iterator = ExplodedNode * const *; + using succ_iterator = ExplodedNode *const *; using succ_range = llvm::iterator_range; - using const_succ_iterator = const ExplodedNode * const *; + using const_succ_iterator = const ExplodedNode *const *; using const_succ_range = llvm::iterator_range; - using pred_iterator = ExplodedNode * const *; + using pred_iterator = ExplodedNode *const *; using pred_range = llvm::iterator_range; - using const_pred_iterator = const ExplodedNode * const *; + using const_pred_iterator = const ExplodedNode *const *; using const_pred_range = llvm::iterator_range; pred_iterator pred_begin() { return Preds.begin(); } @@ -240,10 +232,10 @@ class ExplodedNode : public llvm::FoldingSetNode { pred_range preds() { return {Preds.begin(), Preds.end()}; } const_pred_iterator pred_begin() const { - return const_cast(this)->pred_begin(); + return const_cast(this)->pred_begin(); } const_pred_iterator pred_end() const { - return const_cast(this)->pred_end(); + return const_cast(this)->pred_end(); } const_pred_range preds() const { return {Preds.begin(), Preds.end()}; } @@ -252,10 +244,10 @@ class ExplodedNode : public llvm::FoldingSetNode { succ_range succs() { return {Succs.begin(), Succs.end()}; } const_succ_iterator succ_begin() const { - return const_cast(this)->succ_begin(); + return const_cast(this)->succ_begin(); } const_succ_iterator succ_end() const { - return const_cast(this)->succ_end(); + return const_cast(this)->succ_end(); } const_succ_range succs() const { return {Succs.begin(), Succs.end()}; } @@ -350,17 +342,14 @@ class ExplodedGraph { /// this pair exists, it is created. IsNew is set to true if /// the node was freshly created. ExplodedNode *getNode(const ProgramPoint &L, ProgramStateRef State, - bool IsSink = false, - bool* IsNew = nullptr); + bool IsSink = false, bool *IsNew = nullptr); /// Create a node for a (Location, State) pair, /// but don't store it for deduplication later. This /// is useful when copying an already completed /// ExplodedGraph for further processing. - ExplodedNode *createUncachedNode(const ProgramPoint &L, - ProgramStateRef State, - int64_t Id, - bool IsSink = false); + ExplodedNode *createUncachedNode(const ProgramPoint &L, ProgramStateRef State, + int64_t Id, bool IsSink = false); std::unique_ptr MakeEmptyGraph() const { return std::make_unique(); @@ -416,7 +405,7 @@ class ExplodedGraph { const_eop_iterator eop_end() const { return EndNodes.end(); } - llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); } + llvm::BumpPtrAllocator &getAllocator() { return BVC.getAllocator(); } BumpVectorContext &getNodeAllocator() { return BVC; } using NodeMap = llvm::DenseMap; @@ -461,21 +450,22 @@ class ExplodedNodeSet { public: ExplodedNodeSet(ExplodedNode *N) { - assert(N && !static_cast(N)->isSink()); + assert(N && !static_cast(N)->isSink()); Impl.insert(N); } ExplodedNodeSet() = default; void Add(ExplodedNode *N) { - if (N && !static_cast(N)->isSink()) Impl.insert(N); + if (N && !static_cast(N)->isSink()) + Impl.insert(N); } using iterator = ImplTy::iterator; using const_iterator = ImplTy::const_iterator; - unsigned size() const { return Impl.size(); } - bool empty() const { return Impl.empty(); } + unsigned size() const { return Impl.size(); } + bool empty() const { return Impl.empty(); } bool erase(ExplodedNode *N) { return Impl.remove(N); } void clear() { Impl.clear(); } @@ -502,40 +492,34 @@ class ExplodedNodeSet { // GraphTraits namespace llvm { - template <> struct GraphTraits { - using GraphTy = clang::ento::ExplodedGraph *; - using NodeRef = clang::ento::ExplodedNode *; - using ChildIteratorType = clang::ento::ExplodedNode::succ_iterator; - using nodes_iterator = llvm::df_iterator; - - static NodeRef getEntryNode(const GraphTy G) { - return *G->roots_begin(); - } - - static bool predecessorOfTrivial(NodeRef N) { - return N->succ_size() == 1 && N->getFirstSucc()->isTrivial(); - } - - static ChildIteratorType child_begin(NodeRef N) { - if (predecessorOfTrivial(N)) - return child_begin(*N->succ_begin()); - return N->succ_begin(); - } - - static ChildIteratorType child_end(NodeRef N) { - if (predecessorOfTrivial(N)) - return child_end(N->getFirstSucc()); - return N->succ_end(); - } - - static nodes_iterator nodes_begin(const GraphTy G) { - return df_begin(G); - } - - static nodes_iterator nodes_end(const GraphTy G) { - return df_end(G); - } - }; +template <> struct GraphTraits { + using GraphTy = clang::ento::ExplodedGraph *; + using NodeRef = clang::ento::ExplodedNode *; + using ChildIteratorType = clang::ento::ExplodedNode::succ_iterator; + using nodes_iterator = llvm::df_iterator; + + static NodeRef getEntryNode(const GraphTy G) { return *G->roots_begin(); } + + static bool predecessorOfTrivial(NodeRef N) { + return N->succ_size() == 1 && N->getFirstSucc()->isTrivial(); + } + + static ChildIteratorType child_begin(NodeRef N) { + if (predecessorOfTrivial(N)) + return child_begin(*N->succ_begin()); + return N->succ_begin(); + } + + static ChildIteratorType child_end(NodeRef N) { + if (predecessorOfTrivial(N)) + return child_end(N->getFirstSucc()); + return N->succ_end(); + } + + static nodes_iterator nodes_begin(const GraphTy G) { return df_begin(G); } + + static nodes_iterator nodes_end(const GraphTy G) { return df_end(G); } +}; } // namespace llvm #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index ed5c4adb5e3d5..48d76e64171bd 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -21,18 +21,18 @@ #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" #include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/LLVM.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" #include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h" #include "llvm/ADT/ArrayRef.h" #include @@ -180,8 +180,8 @@ class ExprEngine { public: ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr, - SetOfConstDecls *VisitedCalleesIn, - FunctionSummariesTy *FS, InliningModes HowToInlineIn); + SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, + InliningModes HowToInlineIn); virtual ~ExprEngine() = default; @@ -217,8 +217,7 @@ class ExprEngine { BugReporter &getBugReporter() { return BR; } - cross_tu::CrossTranslationUnitContext * - getCrossTranslationUnitContext() { + cross_tu::CrossTranslationUnitContext *getCrossTranslationUnitContext() { return &CTU; } @@ -242,7 +241,7 @@ class ExprEngine { /// Dump graph to the specified filename. /// If filename is empty, generate a temporary one. /// \return The filename the graph is written into. - std::string DumpGraph(bool trim = false, StringRef Filename=""); + std::string DumpGraph(bool trim = false, StringRef Filename = ""); /// Dump the graph consisting of the given nodes to a specified filename. /// Generate a temporary filename if it's not provided. @@ -289,10 +288,11 @@ class ExprEngine { /// \p ReferenceStmt must either be a ReturnStmt or \c NULL. Otherwise, /// it must be ProgramPoint::PreStmtPurgeDeadSymbolsKind (the default) /// and \p ReferenceStmt must be valid (non-null). - void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, - const Stmt *ReferenceStmt, const LocationContext *LC, - const Stmt *DiagnosticStmt = nullptr, - ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind); + void + removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, + const Stmt *ReferenceStmt, const LocationContext *LC, + const Stmt *DiagnosticStmt = nullptr, + ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind); /// processCFGElement - Called by CoreEngine. Used to generate new successor /// nodes by processing the 'effects' of a CFG element. @@ -301,7 +301,7 @@ class ExprEngine { void ProcessStmt(const Stmt *S, ExplodedNode *Pred); - void ProcessLoopExit(const Stmt* S, ExplodedNode *Pred); + void ProcessLoopExit(const Stmt *S, ExplodedNode *Pred); void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred); @@ -309,16 +309,16 @@ class ExprEngine { void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred); - void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, - ExplodedNode *Pred, ExplodedNodeSet &Dst); - void ProcessDeleteDtor(const CFGDeleteDtor D, - ExplodedNode *Pred, ExplodedNodeSet &Dst); - void ProcessBaseDtor(const CFGBaseDtor D, - ExplodedNode *Pred, ExplodedNodeSet &Dst); - void ProcessMemberDtor(const CFGMemberDtor D, - ExplodedNode *Pred, ExplodedNodeSet &Dst); - void ProcessTemporaryDtor(const CFGTemporaryDtor D, - ExplodedNode *Pred, ExplodedNodeSet &Dst); + void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, + ExplodedNodeSet &Dst); + void ProcessDeleteDtor(const CFGDeleteDtor D, ExplodedNode *Pred, + ExplodedNodeSet &Dst); + void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, + ExplodedNodeSet &Dst); + void ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, + ExplodedNodeSet &Dst); + void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// Called by CoreEngine when processing the entrance of a CFGBlock. void processCFGBlockEntrance(const BlockEdge &L, @@ -327,12 +327,9 @@ class ExprEngine { /// ProcessBranch - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a branch condition. - void processBranch(const Stmt *Condition, - NodeBuilderContext& BuilderCtx, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, - const CFGBlock *DstT, - const CFGBlock *DstF); + void processBranch(const Stmt *Condition, NodeBuilderContext &BuilderCtx, + ExplodedNode *Pred, ExplodedNodeSet &Dst, + const CFGBlock *DstT, const CFGBlock *DstF); /// Called by CoreEngine. /// Used to generate successor nodes for temporary destructors depending @@ -346,39 +343,34 @@ class ExprEngine { /// Called by CoreEngine. Used to processing branching behavior /// at static initializers. void processStaticInitializer(const DeclStmt *DS, - NodeBuilderContext& BuilderCtx, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, - const CFGBlock *DstT, - const CFGBlock *DstF); + NodeBuilderContext &BuilderCtx, + ExplodedNode *Pred, ExplodedNodeSet &Dst, + const CFGBlock *DstT, const CFGBlock *DstF); /// processIndirectGoto - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a computed goto jump. - void processIndirectGoto(IndirectGotoNodeBuilder& builder); + void processIndirectGoto(IndirectGotoNodeBuilder &builder); /// ProcessSwitch - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a switch statement. - void processSwitch(SwitchNodeBuilder& builder); + void processSwitch(SwitchNodeBuilder &builder); /// Called by CoreEngine. Used to notify checkers that processing a /// function has begun. Called for both inlined and top-level functions. - void processBeginOfFunction(NodeBuilderContext &BC, - ExplodedNode *Pred, ExplodedNodeSet &Dst, - const BlockEdge &L); + void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, + ExplodedNodeSet &Dst, const BlockEdge &L); /// Called by CoreEngine. Used to notify checkers that processing a /// function has ended. Called for both inlined and top-level functions. - void processEndOfFunction(NodeBuilderContext& BC, - ExplodedNode *Pred, + void processEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, const ReturnStmt *RS = nullptr); /// Remove dead bindings/symbols before exiting a function. - void removeDeadOnEndOfFunction(NodeBuilderContext& BC, - ExplodedNode *Pred, + void removeDeadOnEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// Generate the entry node of the callee. - void processCallEnter(NodeBuilderContext& BC, CallEnter CE, + void processCallEnter(NodeBuilderContext &BC, CallEnter CE, ExplodedNode *Pred); /// Generate the sequence of nodes that simulate the call exit and the post @@ -393,20 +385,19 @@ class ExprEngine { ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption); - /// processRegionChanges - Called by ProgramStateManager whenever a change is made + /// processRegionChanges - Called by ProgramStateManager whenever a change is + /// made /// to the store. Used to update checkers that track region values. ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef ExplicitRegions, ArrayRef Regions, - const LocationContext *LCtx, - const CallEvent *Call); + const LocationContext *LCtx, const CallEvent *Call); - inline ProgramStateRef - processRegionChange(ProgramStateRef state, - const MemRegion* MR, - const LocationContext *LCtx) { + inline ProgramStateRef processRegionChange(ProgramStateRef state, + const MemRegion *MR, + const LocationContext *LCtx) { return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr); } @@ -424,9 +415,7 @@ class ExprEngine { } // FIXME: Remove when we migrate over to just using SValBuilder. - BasicValueFactory &getBasicVals() { - return StateMgr.getBasicVals(); - } + BasicValueFactory &getBasicVals() { return StateMgr.getBasicVals(); } SymbolManager &getSymbolManager() { return SymMgr; } MemRegionManager &getRegionManager() { return MRMgr; } @@ -450,8 +439,7 @@ class ExprEngine { ExplodedNodeSet &Dst); /// VisitArraySubscriptExpr - Transfer function for array accesses. - void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex, - ExplodedNode *Pred, + void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitGCCAsmStmt - Transfer function logic for inline asm. @@ -471,10 +459,9 @@ class ExprEngine { ExplodedNodeSet &Dst); /// VisitBinaryOperator - Transfer function logic for binary operators. - void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, + void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst); - /// VisitCall - Transfer function for function calls. void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst); @@ -503,7 +490,7 @@ class ExprEngine { ExplodedNodeSet &Dst); /// VisitLogicalExpr - Transfer function logic for '&&', '||' - void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, + void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitMemberExpr - Transfer function for member expressions. @@ -543,11 +530,11 @@ class ExprEngine { ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitUnaryOperator - Transfer function logic for unary operators. - void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, + void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// Handle ++ and -- (both pre- and post-increment). - void VisitIncrementDecrementOperator(const UnaryOperator* U, + void VisitIncrementDecrementOperator(const UnaryOperator *U, ExplodedNode *Pred, ExplodedNodeSet &Dst); @@ -559,7 +546,7 @@ class ExprEngine { ExplodedNodeSet &Dst); void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, - ExplodedNodeSet & Dst); + ExplodedNodeSet &Dst); void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst); @@ -568,12 +555,10 @@ class ExprEngine { ExplodedNode *Pred, ExplodedNodeSet &Dst); void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, - const Stmt *S, bool IsBaseDtor, - ExplodedNode *Pred, ExplodedNodeSet &Dst, - EvalCallOptions &Options); + const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, + ExplodedNodeSet &Dst, EvalCallOptions &Options); - void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, - ExplodedNode *Pred, + void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst); void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, @@ -584,17 +569,17 @@ class ExprEngine { /// Create a C++ temporary object for an rvalue. void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, - ExplodedNode *Pred, - ExplodedNodeSet &Dst); + ExplodedNode *Pred, ExplodedNodeSet &Dst); - /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic + /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly + /// assume symbolic /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) /// with those assumptions. - void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, - const Expr *Ex); + void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, + ExplodedNodeSet &Src, const Expr *Ex); static std::pair - geteagerlyAssumeBinOpBifurcationTags(); + geteagerlyAssumeBinOpBifurcationTags(); ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex, const LocationContext *LCtx, QualType T, @@ -606,8 +591,8 @@ class ExprEngine { StmtNodeBuilder &Bldr); public: - SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, - SVal LHS, SVal RHS, QualType T) { + SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, SVal LHS, + SVal RHS, QualType T) { return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T); } @@ -635,20 +620,19 @@ class ExprEngine { const LocationContext *LC); /// Call PointerEscape callback when a value escapes as a result of bind. - ProgramStateRef processPointerEscapedOnBind( - ProgramStateRef State, ArrayRef> LocAndVals, - const LocationContext *LCtx, PointerEscapeKind Kind, - const CallEvent *Call); + ProgramStateRef + processPointerEscapedOnBind(ProgramStateRef State, + ArrayRef> LocAndVals, + const LocationContext *LCtx, + PointerEscapeKind Kind, const CallEvent *Call); /// Call PointerEscape callback when a value escapes as a result of /// region invalidation. /// \param[in] ITraits Specifies invalidation traits for regions/symbols. ProgramStateRef notifyCheckersOfPointerEscape( - ProgramStateRef State, - const InvalidatedSymbols *Invalidated, - ArrayRef ExplicitRegions, - const CallEvent *Call, - RegionAndSymbolInvalidationTraits &ITraits); + ProgramStateRef State, const InvalidatedSymbols *Invalidated, + ArrayRef ExplicitRegions, const CallEvent *Call, + RegionAndSymbolInvalidationTraits &ITraits); private: /// evalBind - Handle the semantics of binding a value to a specific location. @@ -657,10 +641,9 @@ class ExprEngine { SVal location, SVal Val, bool atDeclInit = false, const ProgramPoint *PP = nullptr); - ProgramStateRef - processPointerEscapedOnBind(ProgramStateRef State, - SVal Loc, SVal Val, - const LocationContext *LCtx); + ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, + SVal Val, + const LocationContext *LCtx); /// A simple wrapper when you only need to notify checkers of pointer-escape /// of some values. @@ -676,19 +659,16 @@ class ExprEngine { // same as state->getLValue(Ex). /// Simulate a read of the result of Ex. void evalLoad(ExplodedNodeSet &Dst, - const Expr *NodeEx, /* Eventually will be a CFGStmt */ - const Expr *BoundExpr, - ExplodedNode *Pred, - ProgramStateRef St, - SVal location, - const ProgramPointTag *tag = nullptr, + const Expr *NodeEx, /* Eventually will be a CFGStmt */ + const Expr *BoundExpr, ExplodedNode *Pred, ProgramStateRef St, + SVal location, const ProgramPointTag *tag = nullptr, QualType LoadTy = QualType()); // FIXME: 'tag' should be removed, and a LocationContext should be used // instead. void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, - ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, - const ProgramPointTag *tag = nullptr); + ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, + SVal Val, const ProgramPointTag *tag = nullptr); /// Return the CFG element corresponding to the worklist element /// that is currently being processed by ExprEngine. @@ -763,11 +743,8 @@ class ExprEngine { void evalLocation(ExplodedNodeSet &Dst, const Stmt *NodeEx, /* This will eventually be a CFGStmt */ - const Stmt *BoundEx, - ExplodedNode *Pred, - ProgramStateRef St, - SVal location, - bool isLoad); + const Stmt *BoundEx, ExplodedNode *Pred, ProgramStateRef St, + SVal location, bool isLoad); /// Count the stack depth and determine if the call is recursive. void examineStackFrames(const Decl *D, const LocationContext *LCtx, @@ -858,9 +835,8 @@ class ExprEngine { /// Either inline or process the call conservatively (or both), based /// on DynamicDispatchBifurcation data. - void BifurcateCall(const MemRegion *BifurReg, - const CallEvent &Call, const Decl *D, NodeBuilder &Bldr, - ExplodedNode *Pred); + void BifurcateCall(const MemRegion *BifurReg, const CallEvent &Call, + const Decl *D, NodeBuilder &Bldr, ExplodedNode *Pred); bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC); @@ -1006,10 +982,10 @@ class ExprEngine { /// The GDM stores the corresponding CallExpr pointer. // FIXME: This does not use the nice trait macros because it must be accessible // from multiple translation units. -struct ReplayWithoutInlining{}; +struct ReplayWithoutInlining {}; template <> -struct ProgramStateTrait : - public ProgramStatePartialTrait { +struct ProgramStateTrait + : public ProgramStatePartialTrait { static void *GDMIndex(); }; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h index 3ee0d229cfc29..dc6d969f41c8c 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h @@ -49,8 +49,8 @@ class FunctionSummariesTy { unsigned TimesInlined : 32; FunctionSummary() - : TotalBasicBlocks(0), InlineChecked(0), MayInline(0), - TimesInlined(0) {} + : TotalBasicBlocks(0), InlineChecked(0), MayInline(0), TimesInlined(0) { + } }; using MapTy = llvm::DenseMap; @@ -81,9 +81,7 @@ class FunctionSummariesTy { I->second.MayInline = 0; } - void markReachedMaxBlockCount(const Decl *D) { - markShouldNotInline(D); - } + void markReachedMaxBlockCount(const Decl *D) { markShouldNotInline(D); } std::optional mayInline(const Decl *D) { MapTy::const_iterator I = Map.find(D); @@ -92,7 +90,7 @@ class FunctionSummariesTy { return std::nullopt; } - void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) { + void markVisitedBasicBlock(unsigned ID, const Decl *D, unsigned TotalIDs) { MapTy::iterator I = findOrInsertSummary(D); llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks; assert(ID < TotalIDs); @@ -103,21 +101,21 @@ class FunctionSummariesTy { Blocks.set(ID); } - unsigned getNumVisitedBasicBlocks(const Decl* D) { + unsigned getNumVisitedBasicBlocks(const Decl *D) { MapTy::const_iterator I = Map.find(D); if (I != Map.end()) return I->second.VisitedBasicBlocks.count(); return 0; } - unsigned getNumTimesInlined(const Decl* D) { + unsigned getNumTimesInlined(const Decl *D) { MapTy::const_iterator I = Map.find(D); if (I != Map.end()) return I->second.TimesInlined; return 0; } - void bumpNumTimesInlined(const Decl* D) { + void bumpNumTimesInlined(const Decl *D) { MapTy::iterator I = findOrInsertSummary(D); I->second.TimesInlined++; } @@ -125,9 +123,9 @@ class FunctionSummariesTy { /// Get the percentage of the reachable blocks. unsigned getPercentBlocksReachable(const Decl *D) { MapTy::const_iterator I = Map.find(D); - if (I != Map.end()) - return ((I->second.VisitedBasicBlocks.count() * 100) / - I->second.TotalBasicBlocks); + if (I != Map.end()) + return ((I->second.VisitedBasicBlocks.count() * 100) / + I->second.TotalBasicBlocks); return 0; } diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h index eb2b0b343428f..9bf2060e00499 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h @@ -24,8 +24,8 @@ #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPUNROLLING_H #include "clang/Analysis/CFG.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" namespace clang { namespace ento { @@ -35,7 +35,7 @@ bool isUnrolledState(ProgramStateRef State); /// Updates the stack of loops contained by the ProgramState. ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx, - ExplodedNode* Pred, unsigned maxVisitOnPath); + ExplodedNode *Pred, unsigned maxVisitOnPath); /// Updates the given ProgramState. In current implementation it removes the top /// element of the stack of loops. diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 151d3e57c1cb8..0a21938ed48cd 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -96,7 +96,7 @@ class RegionOffset { class MemRegion : public llvm::FoldingSetNode { public: enum Kind { -#define REGION(Id, Parent) Id ## Kind, +#define REGION(Id, Parent) Id##Kind, #define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last, #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" }; @@ -112,7 +112,7 @@ class MemRegion : public llvm::FoldingSetNode { public: ASTContext &getContext() const; - virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; + virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0; virtual MemRegionManager &getMemRegionManager() const = 0; @@ -171,7 +171,7 @@ class MemRegion : public llvm::FoldingSetNode { Kind getKind() const { return kind; } - template const RegionTy* getAs() const; + template const RegionTy *getAs() const; template LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *castAs() const; @@ -442,7 +442,7 @@ class SubRegion : public MemRegion { virtual void anchor(); protected: - const MemRegion* superRegion; + const MemRegion *superRegion; SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) { assert(classof(this)); @@ -451,15 +451,13 @@ class SubRegion : public MemRegion { public: LLVM_ATTRIBUTE_RETURNS_NONNULL - const MemRegion* getSuperRegion() const { - return superRegion; - } + const MemRegion *getSuperRegion() const { return superRegion; } MemRegionManager &getMemRegionManager() const override; - bool isSubRegionOf(const MemRegion* R) const override; + bool isSubRegionOf(const MemRegion *R) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() > END_MEMSPACES; } }; @@ -484,7 +482,7 @@ class AllocaRegion : public SubRegion { assert(Ex); } - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, + static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *Ex, unsigned Cnt, const MemRegion *superRegion); public: @@ -493,11 +491,11 @@ class AllocaRegion : public SubRegion { bool isBoundable() const override { return true; } - void Profile(llvm::FoldingSetNodeID& ID) const override; + void Profile(llvm::FoldingSetNodeID &ID) const override; void dumpToStream(raw_ostream &os) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == AllocaRegionKind; } }; @@ -520,18 +518,19 @@ class TypedRegion : public SubRegion { bool isBoundable() const override { return true; } - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { unsigned k = R->getKind(); return k >= BEGIN_TYPED_REGIONS && k <= END_TYPED_REGIONS; } }; -/// TypedValueRegion - An abstract class representing regions having a typed value. +/// TypedValueRegion - An abstract class representing regions having a typed +/// value. class TypedValueRegion : public TypedRegion { void anchor() override; protected: - TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) { + TypedValueRegion(const MemRegion *sReg, Kind k) : TypedRegion(sReg, k) { assert(classof(this)); } @@ -552,7 +551,7 @@ class TypedValueRegion : public TypedRegion { return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; } - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { unsigned k = R->getKind(); return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS; } @@ -569,7 +568,7 @@ class CodeTextRegion : public TypedRegion { public: bool isBoundable() const override { return false; } - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { Kind k = R->getKind(); return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS; } @@ -581,13 +580,13 @@ class FunctionCodeRegion : public CodeTextRegion { const NamedDecl *FD; - FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg) + FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion *sreg) : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) { assert(isa(fd) || isa(fd)); } - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD, - const MemRegion*); + static void ProfileRegion(llvm::FoldingSetNodeID &ID, const NamedDecl *FD, + const MemRegion *); public: QualType getLocationType() const override { @@ -604,15 +603,13 @@ class FunctionCodeRegion : public CodeTextRegion { return {}; } - const NamedDecl *getDecl() const { - return FD; - } + const NamedDecl *getDecl() const { return FD; } void dumpToStream(raw_ostream &os) const override; - void Profile(llvm::FoldingSetNodeID& ID) const override; + void Profile(llvm::FoldingSetNodeID &ID) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == FunctionCodeRegionKind; } }; @@ -630,36 +627,32 @@ class BlockCodeRegion : public CodeTextRegion { AnalysisDeclContext *AC; CanQualType locTy; - BlockCodeRegion(const BlockDecl *bd, CanQualType lTy, - AnalysisDeclContext *ac, const CodeSpaceRegion* sreg) + BlockCodeRegion(const BlockDecl *bd, CanQualType lTy, AnalysisDeclContext *ac, + const CodeSpaceRegion *sreg) : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) { assert(bd); assert(ac); assert(lTy->getTypePtr()->isBlockPointerType()); } - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, - CanQualType, const AnalysisDeclContext*, - const MemRegion*); + static void ProfileRegion(llvm::FoldingSetNodeID &ID, const BlockDecl *BD, + CanQualType, const AnalysisDeclContext *, + const MemRegion *); public: - QualType getLocationType() const override { - return locTy; - } + QualType getLocationType() const override { return locTy; } LLVM_ATTRIBUTE_RETURNS_NONNULL - const BlockDecl *getDecl() const { - return BD; - } + const BlockDecl *getDecl() const { return BD; } LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext *getAnalysisDeclContext() const { return AC; } void dumpToStream(raw_ostream &os) const override; - void Profile(llvm::FoldingSetNodeID& ID) const override; + void Profile(llvm::FoldingSetNodeID &ID) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == BlockCodeRegionKind; } }; @@ -687,11 +680,10 @@ class BlockDataRegion : public TypedRegion { assert(bc->getDecl()); assert(lc); assert(isa(sreg) || - isa(sreg) || - isa(sreg)); + isa(sreg) || isa(sreg)); } - static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *, + static void ProfileRegion(llvm::FoldingSetNodeID &, const BlockCodeRegion *, const LocationContext *, unsigned, const MemRegion *); @@ -705,18 +697,16 @@ class BlockDataRegion : public TypedRegion { QualType getLocationType() const override { return BC->getLocationType(); } class referenced_vars_iterator { - const MemRegion * const *R; - const MemRegion * const *OriginalR; + const MemRegion *const *R; + const MemRegion *const *OriginalR; public: - explicit referenced_vars_iterator(const MemRegion * const *r, - const MemRegion * const *originalR) + explicit referenced_vars_iterator(const MemRegion *const *r, + const MemRegion *const *originalR) : R(r), OriginalR(originalR) {} LLVM_ATTRIBUTE_RETURNS_NONNULL - const VarRegion *getCapturedRegion() const { - return cast(*R); - } + const VarRegion *getCapturedRegion() const { return cast(*R); } LLVM_ATTRIBUTE_RETURNS_NONNULL const VarRegion *getOriginalRegion() const { @@ -755,9 +745,9 @@ class BlockDataRegion : public TypedRegion { void dumpToStream(raw_ostream &os) const override; - void Profile(llvm::FoldingSetNodeID& ID) const override; + void Profile(llvm::FoldingSetNodeID &ID) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == BlockDataRegionKind; } @@ -807,15 +797,14 @@ class SymbolicRegion : public SubRegion { bool isBoundable() const override { return true; } - void Profile(llvm::FoldingSetNodeID& ID) const override; + void Profile(llvm::FoldingSetNodeID &ID) const override; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, - SymbolRef sym, - const MemRegion* superRegion); + static void ProfileRegion(llvm::FoldingSetNodeID &ID, SymbolRef sym, + const MemRegion *superRegion); void dumpToStream(raw_ostream &os) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == SymbolicRegionKind; } }; @@ -843,13 +832,13 @@ class StringRegion : public TypedValueRegion { bool isBoundable() const override { return false; } - void Profile(llvm::FoldingSetNodeID& ID) const override { + void Profile(llvm::FoldingSetNodeID &ID) const override { ProfileRegion(ID, Str, superRegion); } void dumpToStream(raw_ostream &os) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == StringRegionKind; } }; @@ -878,13 +867,13 @@ class ObjCStringRegion : public TypedValueRegion { bool isBoundable() const override { return false; } - void Profile(llvm::FoldingSetNodeID& ID) const override { + void Profile(llvm::FoldingSetNodeID &ID) const override { ProfileRegion(ID, Str, superRegion); } void dumpToStream(raw_ostream &os) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == ObjCStringRegionKind; } }; @@ -905,23 +894,23 @@ class CompoundLiteralRegion : public TypedValueRegion { isa(sReg)); } - static void ProfileRegion(llvm::FoldingSetNodeID& ID, + static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CompoundLiteralExpr *CL, - const MemRegion* superRegion); + const MemRegion *superRegion); public: QualType getValueType() const override { return CL->getType(); } bool isBoundable() const override { return !CL->isFileScope(); } - void Profile(llvm::FoldingSetNodeID& ID) const override; + void Profile(llvm::FoldingSetNodeID &ID) const override; void dumpToStream(raw_ostream &os) const override; LLVM_ATTRIBUTE_RETURNS_NONNULL const CompoundLiteralExpr *getLiteralExpr() const { return CL; } - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == CompoundLiteralRegionKind; } }; @@ -936,7 +925,7 @@ class DeclRegion : public TypedValueRegion { // TODO what does this return? virtual const ValueDecl *getDecl() const = 0; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { unsigned k = R->getKind(); return k >= BEGIN_DECL_REGIONS && k <= END_DECL_REGIONS; } @@ -1011,7 +1000,7 @@ class NonParamVarRegion : public VarRegion { void printPrettyAsExpr(raw_ostream &os) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == NonParamVarRegionKind; } }; @@ -1046,7 +1035,7 @@ class ParamVarRegion : public VarRegion { const Expr *getOriginExpr() const { return OriginExpr; } unsigned getIndex() const { return Index; } - void Profile(llvm::FoldingSetNodeID& ID) const override; + void Profile(llvm::FoldingSetNodeID &ID) const override; void dumpToStream(raw_ostream &os) const override; @@ -1077,20 +1066,17 @@ class CXXThisRegion : public TypedValueRegion { "Invalid region type!"); } - static void ProfileRegion(llvm::FoldingSetNodeID &ID, - const PointerType *PT, + static void ProfileRegion(llvm::FoldingSetNodeID &ID, const PointerType *PT, const MemRegion *sReg); public: void Profile(llvm::FoldingSetNodeID &ID) const override; - QualType getValueType() const override { - return QualType(ThisPointerTy, 0); - } + QualType getValueType() const override { return QualType(ThisPointerTy, 0); } void dumpToStream(raw_ostream &os) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == CXXThisRegionKind; } @@ -1109,7 +1095,7 @@ class FieldRegion : public DeclRegion { } static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD, - const MemRegion* superRegion) { + const MemRegion *superRegion) { ID.AddInteger(static_cast(FieldRegionKind)); ID.AddPointer(FD); ID.AddPointer(superRegion); @@ -1133,7 +1119,7 @@ class FieldRegion : public DeclRegion { bool canPrintPrettyAsExpr() const override; void printPrettyAsExpr(raw_ostream &os) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == FieldRegionKind; } }; @@ -1145,14 +1131,14 @@ class ObjCIvarRegion : public DeclRegion { ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg); - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd, - const MemRegion* superRegion); + static void ProfileRegion(llvm::FoldingSetNodeID &ID, const ObjCIvarDecl *ivd, + const MemRegion *superRegion); public: LLVM_ATTRIBUTE_RETURNS_NONNULL const ObjCIvarDecl *getDecl() const override; - void Profile(llvm::FoldingSetNodeID& ID) const override; + void Profile(llvm::FoldingSetNodeID &ID) const override; QualType getValueType() const override; @@ -1161,7 +1147,7 @@ class ObjCIvarRegion : public DeclRegion { void dumpToStream(raw_ostream &os) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == ObjCIvarRegionKind; } }; @@ -1176,7 +1162,7 @@ class RegionRawOffset { const MemRegion *Region; CharUnits Offset; - RegionRawOffset(const MemRegion* reg, CharUnits offset = CharUnits::Zero()) + RegionRawOffset(const MemRegion *reg, CharUnits offset = CharUnits::Zero()) : Region(reg), Offset(offset) {} public: @@ -1207,8 +1193,8 @@ class ElementRegion : public TypedValueRegion { "Invalid region type!"); } - static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, - SVal Idx, const MemRegion* superRegion); + static void ProfileRegion(llvm::FoldingSetNodeID &ID, QualType elementType, + SVal Idx, const MemRegion *superRegion); public: NonLoc getIndex() const { return Index; } @@ -1222,9 +1208,9 @@ class ElementRegion : public TypedValueRegion { void dumpToStream(raw_ostream &os) const override; - void Profile(llvm::FoldingSetNodeID& ID) const override; + void Profile(llvm::FoldingSetNodeID &ID) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == ElementRegionKind; } }; @@ -1241,8 +1227,8 @@ class CXXTempObjectRegion : public TypedValueRegion { assert(isa(sReg)); } - static void ProfileRegion(llvm::FoldingSetNodeID &ID, - Expr const *E, const MemRegion *sReg); + static void ProfileRegion(llvm::FoldingSetNodeID &ID, Expr const *E, + const MemRegion *sReg); public: LLVM_ATTRIBUTE_RETURNS_NONNULL @@ -1257,7 +1243,7 @@ class CXXTempObjectRegion : public TypedValueRegion { void Profile(llvm::FoldingSetNodeID &ID) const override; - static bool classof(const MemRegion* R) { + static bool classof(const MemRegion *R) { return R->getKind() == CXXTempObjectRegionKind; } }; @@ -1379,8 +1365,7 @@ class CXXDerivedObjectRegion : public TypedValueRegion { } }; -template -const RegionTy* MemRegion::getAs() const { +template const RegionTy *MemRegion::getAs() const { if (const auto *RT = dyn_cast(this)) return RT; @@ -1398,7 +1383,7 @@ LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *MemRegion::castAs() const { class MemRegionManager { ASTContext &Ctx; - llvm::BumpPtrAllocator& A; + llvm::BumpPtrAllocator &A; llvm::FoldingSet Regions; @@ -1407,11 +1392,11 @@ class MemRegionManager { GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr; llvm::DenseMap - StackLocalsSpaceRegions; + StackLocalsSpaceRegions; llvm::DenseMap - StackArgumentsSpaceRegions; + StackArgumentsSpaceRegions; llvm::DenseMap - StaticsGlobalSpaceRegions; + StaticsGlobalSpaceRegions; HeapSpaceRegion *heap = nullptr; UnknownSpaceRegion *unknown = nullptr; @@ -1443,9 +1428,9 @@ class MemRegionManager { /// getGlobalsRegion - Retrieve the memory region associated with /// global variables. - const GlobalsSpaceRegion *getGlobalsRegion( - MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind, - const CodeTextRegion *R = nullptr); + const GlobalsSpaceRegion * + getGlobalsRegion(MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind, + const CodeTextRegion *R = nullptr); /// getHeapRegion - Retrieve the memory region associated with the /// generic "heap". @@ -1463,7 +1448,7 @@ class MemRegionManager { /// getCompoundLiteralRegion - Retrieve the region associated with a /// given CompoundLiteral. - const CompoundLiteralRegion* + const CompoundLiteralRegion * getCompoundLiteralRegion(const CompoundLiteralExpr *CL, const LocationContext *LC); @@ -1507,8 +1492,8 @@ class MemRegionManager { const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER, const SubRegion *superRegion) { - return getElementRegion(ER->getElementType(), ER->getIndex(), - superRegion, ER->getContext()); + return getElementRegion(ER->getElementType(), ER->getIndex(), superRegion, + ER->getContext()); } /// getFieldRegion - Retrieve or create the memory region associated with @@ -1516,7 +1501,7 @@ class MemRegionManager { /// memory region (which typically represents the memory representing /// a structure or class). const FieldRegion *getFieldRegion(const FieldDecl *fd, - const SubRegion* superRegion); + const SubRegion *superRegion); const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR, const SubRegion *superRegion) { @@ -1528,7 +1513,7 @@ class MemRegionManager { /// to the containing region (which typically represents the Objective-C /// object). const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd, - const SubRegion* superRegion); + const SubRegion *superRegion); const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC); @@ -1585,27 +1570,23 @@ class MemRegionManager { unsigned blockCount); private: - template - RegionTy* getSubRegion(const Arg1Ty arg1, - const SuperTy* superRegion); + template + RegionTy *getSubRegion(const Arg1Ty arg1, const SuperTy *superRegion); - template - RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2, - const SuperTy* superRegion); + template + RegionTy *getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2, + const SuperTy *superRegion); - template - RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2, - const Arg3Ty arg3, - const SuperTy* superRegion); + template + RegionTy *getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2, + const Arg3Ty arg3, const SuperTy *superRegion); - template - const REG* LazyAllocate(REG*& region); + template const REG *LazyAllocate(REG *®ion); template - const REG* LazyAllocate(REG*& region, ARG a); + const REG *LazyAllocate(REG *®ion, ARG a); }; //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index ca75c2a756a4a..8ed765db41a51 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -39,9 +39,9 @@ class AnalysisManager; class CallEvent; class CallEventManager; -typedef std::unique_ptr(*ConstraintManagerCreator)( +typedef std::unique_ptr (*ConstraintManagerCreator)( ProgramStateManager &, ExprEngine *); -typedef std::unique_ptr(*StoreManagerCreator)( +typedef std::unique_ptr (*StoreManagerCreator)( ProgramStateManager &); //===----------------------------------------------------------------------===// @@ -50,9 +50,9 @@ typedef std::unique_ptr(*StoreManagerCreator)( template struct ProgramStateTrait { typedef typename T::data_type data_type; - static inline void *MakeVoidPtr(data_type D) { return (void*) D; } - static inline data_type MakeData(void *const* P) { - return P ? (data_type) *P : (data_type) 0; + static inline void *MakeVoidPtr(data_type D) { return (void *)D; } + static inline data_type MakeData(void *const *P) { + return P ? (data_type)*P : (data_type)0; } }; @@ -70,11 +70,11 @@ template struct ProgramStateTrait { /// values will never change. class ProgramState : public llvm::FoldingSetNode { public: - typedef llvm::ImmutableSet IntSetTy; - typedef llvm::ImmutableMap GenericDataMap; + typedef llvm::ImmutableSet IntSetTy; + typedef llvm::ImmutableMap GenericDataMap; private: - void operator=(const ProgramState& R) = delete; + void operator=(const ProgramState &R) = delete; friend class ProgramStateManager; friend class ExplodedGraph; @@ -82,9 +82,9 @@ class ProgramState : public llvm::FoldingSetNode { friend class NodeBuilder; ProgramStateManager *stateMgr; - Environment Env; // Maps a Stmt to its current SVal. - Store store; // Maps a location to its current value. - GenericDataMap GDM; // Custom data stored by a client of this class. + Environment Env; // Maps a Stmt to its current SVal. + Store store; // Maps a location to its current value. + GenericDataMap GDM; // Custom data stored by a client of this class. // A state is infeasible if there is a contradiction among the constraints. // An infeasible state is represented by a `nullptr`. @@ -132,8 +132,8 @@ class ProgramState : public llvm::FoldingSetNode { public: /// This ctor is used when creating the first ProgramState object. - ProgramState(ProgramStateManager *mgr, const Environment& env, - StoreRef st, GenericDataMap gdm); + ProgramState(ProgramStateManager *mgr, const Environment &env, StoreRef st, + GenericDataMap gdm); /// Copy ctor - We must explicitly define this or else the "Next" ptr /// in FoldingSetNode will also get copied. @@ -144,9 +144,7 @@ class ProgramState : public llvm::FoldingSetNode { int64_t getID() const; /// Return the ProgramStateManager associated with this state. - ProgramStateManager &getStateManager() const { - return *stateMgr; - } + ProgramStateManager &getStateManager() const { return *stateMgr; } AnalysisManager &getAnalysisManager() const; @@ -155,13 +153,12 @@ class ProgramState : public llvm::FoldingSetNode { /// getEnvironment - Return the environment associated with this state. /// The environment is the mapping from expressions to values. - const Environment& getEnvironment() const { return Env; } + const Environment &getEnvironment() const { return Env; } /// Return the store associated with this state. The store /// is a mapping from locations to values. Store getStore() const { return store; } - /// getGDM - Return the generic data map associated with this state. GenericDataMap getGDM() const { return GDM; } @@ -170,7 +167,7 @@ class ProgramState : public llvm::FoldingSetNode { /// Profile - Profile the contents of a ProgramState object for use in a /// FoldingSet. Two ProgramState objects are considered equal if they /// have the same Environment, Store, and GenericDataMap. - static void Profile(llvm::FoldingSetNodeID& ID, const ProgramState *V) { + static void Profile(llvm::FoldingSetNodeID &ID, const ProgramState *V) { V->Env.Profile(ID); ID.AddPointer(V->store); V->GDM.Profile(ID); @@ -179,9 +176,7 @@ class ProgramState : public llvm::FoldingSetNode { /// Profile - Used to profile the contents of this object for inclusion /// in a FoldingSet. - void Profile(llvm::FoldingSetNodeID& ID) const { - Profile(ID, this); - } + void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, this); } BasicValueFactory &getBasicVals() const; SymbolManager &getSymbolManager() const; @@ -190,12 +185,12 @@ class ProgramState : public llvm::FoldingSetNode { // Constraints on values. //==---------------------------------------------------------------------==// // - // Each ProgramState records constraints on symbolic values. These constraints - // are managed using the ConstraintManager associated with a ProgramStateManager. - // As constraints gradually accrue on symbolic values, added constraints - // may conflict and indicate that a state is infeasible (as no real values - // could satisfy all the constraints). This is the principal mechanism - // for modeling path-sensitivity in ExprEngine/ProgramState. + // Each ProgramState records constraints on symbolic values. These + // constraints are managed using the ConstraintManager associated with a + // ProgramStateManager. As constraints gradually accrue on symbolic values, + // added constraints may conflict and indicate that a state is infeasible (as + // no real values could satisfy all the constraints). This is the principal + // mechanism for modeling path-sensitivity in ExprEngine/ProgramState. // // Various "assume" methods form the interface for adding constraints to // symbolic values. A call to 'assume' indicates an assumption being placed @@ -208,8 +203,8 @@ class ProgramState : public llvm::FoldingSetNode { // (3) A binary value "Assumption" that indicates whether the constraint is // assumed to be true or false. // - // The output of "assume*" is a new ProgramState object with the added constraints. - // If no new state is feasible, NULL is returned. + // The output of "assume*" is a new ProgramState object with the added + // constraints. If no new state is feasible, NULL is returned. // /// Assumes that the value of \p cond is zero (if \p assumption is "false") @@ -269,7 +264,7 @@ class ProgramState : public llvm::FoldingSetNode { /// Utility method for getting regions. LLVM_ATTRIBUTE_RETURNS_NONNULL - const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const; + const VarRegion *getRegion(const VarDecl *D, const LocationContext *LC) const; //==---------------------------------------------------------------------==// // Binding and retrieving values to/from the environment and symbolic store. @@ -380,11 +375,11 @@ class ProgramState : public llvm::FoldingSetNode { SVal getSVal(Loc LV, QualType T = QualType()) const; /// Returns the "raw" SVal bound to LV before any value simplfication. - SVal getRawSVal(Loc LV, QualType T= QualType()) const; + SVal getRawSVal(Loc LV, QualType T = QualType()) const; /// Return the value bound to the specified location. /// Returns UnknownVal() if none found. - SVal getSVal(const MemRegion* R, QualType T = QualType()) const; + SVal getSVal(const MemRegion *R, QualType T = QualType()) const; /// Return the value bound to the specified location, assuming /// that the value is a scalar integer or an enumeration or a pointer. @@ -401,7 +396,7 @@ class ProgramState : public llvm::FoldingSetNode { /// directly when making multiple scans on the same state with the same /// visitor to avoid repeated initialization cost. /// \sa ScanReachableSymbols - bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const; + bool scanReachableSymbols(SVal val, SymbolVisitor &visitor) const; /// Visits the symbols reachable from the regions in the given /// MemRegions range using the provided SymbolVisitor. @@ -409,29 +404,29 @@ class ProgramState : public llvm::FoldingSetNode { SymbolVisitor &visitor) const; template CB scanReachableSymbols(SVal val) const; - template CB - scanReachableSymbols(llvm::iterator_range Reachable) const; + template + CB scanReachableSymbols( + llvm::iterator_range Reachable) const; //==---------------------------------------------------------------------==// // Accessing the Generic Data Map (GDM). //==---------------------------------------------------------------------==// - void *const* FindGDM(void *K) const; + void *const *FindGDM(void *K) const; template [[nodiscard]] ProgramStateRef add(typename ProgramStateTrait::key_type K) const; - template - typename ProgramStateTrait::data_type - get() const { - return ProgramStateTrait::MakeData(FindGDM(ProgramStateTrait::GDMIndex())); + template typename ProgramStateTrait::data_type get() const { + return ProgramStateTrait::MakeData( + FindGDM(ProgramStateTrait::GDMIndex())); } - template + template typename ProgramStateTrait::lookup_type get(typename ProgramStateTrait::key_type key) const { - void *const* d = FindGDM(ProgramStateTrait::GDMIndex()); + void *const *d = FindGDM(ProgramStateTrait::GDMIndex()); return ProgramStateTrait::Lookup(ProgramStateTrait::MakeData(d), key); } @@ -464,10 +459,11 @@ class ProgramState : public llvm::FoldingSetNode { typename ProgramStateTrait::value_type E, typename ProgramStateTrait::context_type C) const; - template + template bool contains(typename ProgramStateTrait::key_type key) const { - void *const* d = FindGDM(ProgramStateTrait::GDMIndex()); - return ProgramStateTrait::Contains(ProgramStateTrait::MakeData(d), key); + void *const *d = FindGDM(ProgramStateTrait::GDMIndex()); + return ProgramStateTrait::Contains(ProgramStateTrait::MakeData(d), + key); } // Pretty-printing. @@ -487,11 +483,9 @@ class ProgramState : public llvm::FoldingSetNode { /// \sa invalidateValues() /// \sa invalidateRegions() ProgramStateRef - invalidateRegionsImpl(ArrayRef Values, - const Expr *E, unsigned BlockCount, - const LocationContext *LCtx, - bool ResultsInSymbolEscape, - InvalidatedSymbols *IS, + invalidateRegionsImpl(ArrayRef Values, const Expr *E, + unsigned BlockCount, const LocationContext *LCtx, + bool ResultsInSymbolEscape, InvalidatedSymbols *IS, RegionAndSymbolInvalidationTraits *HTraits, const CallEvent *Call) const; }; @@ -503,17 +497,19 @@ class ProgramState : public llvm::FoldingSetNode { class ProgramStateManager { friend class ProgramState; friend void ProgramStateRelease(const ProgramState *state); + private: /// Eng - The ExprEngine that owns this state manager. ExprEngine *Eng; /* Can be null. */ - EnvironmentManager EnvMgr; - std::unique_ptr StoreMgr; - std::unique_ptr ConstraintMgr; + EnvironmentManager EnvMgr; + std::unique_ptr StoreMgr; + std::unique_ptr ConstraintMgr; - ProgramState::GenericDataMap::Factory GDMFactory; + ProgramState::GenericDataMap::Factory GDMFactory; - typedef llvm::DenseMap > GDMContextsTy; + typedef llvm::DenseMap> + GDMContextsTy; GDMContextsTy GDMContexts; /// StateSet - FoldingSet containing all the states created for analyzing @@ -533,11 +529,9 @@ class ProgramStateManager { std::vector freeStates; public: - ProgramStateManager(ASTContext &Ctx, - StoreManagerCreator CreateStoreManager, - ConstraintManagerCreator CreateConstraintManager, - llvm::BumpPtrAllocator& alloc, - ExprEngine *expreng); + ProgramStateManager(ASTContext &Ctx, StoreManagerCreator CreateStoreManager, + ConstraintManagerCreator CreateConstraintManager, + llvm::BumpPtrAllocator &alloc, ExprEngine *expreng); ~ProgramStateManager(); @@ -550,24 +544,18 @@ class ProgramStateManager { return svalBuilder->getBasicValueFactory(); } - SValBuilder &getSValBuilder() { - return *svalBuilder; - } + SValBuilder &getSValBuilder() { return *svalBuilder; } - const SValBuilder &getSValBuilder() const { - return *svalBuilder; - } + const SValBuilder &getSValBuilder() const { return *svalBuilder; } - SymbolManager &getSymbolManager() { - return svalBuilder->getSymbolManager(); - } + SymbolManager &getSymbolManager() { return svalBuilder->getSymbolManager(); } const SymbolManager &getSymbolManager() const { return svalBuilder->getSymbolManager(); } - llvm::BumpPtrAllocator& getAllocator() { return Alloc; } + llvm::BumpPtrAllocator &getAllocator() { return Alloc; } - MemRegionManager& getRegionManager() { + MemRegionManager &getRegionManager() { return svalBuilder->getRegionManager(); } const MemRegionManager &getRegionManager() const { @@ -586,7 +574,6 @@ class ProgramStateManager { SymbolReaper &SymReaper); public: - SVal ArrayToPointer(Loc Array, QualType ElementTy) { return StoreMgr->ArrayToPointer(Array, ElementTy); } @@ -597,13 +584,13 @@ class ProgramStateManager { // Methods that query & manipulate the Store. - void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler& F) { + void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler &F) { StoreMgr->iterBindings(state->getStore(), F); } ProgramStateRef getPersistentState(ProgramState &Impl); ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, - ProgramStateRef GDMState); + ProgramStateRef GDMState); bool haveEqualConstraints(ProgramStateRef S1, ProgramStateRef S2) const { return ConstraintMgr->haveEqualConstraints(S1, S2); @@ -621,15 +608,15 @@ class ProgramStateManager { // Generic Data Map methods. //==---------------------------------------------------------------------==// // - // ProgramStateManager and ProgramState support a "generic data map" that allows - // different clients of ProgramState objects to embed arbitrary data within a - // ProgramState object. The generic data map is essentially an immutable map - // from a "tag" (that acts as the "key" for a client) and opaque values. - // Tags/keys and values are simply void* values. The typical way that clients - // generate unique tags are by taking the address of a static variable. - // Clients are responsible for ensuring that data values referred to by a - // the data pointer are immutable (and thus are essentially purely functional - // data). + // ProgramStateManager and ProgramState support a "generic data map" that + // allows different clients of ProgramState objects to embed arbitrary data + // within a ProgramState object. The generic data map is essentially an + // immutable map from a "tag" (that acts as the "key" for a client) and opaque + // values. Tags/keys and values are simply void* values. The typical way that + // clients generate unique tags are by taking the address of a static + // variable. Clients are responsible for ensuring that data values referred to + // by a the data pointer are immutable (and thus are essentially purely + // functional data). // // The templated methods below use the ProgramStateTrait class // to resolve keys into the GDM and to return data values to clients. @@ -637,46 +624,49 @@ class ProgramStateManager { // Trait based GDM dispatch. template - ProgramStateRef set(ProgramStateRef st, typename ProgramStateTrait::data_type D) { + ProgramStateRef set(ProgramStateRef st, + typename ProgramStateTrait::data_type D) { return addGDM(st, ProgramStateTrait::GDMIndex(), ProgramStateTrait::MakeVoidPtr(D)); } - template + template ProgramStateRef set(ProgramStateRef st, - typename ProgramStateTrait::key_type K, - typename ProgramStateTrait::value_type V, - typename ProgramStateTrait::context_type C) { + typename ProgramStateTrait::key_type K, + typename ProgramStateTrait::value_type V, + typename ProgramStateTrait::context_type C) { return addGDM(st, ProgramStateTrait::GDMIndex(), - ProgramStateTrait::MakeVoidPtr(ProgramStateTrait::Set(st->get(), K, V, C))); + ProgramStateTrait::MakeVoidPtr( + ProgramStateTrait::Set(st->get(), K, V, C))); } template ProgramStateRef add(ProgramStateRef st, - typename ProgramStateTrait::key_type K, - typename ProgramStateTrait::context_type C) { + typename ProgramStateTrait::key_type K, + typename ProgramStateTrait::context_type C) { return addGDM(st, ProgramStateTrait::GDMIndex(), - ProgramStateTrait::MakeVoidPtr(ProgramStateTrait::Add(st->get(), K, C))); + ProgramStateTrait::MakeVoidPtr( + ProgramStateTrait::Add(st->get(), K, C))); } template ProgramStateRef remove(ProgramStateRef st, - typename ProgramStateTrait::key_type K, - typename ProgramStateTrait::context_type C) { + typename ProgramStateTrait::key_type K, + typename ProgramStateTrait::context_type C) { return addGDM(st, ProgramStateTrait::GDMIndex(), - ProgramStateTrait::MakeVoidPtr(ProgramStateTrait::Remove(st->get(), K, C))); + ProgramStateTrait::MakeVoidPtr( + ProgramStateTrait::Remove(st->get(), K, C))); } - template - ProgramStateRef remove(ProgramStateRef st) { + template ProgramStateRef remove(ProgramStateRef st) { return removeGDM(st, ProgramStateTrait::GDMIndex()); } void *FindGDMContext(void *index, - void *(*CreateContext)(llvm::BumpPtrAllocator&), - void (*DeleteContext)(void*)); + void *(*CreateContext)(llvm::BumpPtrAllocator &), + void (*DeleteContext)(void *)); template typename ProgramStateTrait::context_type get_context() { @@ -688,7 +678,6 @@ class ProgramStateManager { } }; - //===----------------------------------------------------------------------===// // Out-of-line method definitions for ProgramState. //===----------------------------------------------------------------------===// @@ -697,28 +686,27 @@ inline ConstraintManager &ProgramState::getConstraintManager() const { return stateMgr->getConstraintManager(); } -inline const VarRegion* ProgramState::getRegion(const VarDecl *D, - const LocationContext *LC) const -{ +inline const VarRegion * +ProgramState::getRegion(const VarDecl *D, const LocationContext *LC) const { return getStateManager().getRegionManager().getVarRegion(D, LC); } inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond, - bool Assumption) const { + bool Assumption) const { if (Cond.isUnknown()) return this; - return getStateManager().ConstraintMgr - ->assume(this, Cond.castAs(), Assumption); + return getStateManager().ConstraintMgr->assume( + this, Cond.castAs(), Assumption); } -inline std::pair +inline std::pair ProgramState::assume(DefinedOrUnknownSVal Cond) const { if (Cond.isUnknown()) return std::make_pair(this, this); - return getStateManager().ConstraintMgr - ->assumeDual(this, Cond.castAs()); + return getStateManager().ConstraintMgr->assumeDual( + this, Cond.castAs()); } inline ProgramStateRef ProgramState::assumeInclusiveRange( @@ -746,7 +734,8 @@ ProgramState::assumeInclusiveRange(DefinedOrUnknownSVal Val, this, Val.castAs(), From, To); } -inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V, const LocationContext *LCtx) const { +inline ProgramStateRef +ProgramState::bindLoc(SVal LV, SVal V, const LocationContext *LCtx) const { if (std::optional L = LV.getAs()) return bindLoc(*L, V, LCtx); return this; @@ -756,25 +745,25 @@ inline Loc ProgramState::getLValue(const CXXBaseSpecifier &BaseSpec, const SubRegion *Super) const { const auto *Base = BaseSpec.getType()->getAsCXXRecordDecl(); return loc::MemRegionVal( - getStateManager().getRegionManager().getCXXBaseObjectRegion( - Base, Super, BaseSpec.isVirtual())); + getStateManager().getRegionManager().getCXXBaseObjectRegion( + Base, Super, BaseSpec.isVirtual())); } inline Loc ProgramState::getLValue(const CXXRecordDecl *BaseClass, const SubRegion *Super, bool IsVirtual) const { return loc::MemRegionVal( - getStateManager().getRegionManager().getCXXBaseObjectRegion( - BaseClass, Super, IsVirtual)); + getStateManager().getRegionManager().getCXXBaseObjectRegion( + BaseClass, Super, IsVirtual)); } inline Loc ProgramState::getLValue(const VarDecl *VD, - const LocationContext *LC) const { + const LocationContext *LC) const { return getStateManager().StoreMgr->getLValueVar(VD, LC); } inline Loc ProgramState::getLValue(const CompoundLiteralExpr *literal, - const LocationContext *LC) const { + const LocationContext *LC) const { return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC); } @@ -796,14 +785,15 @@ inline SVal ProgramState::getLValue(const IndirectFieldDecl *D, return Base; } -inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{ +inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, + SVal Base) const { if (std::optional N = Idx.getAs()) return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base); return UnknownVal(); } inline SVal ProgramState::getSVal(const Stmt *Ex, - const LocationContext *LCtx) const{ + const LocationContext *LCtx) const { return Env.getSVal(EnvironmentEntry(Ex, LCtx), *getStateManager().svalBuilder); } @@ -825,10 +815,9 @@ inline SVal ProgramState::getRawSVal(Loc LV, QualType T) const { return getStateManager().StoreMgr->getBinding(getStore(), LV, T); } -inline SVal ProgramState::getSVal(const MemRegion* R, QualType T) const { +inline SVal ProgramState::getSVal(const MemRegion *R, QualType T) const { return getStateManager().StoreMgr->getBinding(getStore(), - loc::MemRegionVal(R), - T); + loc::MemRegionVal(R), T); } inline BasicValueFactory &ProgramState::getBasicVals() const { @@ -839,8 +828,9 @@ inline SymbolManager &ProgramState::getSymbolManager() const { return getStateManager().getSymbolManager(); } -template -ProgramStateRef ProgramState::add(typename ProgramStateTrait::key_type K) const { +template +ProgramStateRef +ProgramState::add(typename ProgramStateTrait::key_type K) const { return getStateManager().add(this, K, get_context()); } @@ -849,42 +839,45 @@ typename ProgramStateTrait::context_type ProgramState::get_context() const { return getStateManager().get_context(); } -template -ProgramStateRef ProgramState::remove(typename ProgramStateTrait::key_type K) const { +template +ProgramStateRef +ProgramState::remove(typename ProgramStateTrait::key_type K) const { return getStateManager().remove(this, K, get_context()); } -template -ProgramStateRef ProgramState::remove(typename ProgramStateTrait::key_type K, - typename ProgramStateTrait::context_type C) const { +template +ProgramStateRef +ProgramState::remove(typename ProgramStateTrait::key_type K, + typename ProgramStateTrait::context_type C) const { return getStateManager().remove(this, K, C); } -template -ProgramStateRef ProgramState::remove() const { +template ProgramStateRef ProgramState::remove() const { return getStateManager().remove(this); } -template -ProgramStateRef ProgramState::set(typename ProgramStateTrait::data_type D) const { +template +ProgramStateRef +ProgramState::set(typename ProgramStateTrait::data_type D) const { return getStateManager().set(this, D); } -template -ProgramStateRef ProgramState::set(typename ProgramStateTrait::key_type K, - typename ProgramStateTrait::value_type E) const { +template +ProgramStateRef +ProgramState::set(typename ProgramStateTrait::key_type K, + typename ProgramStateTrait::value_type E) const { return getStateManager().set(this, K, E, get_context()); } -template -ProgramStateRef ProgramState::set(typename ProgramStateTrait::key_type K, - typename ProgramStateTrait::value_type E, - typename ProgramStateTrait::context_type C) const { +template +ProgramStateRef +ProgramState::set(typename ProgramStateTrait::key_type K, + typename ProgramStateTrait::value_type E, + typename ProgramStateTrait::context_type C) const { return getStateManager().set(this, K, E, C); } -template -CB ProgramState::scanReachableSymbols(SVal val) const { +template CB ProgramState::scanReachableSymbols(SVal val) const { CB cb(this); scanReachableSymbols(val, cb); return cb; @@ -903,11 +896,12 @@ CB ProgramState::scanReachableSymbols( /// SymbolVisitor. Terminates recursive traversal when the visitor function /// returns false. class ScanReachableSymbols { - typedef llvm::DenseSet VisitedItems; + typedef llvm::DenseSet VisitedItems; VisitedItems visited; ProgramStateRef state; SymbolVisitor &visitor; + public: ScanReachableSymbols(ProgramStateRef st, SymbolVisitor &v) : state(std::move(st)), visitor(v) {} @@ -919,8 +913,8 @@ class ScanReachableSymbols { bool scan(const SymExpr *sym); }; -} // end ento namespace +} // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h index 15bec97c5be8f..81f5d3ccf9470 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h @@ -1,15 +1,16 @@ -//ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- C++ -*- +// ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- C++ +// -*- // -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Part of the LLVM Project, under the Apache License v2.0 with LLVM +// Exceptions. See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // -// This file defines partial implementations of template specializations of -// the class ProgramStateTrait<>. ProgramStateTrait<> is used by ProgramState -// to implement set/get methods for manipulating a ProgramState's -// generic data map. +// This file defines partial implementations of template specializations of +// the class ProgramStateTrait<>. ProgramStateTrait<> is used by ProgramState +// to implement set/get methods for manipulating a ProgramState's +// generic data map. // //===----------------------------------------------------------------------===// @@ -48,249 +49,231 @@ template struct ProgramStatePartialTrait; } \ } - /// Declares a factory for objects of type \p Type in the program state - /// manager. The type must provide a ::Factory sub-class. Commonly used for - /// ImmutableMap, ImmutableSet, ImmutableList. The macro should not be used - /// inside namespaces. - #define REGISTER_FACTORY_WITH_PROGRAMSTATE(Type) \ - namespace clang { \ - namespace ento { \ - template <> \ - struct ProgramStateTrait \ - : public ProgramStatePartialTrait { \ - static void *GDMIndex() { static int Index; return &Index; } \ - }; \ - } \ - } - - /// Helper for registering a map trait. - /// - /// If the map type were written directly in the invocation of - /// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments - /// would be treated as a macro argument separator, which is wrong. - /// This allows the user to specify a map type in a way that the preprocessor - /// can deal with. - #define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap - - /// Declares an immutable map of type \p NameTy, suitable for placement into - /// the ProgramState. This is implementing using llvm::ImmutableMap. - /// - /// \code - /// State = State->set(K, V); - /// const Value *V = State->get(K); // Returns NULL if not in the map. - /// State = State->remove(K); - /// NameTy Map = State->get(); - /// \endcode - /// - /// The macro should not be used inside namespaces, or for traits that must - /// be accessible from more than one translation unit. - #define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \ - REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \ - CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value)) - - /// Declares an immutable map type \p Name and registers the factory - /// for such maps in the program state, but does not add the map itself - /// to the program state. Useful for managing lifetime of maps that are used - /// as elements of other program state data structures. - #define REGISTER_MAP_FACTORY_WITH_PROGRAMSTATE(Name, Key, Value) \ - using Name = llvm::ImmutableMap; \ - REGISTER_FACTORY_WITH_PROGRAMSTATE(Name) - - - /// Declares an immutable set of type \p NameTy, suitable for placement into - /// the ProgramState. This is implementing using llvm::ImmutableSet. - /// - /// \code - /// State = State->add(E); - /// State = State->remove(E); - /// bool Present = State->contains(E); - /// NameTy Set = State->get(); - /// \endcode - /// - /// The macro should not be used inside namespaces, or for traits that must - /// be accessible from more than one translation unit. - #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \ - REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet) - - /// Declares an immutable set type \p Name and registers the factory - /// for such sets in the program state, but does not add the set itself - /// to the program state. Useful for managing lifetime of sets that are used - /// as elements of other program state data structures. - #define REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(Name, Elem) \ - using Name = llvm::ImmutableSet; \ - REGISTER_FACTORY_WITH_PROGRAMSTATE(Name) - - - /// Declares an immutable list type \p NameTy, suitable for placement into - /// the ProgramState. This is implementing using llvm::ImmutableList. - /// - /// \code - /// State = State->add(E); // Adds to the /end/ of the list. - /// bool Present = State->contains(E); - /// NameTy List = State->get(); - /// \endcode - /// - /// The macro should not be used inside namespaces, or for traits that must - /// be accessible from more than one translation unit. - #define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \ - REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList) - - /// Declares an immutable list of type \p Name and registers the factory - /// for such lists in the program state, but does not add the list itself - /// to the program state. Useful for managing lifetime of lists that are used - /// as elements of other program state data structures. - #define REGISTER_LIST_FACTORY_WITH_PROGRAMSTATE(Name, Elem) \ - using Name = llvm::ImmutableList; \ - REGISTER_FACTORY_WITH_PROGRAMSTATE(Name) - - - // Partial-specialization for ImmutableMap. - template - struct ProgramStatePartialTrait> { - using data_type = llvm::ImmutableMap; - using context_type = typename data_type::Factory &; - using key_type = Key; - using value_type = Data; - using lookup_type = const value_type *; - - static data_type MakeData(void *const *p) { - return p ? data_type((typename data_type::TreeTy *) *p) - : data_type(nullptr); - } - - static void *MakeVoidPtr(data_type B) { - return B.getRoot(); - } - - static lookup_type Lookup(data_type B, key_type K) { - return B.lookup(K); - } - - static data_type Set(data_type B, key_type K, value_type E, - context_type F) { - return F.add(B, K, E); - } - - static data_type Remove(data_type B, key_type K, context_type F) { - return F.remove(B, K); - } - - static bool Contains(data_type B, key_type K) { - return B.contains(K); - } - - static context_type MakeContext(void *p) { - return *((typename data_type::Factory *) p); - } - - static void *CreateContext(llvm::BumpPtrAllocator& Alloc) { - return new typename data_type::Factory(Alloc); - } - - static void DeleteContext(void *Ctx) { - delete (typename data_type::Factory *) Ctx; - } - }; - - // Partial-specialization for ImmutableSet. - template - struct ProgramStatePartialTrait> { - using data_type = llvm::ImmutableSet; - using context_type = typename data_type::Factory &; - using key_type = Key; - - static data_type MakeData(void *const *p) { - return p ? data_type((typename data_type::TreeTy *) *p) - : data_type(nullptr); - } - - static void *MakeVoidPtr(data_type B) { - return B.getRoot(); - } - - static data_type Add(data_type B, key_type K, context_type F) { - return F.add(B, K); - } - - static data_type Remove(data_type B, key_type K, context_type F) { - return F.remove(B, K); - } - - static bool Contains(data_type B, key_type K) { - return B.contains(K); - } - - static context_type MakeContext(void *p) { - return *((typename data_type::Factory *) p); - } - - static void *CreateContext(llvm::BumpPtrAllocator &Alloc) { - return new typename data_type::Factory(Alloc); - } - - static void DeleteContext(void *Ctx) { - delete (typename data_type::Factory *) Ctx; - } - }; - - // Partial-specialization for ImmutableList. - template - struct ProgramStatePartialTrait> { - using data_type = llvm::ImmutableList; - using key_type = T; - using context_type = typename data_type::Factory &; - - static data_type Add(data_type L, key_type K, context_type F) { - return F.add(K, L); - } - - static bool Contains(data_type L, key_type K) { - return L.contains(K); - } - - static data_type MakeData(void *const *p) { - return p ? data_type((const llvm::ImmutableListImpl *) *p) - : data_type(nullptr); - } - - static void *MakeVoidPtr(data_type D) { - return const_cast *>(D.getInternalPointer()); - } - - static context_type MakeContext(void *p) { - return *((typename data_type::Factory *) p); - } - - static void *CreateContext(llvm::BumpPtrAllocator &Alloc) { - return new typename data_type::Factory(Alloc); - } - - static void DeleteContext(void *Ctx) { - delete (typename data_type::Factory *) Ctx; - } - }; - - template struct DefaultProgramStatePartialTraitImpl { - using data_type = T; - static T MakeData(void *const *P) { return P ? (T)(uintptr_t)*P : T{}; } - static void *MakeVoidPtr(T D) { return (void *)(uintptr_t)D; } - }; - - // Partial specialization for integral types. - template - struct ProgramStatePartialTrait::value>> - : DefaultProgramStatePartialTraitImpl {}; - - // Partial specialization for enums. - template - struct ProgramStatePartialTrait::value>> - : DefaultProgramStatePartialTraitImpl {}; - - // Partial specialization for pointers. - template - struct ProgramStatePartialTrait - : DefaultProgramStatePartialTraitImpl {}; +/// Declares a factory for objects of type \p Type in the program state +/// manager. The type must provide a ::Factory sub-class. Commonly used for +/// ImmutableMap, ImmutableSet, ImmutableList. The macro should not be used +/// inside namespaces. +#define REGISTER_FACTORY_WITH_PROGRAMSTATE(Type) \ + namespace clang { \ + namespace ento { \ + template <> \ + struct ProgramStateTrait : public ProgramStatePartialTrait { \ + static void *GDMIndex() { \ + static int Index; \ + return &Index; \ + } \ + }; \ + } \ + } + +/// Helper for registering a map trait. +/// +/// If the map type were written directly in the invocation of +/// REGISTER_TRAIT_WITH_PROGRAMSTATE, the comma in the template arguments +/// would be treated as a macro argument separator, which is wrong. +/// This allows the user to specify a map type in a way that the preprocessor +/// can deal with. +#define CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value) llvm::ImmutableMap + +/// Declares an immutable map of type \p NameTy, suitable for placement into +/// the ProgramState. This is implementing using llvm::ImmutableMap. +/// +/// \code +/// State = State->set(K, V); +/// const Value *V = State->get(K); // Returns NULL if not in the map. +/// State = State->remove(K); +/// NameTy Map = State->get(); +/// \endcode +/// +/// The macro should not be used inside namespaces, or for traits that must +/// be accessible from more than one translation unit. +#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value) \ + REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, \ + CLANG_ENTO_PROGRAMSTATE_MAP(Key, Value)) + +/// Declares an immutable map type \p Name and registers the factory +/// for such maps in the program state, but does not add the map itself +/// to the program state. Useful for managing lifetime of maps that are used +/// as elements of other program state data structures. +#define REGISTER_MAP_FACTORY_WITH_PROGRAMSTATE(Name, Key, Value) \ + using Name = llvm::ImmutableMap; \ + REGISTER_FACTORY_WITH_PROGRAMSTATE(Name) + +/// Declares an immutable set of type \p NameTy, suitable for placement into +/// the ProgramState. This is implementing using llvm::ImmutableSet. +/// +/// \code +/// State = State->add(E); +/// State = State->remove(E); +/// bool Present = State->contains(E); +/// NameTy Set = State->get(); +/// \endcode +/// +/// The macro should not be used inside namespaces, or for traits that must +/// be accessible from more than one translation unit. +#define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \ + REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet) + +/// Declares an immutable set type \p Name and registers the factory +/// for such sets in the program state, but does not add the set itself +/// to the program state. Useful for managing lifetime of sets that are used +/// as elements of other program state data structures. +#define REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(Name, Elem) \ + using Name = llvm::ImmutableSet; \ + REGISTER_FACTORY_WITH_PROGRAMSTATE(Name) + +/// Declares an immutable list type \p NameTy, suitable for placement into +/// the ProgramState. This is implementing using llvm::ImmutableList. +/// +/// \code +/// State = State->add(E); // Adds to the /end/ of the list. +/// bool Present = State->contains(E); +/// NameTy List = State->get(); +/// \endcode +/// +/// The macro should not be used inside namespaces, or for traits that must +/// be accessible from more than one translation unit. +#define REGISTER_LIST_WITH_PROGRAMSTATE(Name, Elem) \ + REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableList) + +/// Declares an immutable list of type \p Name and registers the factory +/// for such lists in the program state, but does not add the list itself +/// to the program state. Useful for managing lifetime of lists that are used +/// as elements of other program state data structures. +#define REGISTER_LIST_FACTORY_WITH_PROGRAMSTATE(Name, Elem) \ + using Name = llvm::ImmutableList; \ + REGISTER_FACTORY_WITH_PROGRAMSTATE(Name) + +// Partial-specialization for ImmutableMap. +template +struct ProgramStatePartialTrait> { + using data_type = llvm::ImmutableMap; + using context_type = typename data_type::Factory &; + using key_type = Key; + using value_type = Data; + using lookup_type = const value_type *; + + static data_type MakeData(void *const *p) { + return p ? data_type((typename data_type::TreeTy *)*p) : data_type(nullptr); + } + + static void *MakeVoidPtr(data_type B) { return B.getRoot(); } + + static lookup_type Lookup(data_type B, key_type K) { return B.lookup(K); } + + static data_type Set(data_type B, key_type K, value_type E, context_type F) { + return F.add(B, K, E); + } + + static data_type Remove(data_type B, key_type K, context_type F) { + return F.remove(B, K); + } + + static bool Contains(data_type B, key_type K) { return B.contains(K); } + + static context_type MakeContext(void *p) { + return *((typename data_type::Factory *)p); + } + + static void *CreateContext(llvm::BumpPtrAllocator &Alloc) { + return new typename data_type::Factory(Alloc); + } + + static void DeleteContext(void *Ctx) { + delete (typename data_type::Factory *)Ctx; + } +}; + +// Partial-specialization for ImmutableSet. +template +struct ProgramStatePartialTrait> { + using data_type = llvm::ImmutableSet; + using context_type = typename data_type::Factory &; + using key_type = Key; + + static data_type MakeData(void *const *p) { + return p ? data_type((typename data_type::TreeTy *)*p) : data_type(nullptr); + } + + static void *MakeVoidPtr(data_type B) { return B.getRoot(); } + + static data_type Add(data_type B, key_type K, context_type F) { + return F.add(B, K); + } + + static data_type Remove(data_type B, key_type K, context_type F) { + return F.remove(B, K); + } + + static bool Contains(data_type B, key_type K) { return B.contains(K); } + + static context_type MakeContext(void *p) { + return *((typename data_type::Factory *)p); + } + + static void *CreateContext(llvm::BumpPtrAllocator &Alloc) { + return new typename data_type::Factory(Alloc); + } + + static void DeleteContext(void *Ctx) { + delete (typename data_type::Factory *)Ctx; + } +}; + +// Partial-specialization for ImmutableList. +template struct ProgramStatePartialTrait> { + using data_type = llvm::ImmutableList; + using key_type = T; + using context_type = typename data_type::Factory &; + + static data_type Add(data_type L, key_type K, context_type F) { + return F.add(K, L); + } + + static bool Contains(data_type L, key_type K) { return L.contains(K); } + + static data_type MakeData(void *const *p) { + return p ? data_type((const llvm::ImmutableListImpl *)*p) + : data_type(nullptr); + } + + static void *MakeVoidPtr(data_type D) { + return const_cast *>(D.getInternalPointer()); + } + + static context_type MakeContext(void *p) { + return *((typename data_type::Factory *)p); + } + + static void *CreateContext(llvm::BumpPtrAllocator &Alloc) { + return new typename data_type::Factory(Alloc); + } + + static void DeleteContext(void *Ctx) { + delete (typename data_type::Factory *)Ctx; + } +}; + +template struct DefaultProgramStatePartialTraitImpl { + using data_type = T; + static T MakeData(void *const *P) { return P ? (T)(uintptr_t)*P : T{}; } + static void *MakeVoidPtr(T D) { return (void *)(uintptr_t)D; } +}; + +// Partial specialization for integral types. +template +struct ProgramStatePartialTrait::value>> + : DefaultProgramStatePartialTraitImpl {}; + +// Partial specialization for enums. +template +struct ProgramStatePartialTrait::value>> + : DefaultProgramStatePartialTraitImpl {}; + +// Partial specialization for pointers. +template +struct ProgramStatePartialTrait + : DefaultProgramStatePartialTraitImpl {}; } // namespace ento } // namespace clang diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h index 0ea26bf2e509b..9a3f277dd6ddd 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h @@ -14,29 +14,28 @@ namespace clang { namespace ento { - class ProgramState; - class ProgramStateManager; - void ProgramStateRetain(const ProgramState *state); - void ProgramStateRelease(const ProgramState *state); -} -} +class ProgramState; +class ProgramStateManager; +void ProgramStateRetain(const ProgramState *state); +void ProgramStateRelease(const ProgramState *state); +} // namespace ento +} // namespace clang namespace llvm { - template <> struct IntrusiveRefCntPtrInfo { - static void retain(const clang::ento::ProgramState *state) { - clang::ento::ProgramStateRetain(state); - } - static void release(const clang::ento::ProgramState *state) { - clang::ento::ProgramStateRelease(state); - } - }; -} +template <> struct IntrusiveRefCntPtrInfo { + static void retain(const clang::ento::ProgramState *state) { + clang::ento::ProgramStateRetain(state); + } + static void release(const clang::ento::ProgramState *state) { + clang::ento::ProgramStateRelease(state); + } +}; +} // namespace llvm namespace clang { namespace ento { - typedef IntrusiveRefCntPtr ProgramStateRef; -} +typedef IntrusiveRefCntPtr ProgramStateRef; } +} // namespace clang #endif - diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index d7cff49036cb8..14a507101b7a8 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -108,7 +108,8 @@ class SValBuilder { /// Evaluates a given SVal. If the SVal has only one possible (integer) value, /// that value is returned. Otherwise, returns NULL. - virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal val) = 0; + virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, + SVal val) = 0; /// Tries to get the minimal possible (integer) value of a given SVal. If the /// constraint manager cannot provide an useful answer, this returns NULL. @@ -124,14 +125,14 @@ class SValBuilder { virtual SVal simplifySVal(ProgramStateRef State, SVal Val) = 0; /// Constructs a symbolic expression for two non-location values. - SVal makeSymExprValNN(BinaryOperator::Opcode op, - NonLoc lhs, NonLoc rhs, QualType resultTy); + SVal makeSymExprValNN(BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, + QualType resultTy); SVal evalUnaryOp(ProgramStateRef state, UnaryOperator::Opcode opc, - SVal operand, QualType type); + SVal operand, QualType type); - SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, - SVal lhs, SVal rhs, QualType type); + SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, + SVal rhs, QualType type); /// \return Whether values in \p lhs and \p rhs are equal at \p state. ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs); @@ -150,9 +151,7 @@ class SValBuilder { return Context.getLangOpts().CPlusPlus ? Context.BoolTy : Context.IntTy; } - QualType getArrayIndexType() const { - return ArrayIndexTy; - } + QualType getArrayIndexType() const { return ArrayIndexTy; } BasicValueFactory &getBasicValueFactory() { return BasicVals; } const BasicValueFactory &getBasicValueFactory() const { return BasicVals; } @@ -167,15 +166,14 @@ class SValBuilder { // Forwarding methods to SymbolManager. - const SymbolConjured* conjureSymbol(const Stmt *stmt, + const SymbolConjured *conjureSymbol(const Stmt *stmt, const LocationContext *LCtx, - QualType type, - unsigned visitCount, + QualType type, unsigned visitCount, const void *symbolTag = nullptr) { return SymMgr.conjureSymbol(stmt, LCtx, type, visitCount, symbolTag); } - const SymbolConjured* conjureSymbol(const Expr *expr, + const SymbolConjured *conjureSymbol(const Expr *expr, const LocationContext *LCtx, unsigned visitCount, const void *symbolTag = nullptr) { @@ -194,19 +192,15 @@ class SValBuilder { /// The advantage of symbols derived/built from other symbols is that we /// preserve the relation between related(or even equivalent) expressions, so /// conjured symbols should be used sparingly. - DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, - const Expr *expr, + DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count); - DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, - const Expr *expr, + DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, - QualType type, - unsigned count); + QualType type, unsigned count); DefinedOrUnknownSVal conjureSymbolVal(const Stmt *stmt, const LocationContext *LCtx, - QualType type, - unsigned visitCount); + QualType type, unsigned visitCount); /// Conjure a symbol representing heap allocated memory region. /// @@ -232,13 +226,13 @@ class SValBuilder { const LocationContext *LCtx, unsigned Count); - DefinedOrUnknownSVal getDerivedRegionValueSymbolVal( - SymbolRef parentSymbol, const TypedValueRegion *region); + DefinedOrUnknownSVal + getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, + const TypedValueRegion *region); DefinedSVal getMetadataSymbolVal(const void *symbolTag, - const MemRegion *region, - const Expr *expr, QualType type, - const LocationContext *LCtx, + const MemRegion *region, const Expr *expr, + QualType type, const LocationContext *LCtx, unsigned count); DefinedSVal getMemberPointer(const NamedDecl *ND); @@ -283,10 +277,10 @@ class SValBuilder { SVal convertToArrayIndex(SVal val); - nonloc::ConcreteInt makeIntVal(const IntegerLiteral* integer) { - return nonloc::ConcreteInt( - BasicVals.getValue(integer->getValue(), - integer->getType()->isUnsignedIntegerOrEnumerationType())); + nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer) { + return nonloc::ConcreteInt(BasicVals.getValue( + integer->getValue(), + integer->getType()->isUnsignedIntegerOrEnumerationType())); } nonloc::ConcreteInt makeBoolVal(const ObjCBoolLiteralExpr *boolean) { @@ -295,7 +289,7 @@ class SValBuilder { nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *boolean); - nonloc::ConcreteInt makeIntVal(const llvm::APSInt& integer) { + nonloc::ConcreteInt makeIntVal(const llvm::APSInt &integer) { return nonloc::ConcreteInt(BasicVals.getValue(integer)); } @@ -303,7 +297,7 @@ class SValBuilder { return loc::ConcreteInt(BasicVals.getValue(integer)); } - NonLoc makeIntVal(const llvm::APInt& integer, bool isUnsigned) { + NonLoc makeIntVal(const llvm::APInt &integer, bool isUnsigned) { return nonloc::ConcreteInt(BasicVals.getValue(integer, isUnsigned)); } @@ -408,7 +402,7 @@ class SValBuilder { const StackFrameContext *SFC); }; -SValBuilder* createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, +SValBuilder *createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context, ProgramStateManager &stateMgr); diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h index b10f416f44356..ed897d1ba42ee 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h @@ -65,15 +65,15 @@ template class SValVisitor { /// subclasses. template class SymExprVisitor { public: - -#define DISPATCH(CLASS) \ - return static_cast(this)->Visit ## CLASS(cast(S)) +#define DISPATCH(CLASS) \ + return static_cast(this)->Visit##CLASS(cast(S)) RetTy Visit(SymbolRef S) { // Dispatch to VisitSymbolFoo for each SymbolFoo. switch (S->getKind()) { -#define SYMBOL(Id, Parent) \ - case SymExpr::Id ## Kind: DISPATCH(Id); +#define SYMBOL(Id, Parent) \ + case SymExpr::Id##Kind: \ + DISPATCH(Id); #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def" } llvm_unreachable("Unknown SymExpr kind!"); @@ -81,7 +81,8 @@ template class SymExprVisitor { // If the implementation chooses not to implement a certain visit method, fall // back on visiting the superclass. -#define SYMBOL(Id, Parent) RetTy Visit ## Id(const Id *S) { DISPATCH(Parent); } +#define SYMBOL(Id, Parent) \ + RetTy Visit##Id(const Id *S) { DISPATCH(Parent); } #define ABSTRACT_SYMBOL(Id, Parent) SYMBOL(Id, Parent) #include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def" @@ -95,14 +96,15 @@ template class SymExprVisitor { /// subclasses. template class MemRegionVisitor { public: - -#define DISPATCH(CLASS) \ - return static_cast(this)->Visit ## CLASS(cast(R)) +#define DISPATCH(CLASS) \ + return static_cast(this)->Visit##CLASS(cast(R)) RetTy Visit(const MemRegion *R) { // Dispatch to VisitFooRegion for each FooRegion. switch (R->getKind()) { -#define REGION(Id, Parent) case MemRegion::Id ## Kind: DISPATCH(Id); +#define REGION(Id, Parent) \ + case MemRegion::Id##Kind: \ + DISPATCH(Id); #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" } llvm_unreachable("Unknown MemRegion kind!"); @@ -110,10 +112,9 @@ template class MemRegionVisitor { // If the implementation chooses not to implement a certain visit method, fall // back on visiting the superclass. -#define REGION(Id, Parent) \ - RetTy Visit ## Id(const Id *R) { DISPATCH(Parent); } -#define ABSTRACT_REGION(Id, Parent) \ - REGION(Id, Parent) +#define REGION(Id, Parent) \ + RetTy Visit##Id(const Id *R) { DISPATCH(Parent); } +#define ABSTRACT_REGION(Id, Parent) REGION(Id, Parent) #include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" // Base case, ignore it. :) diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index c60528b7685fe..d370896e657ad 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -248,8 +248,8 @@ class NonLoc : public DefinedSVal { void dumpToStream(raw_ostream &Out) const; static bool isCompoundType(QualType T) { - return T->isArrayType() || T->isRecordType() || - T->isAnyComplexType() || T->isVectorType(); + return T->isArrayType() || T->isRecordType() || T->isAnyComplexType() || + T->isVectorType(); } static bool classof(SVal V) { @@ -290,13 +290,9 @@ class SymbolVal : public NonLoc { } LLVM_ATTRIBUTE_RETURNS_NONNULL - SymbolRef getSymbol() const { - return (const SymExpr *) Data; - } + SymbolRef getSymbol() const { return (const SymExpr *)Data; } - bool isExpression() const { - return !isa(getSymbol()); - } + bool isExpression() const { return !isa(getSymbol()); } static bool classof(SVal V) { return V.getKind() == SymbolValKind; } }; @@ -343,7 +339,7 @@ class CompoundVal : public NonLoc { public: LLVM_ATTRIBUTE_RETURNS_NONNULL - const CompoundValData* getValue() const { + const CompoundValData *getValue() const { return castDataAs(); } @@ -402,8 +398,7 @@ class PointerToMember : public NonLoc { const NamedDecl *getDecl() const; - template - const AdjustedDecl *getDeclAs() const { + template const AdjustedDecl *getDeclAs() const { return dyn_cast_or_null(getDecl()); } @@ -450,10 +445,9 @@ class MemRegionVal : public Loc { /// Get the underlining region and strip casts. LLVM_ATTRIBUTE_RETURNS_NONNULL - const MemRegion* stripCasts(bool StripBaseCasts = true) const; + const MemRegion *stripCasts(bool StripBaseCasts = true) const; - template - const REGION* getRegionAs() const { + template const REGION *getRegionAs() const { return dyn_cast(getRegion()); } diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index fac0c04ae2caa..efb5a1ddcfc8f 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -14,13 +14,13 @@ #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_STORE_H #include "clang/AST/Type.h" +#include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" -#include "clang/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallVector.h" @@ -128,9 +128,9 @@ class StoreManager { /// getRegionManager - Returns the internal RegionManager object that is /// used to query and manipulate MemRegion objects. - MemRegionManager& getRegionManager() { return MRMgr; } + MemRegionManager &getRegionManager() { return MRMgr; } - SValBuilder& getSValBuilder() { return svalBuilder; } + SValBuilder &getSValBuilder() { return svalBuilder; } virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) { return svalBuilder.makeLoc(MRMgr.getVarRegion(VD, LC)); @@ -161,8 +161,7 @@ class StoreManager { SVal evalDerivedToBase(SVal Derived, const CXXBasePath &CastPath); /// Evaluates a derived-to-base cast through a single level of derivation. - SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType, - bool IsVirtual); + SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType, bool IsVirtual); /// Attempts to do a down cast. Used to model BaseToDerived and C++ /// dynamic_cast. @@ -185,7 +184,8 @@ class StoreManager { std::optional castRegion(const MemRegion *region, QualType CastToTy); - virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, + virtual StoreRef removeDeadBindings(Store store, + const StackFrameContext *LCtx, SymbolReaper &SymReaper) = 0; virtual bool includedInBindings(Store store, @@ -225,20 +225,18 @@ class StoreManager { /// invalidated. This should include any regions explicitly invalidated /// even if they do not currently have bindings. Pass \c NULL if this /// information will not be used. - virtual StoreRef invalidateRegions(Store store, - ArrayRef Values, - const Expr *E, unsigned Count, - const LocationContext *LCtx, - const CallEvent *Call, - InvalidatedSymbols &IS, - RegionAndSymbolInvalidationTraits &ITraits, - InvalidatedRegions *InvalidatedTopLevel, - InvalidatedRegions *Invalidated) = 0; + virtual StoreRef invalidateRegions(Store store, ArrayRef Values, + const Expr *E, unsigned Count, + const LocationContext *LCtx, + const CallEvent *Call, + InvalidatedSymbols &IS, + RegionAndSymbolInvalidationTraits &ITraits, + InvalidatedRegions *InvalidatedTopLevel, + InvalidatedRegions *Invalidated) = 0; /// enterStackFrame - Let the StoreManager to do something when execution /// engine is about to execute into a callee. - StoreRef enterStackFrame(Store store, - const CallEvent &Call, + StoreRef enterStackFrame(Store store, const CallEvent &Call, const StackFrameContext *CalleeCtx); /// Finds the transitive closure of symbols within the given region. @@ -255,13 +253,13 @@ class StoreManager { virtual ~BindingsHandler(); /// \return whether the iteration should continue. - virtual bool HandleBinding(StoreManager& SMgr, Store store, + virtual bool HandleBinding(StoreManager &SMgr, Store store, const MemRegion *region, SVal val) = 0; }; class FindUniqueBinding : public BindingsHandler { SymbolRef Sym; - const MemRegion* Binding = nullptr; + const MemRegion *Binding = nullptr; bool First = true; public: @@ -269,13 +267,13 @@ class StoreManager { explicit operator bool() { return First && Binding; } - bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R, + bool HandleBinding(StoreManager &SMgr, Store store, const MemRegion *R, SVal val) override; const MemRegion *getRegion() { return Binding; } }; /// iterBindings - Iterate over the bindings in the Store. - virtual void iterBindings(Store store, BindingsHandler& f) = 0; + virtual void iterBindings(Store store, BindingsHandler &f) = 0; protected: const ElementRegion *MakeElementRegion(const SubRegion *baseRegion, @@ -286,15 +284,13 @@ class StoreManager { SVal getLValueFieldOrIvar(const Decl *decl, SVal base); }; -inline StoreRef::StoreRef(Store store, StoreManager & smgr) +inline StoreRef::StoreRef(Store store, StoreManager &smgr) : store(store), mgr(smgr) { if (store) mgr.incrementReferenceCount(store); } -inline StoreRef::StoreRef(const StoreRef &sr) - : store(sr.store), mgr(sr.mgr) -{ +inline StoreRef::StoreRef(const StoreRef &sr) : store(sr.store), mgr(sr.mgr) { if (store) mgr.incrementReferenceCount(store); } diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h index 1a56153da11e2..cd8892546af38 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h @@ -20,7 +20,6 @@ namespace ento { namespace summMgr { - /* Key kinds: - C functions @@ -34,24 +33,16 @@ namespace summMgr { - Class, function name + parameter types + const */ -class SummaryKey { - -}; - -} // end namespace clang::summMgr - -class SummaryManagerImpl { - -}; +class SummaryKey {}; +} // namespace summMgr -template -class SummaryManager : SummaryManagerImpl { +class SummaryManagerImpl {}; -}; +template class SummaryManager : SummaryManagerImpl {}; -} // end GR namespace +} // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h index 862a30c0e7363..1ef083c3781fb 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h @@ -134,9 +134,7 @@ class SymbolData : public SymExpr { SymbolID getSymbolID() const { return Sym; } - unsigned computeComplexity() const override { - return 1; - }; + unsigned computeComplexity() const override { return 1; }; // Implement isa support. static inline bool classof(const SymExpr *SE) { diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index 3b64d38ee2b23..d2ef0c2938cb9 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -38,7 +38,7 @@ namespace ento { class BasicValueFactory; class StoreManager; -///A symbol representing the value stored at a MemRegion. +/// A symbol representing the value stored at a MemRegion. class SymbolRegionValue : public SymbolData { const TypedValueRegion *R; @@ -50,14 +50,15 @@ class SymbolRegionValue : public SymbolData { } LLVM_ATTRIBUTE_RETURNS_NONNULL - const TypedValueRegion* getRegion() const { return R; } + const TypedValueRegion *getRegion() const { return R; } - static void Profile(llvm::FoldingSetNodeID& profile, const TypedValueRegion* R) { - profile.AddInteger((unsigned) SymbolRegionValueKind); + static void Profile(llvm::FoldingSetNodeID &profile, + const TypedValueRegion *R) { + profile.AddInteger((unsigned)SymbolRegionValueKind); profile.AddPointer(R); } - void Profile(llvm::FoldingSetNodeID& profile) override { + void Profile(llvm::FoldingSetNodeID &profile) override { Profile(profile, R); } @@ -109,10 +110,10 @@ class SymbolConjured : public SymbolData { void dumpToStream(raw_ostream &os) const override; - static void Profile(llvm::FoldingSetNodeID& profile, const Stmt *S, + static void Profile(llvm::FoldingSetNodeID &profile, const Stmt *S, QualType T, unsigned Count, const LocationContext *LCtx, const void *SymbolTag) { - profile.AddInteger((unsigned) SymbolConjuredKind); + profile.AddInteger((unsigned)SymbolConjuredKind); profile.AddPointer(S); profile.AddPointer(LCtx); profile.Add(T); @@ -120,7 +121,7 @@ class SymbolConjured : public SymbolData { profile.AddPointer(SymbolTag); } - void Profile(llvm::FoldingSetNodeID& profile) override { + void Profile(llvm::FoldingSetNodeID &profile) override { Profile(profile, S, T, Count, LCtx, SymbolTag); } @@ -156,14 +157,14 @@ class SymbolDerived : public SymbolData { void dumpToStream(raw_ostream &os) const override; const MemRegion *getOriginRegion() const override { return getRegion(); } - static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent, + static void Profile(llvm::FoldingSetNodeID &profile, SymbolRef parent, const TypedValueRegion *r) { - profile.AddInteger((unsigned) SymbolDerivedKind); + profile.AddInteger((unsigned)SymbolDerivedKind); profile.AddPointer(r); profile.AddPointer(parent); } - void Profile(llvm::FoldingSetNodeID& profile) override { + void Profile(llvm::FoldingSetNodeID &profile) override { Profile(profile, parentSymbol, R); } @@ -194,12 +195,12 @@ class SymbolExtent : public SymbolData { void dumpToStream(raw_ostream &os) const override; - static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) { - profile.AddInteger((unsigned) SymbolExtentKind); + static void Profile(llvm::FoldingSetNodeID &profile, const SubRegion *R) { + profile.AddInteger((unsigned)SymbolExtentKind); profile.AddPointer(R); } - void Profile(llvm::FoldingSetNodeID& profile) override { + void Profile(llvm::FoldingSetNodeID &profile) override { Profile(profile, R); } @@ -214,7 +215,7 @@ class SymbolExtent : public SymbolData { /// dead-symbol sweeping AND their associated regions are still alive. /// Intended for use by checkers. class SymbolMetadata : public SymbolData { - const MemRegion* R; + const MemRegion *R; const Stmt *S; QualType T; const LocationContext *LCtx; @@ -222,50 +223,50 @@ class SymbolMetadata : public SymbolData { const void *Tag; public: - SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t, + SymbolMetadata(SymbolID sym, const MemRegion *r, const Stmt *s, QualType t, const LocationContext *LCtx, unsigned count, const void *tag) : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), LCtx(LCtx), Count(count), Tag(tag) { - assert(r); - assert(s); - assert(isValidTypeForSymbol(t)); - assert(LCtx); - assert(tag); - } + assert(r); + assert(s); + assert(isValidTypeForSymbol(t)); + assert(LCtx); + assert(tag); + } - LLVM_ATTRIBUTE_RETURNS_NONNULL - const MemRegion *getRegion() const { return R; } + LLVM_ATTRIBUTE_RETURNS_NONNULL + const MemRegion *getRegion() const { return R; } - LLVM_ATTRIBUTE_RETURNS_NONNULL - const Stmt *getStmt() const { return S; } + LLVM_ATTRIBUTE_RETURNS_NONNULL + const Stmt *getStmt() const { return S; } - LLVM_ATTRIBUTE_RETURNS_NONNULL - const LocationContext *getLocationContext() const { return LCtx; } + LLVM_ATTRIBUTE_RETURNS_NONNULL + const LocationContext *getLocationContext() const { return LCtx; } - unsigned getCount() const { return Count; } + unsigned getCount() const { return Count; } - LLVM_ATTRIBUTE_RETURNS_NONNULL - const void *getTag() const { return Tag; } + LLVM_ATTRIBUTE_RETURNS_NONNULL + const void *getTag() const { return Tag; } - QualType getType() const override; + QualType getType() const override; - StringRef getKindStr() const override; + StringRef getKindStr() const override; - void dumpToStream(raw_ostream &os) const override; + void dumpToStream(raw_ostream &os) const override; - static void Profile(llvm::FoldingSetNodeID &profile, const MemRegion *R, - const Stmt *S, QualType T, const LocationContext *LCtx, - unsigned Count, const void *Tag) { - profile.AddInteger((unsigned)SymbolMetadataKind); - profile.AddPointer(R); - profile.AddPointer(S); - profile.Add(T); - profile.AddPointer(LCtx); - profile.AddInteger(Count); - profile.AddPointer(Tag); - } + static void Profile(llvm::FoldingSetNodeID &profile, const MemRegion *R, + const Stmt *S, QualType T, const LocationContext *LCtx, + unsigned Count, const void *Tag) { + profile.AddInteger((unsigned)SymbolMetadataKind); + profile.AddPointer(R); + profile.AddPointer(S); + profile.Add(T); + profile.AddPointer(LCtx); + profile.AddInteger(Count); + profile.AddPointer(Tag); + } - void Profile(llvm::FoldingSetNodeID& profile) override { + void Profile(llvm::FoldingSetNodeID &profile) override { Profile(profile, R, S, T, LCtx, Count, Tag); } @@ -307,15 +308,15 @@ class SymbolCast : public SymExpr { void dumpToStream(raw_ostream &os) const override; - static void Profile(llvm::FoldingSetNodeID& ID, - const SymExpr *In, QualType From, QualType To) { - ID.AddInteger((unsigned) SymbolCastKind); + static void Profile(llvm::FoldingSetNodeID &ID, const SymExpr *In, + QualType From, QualType To) { + ID.AddInteger((unsigned)SymbolCastKind); ID.AddPointer(In); ID.Add(From); ID.Add(To); } - void Profile(llvm::FoldingSetNodeID& ID) override { + void Profile(llvm::FoldingSetNodeID &ID) override { Profile(ID, Operand, FromTy, ToTy); } @@ -336,7 +337,8 @@ class UnarySymExpr : public SymExpr { : SymExpr(UnarySymExprKind), Operand(In), Op(Op), T(T) { // Note, some unary operators are modeled as a binary operator. E.g. ++x is // modeled as x + 1. - assert((Op == UO_Minus || Op == UO_Not) && "non-supported unary expression"); + assert((Op == UO_Minus || Op == UO_Not) && + "non-supported unary expression"); // Unary expressions are results of arithmetic. Pointer arithmetic is not // handled by unary expressions, but it is instead handled by applying // sub-regions to regions. @@ -491,27 +493,26 @@ class SymbolManager { SymbolDependTy SymbolDependencies; unsigned SymbolCounter = 0; - llvm::BumpPtrAllocator& BPAlloc; + llvm::BumpPtrAllocator &BPAlloc; BasicValueFactory &BV; ASTContext &Ctx; public: SymbolManager(ASTContext &ctx, BasicValueFactory &bv, - llvm::BumpPtrAllocator& bpalloc) + llvm::BumpPtrAllocator &bpalloc) : SymbolDependencies(16), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {} static bool canSymbolicate(QualType T); /// Make a unique symbol for MemRegion R according to its kind. - const SymbolRegionValue* getRegionValueSymbol(const TypedValueRegion* R); + const SymbolRegionValue *getRegionValueSymbol(const TypedValueRegion *R); - const SymbolConjured* conjureSymbol(const Stmt *E, - const LocationContext *LCtx, - QualType T, + const SymbolConjured *conjureSymbol(const Stmt *E, + const LocationContext *LCtx, QualType T, unsigned VisitCount, const void *SymbolTag = nullptr); - const SymbolConjured* conjureSymbol(const Expr *E, + const SymbolConjured *conjureSymbol(const Expr *E, const LocationContext *LCtx, unsigned VisitCount, const void *SymbolTag = nullptr) { @@ -533,20 +534,20 @@ class SymbolManager { unsigned VisitCount, const void *SymbolTag = nullptr); - const SymbolCast* getCastSymbol(const SymExpr *Operand, - QualType From, QualType To); + const SymbolCast *getCastSymbol(const SymExpr *Operand, QualType From, + QualType To); const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, - const llvm::APSInt& rhs, QualType t); + const llvm::APSInt &rhs, QualType t); const SymIntExpr *getSymIntExpr(const SymExpr &lhs, BinaryOperator::Opcode op, - const llvm::APSInt& rhs, QualType t) { + const llvm::APSInt &rhs, QualType t) { return getSymIntExpr(&lhs, op, rhs, t); } - const IntSymExpr *getIntSymExpr(const llvm::APSInt& lhs, - BinaryOperator::Opcode op, - const SymExpr *rhs, QualType t); + const IntSymExpr *getIntSymExpr(const llvm::APSInt &lhs, + BinaryOperator::Opcode op, const SymExpr *rhs, + QualType t); const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t); @@ -554,9 +555,7 @@ class SymbolManager { const UnarySymExpr *getUnarySymExpr(const SymExpr *operand, UnaryOperator::Opcode op, QualType t); - QualType getType(const SymExpr *SE) const { - return SE->getType(); - } + QualType getType(const SymExpr *SE) const { return SE->getType(); } /// Add artificial symbol dependency. /// @@ -571,10 +570,7 @@ class SymbolManager { /// A class responsible for cleaning up unused symbols. class SymbolReaper { - enum SymbolStatus { - NotProcessed, - HaveMarkedDependents - }; + enum SymbolStatus { NotProcessed, HaveMarkedDependents }; using SymbolSetTy = llvm::DenseSet; using SymbolMapTy = llvm::DenseMap; @@ -592,7 +588,7 @@ class SymbolReaper { const StackFrameContext *LCtx; const Stmt *Loc; - SymbolManager& SymMgr; + SymbolManager &SymMgr; StoreRef reapedStore; llvm::DenseMap includedRegionCache; @@ -640,9 +636,7 @@ class SymbolReaper { /// /// This should only be called once all marking of dead symbols has completed. /// (For checkers, this means only in the checkDeadSymbols callback.) - bool isDead(SymbolRef sym) { - return !isLive(sym); - } + bool isDead(SymbolRef sym) { return !isLive(sym); } void markLive(const MemRegion *region); void markLazilyCopied(const MemRegion *region); diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h index 7beb7ddf5bce6..196421ff8d139 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h @@ -31,18 +31,11 @@ class WorkListUnit { unsigned blockIdx; // This is the index of the next statement. public: - WorkListUnit(ExplodedNode *N, BlockCounter C, - const CFGBlock *B, unsigned idx) - : node(N), - counter(C), - block(B), - blockIdx(idx) {} + WorkListUnit(ExplodedNode *N, BlockCounter C, const CFGBlock *B, unsigned idx) + : node(N), counter(C), block(B), blockIdx(idx) {} explicit WorkListUnit(ExplodedNode *N, BlockCounter C) - : node(N), - counter(C), - block(nullptr), - blockIdx(0) {} + : node(N), counter(C), block(nullptr), blockIdx(0) {} /// Returns the node associated with the worklist unit. ExplodedNode *getNode() const { return node; } @@ -59,11 +52,12 @@ class WorkListUnit { class WorkList { BlockCounter CurrentCounter; + public: virtual ~WorkList(); virtual bool hasWork() const = 0; - virtual void enqueue(const WorkListUnit& U) = 0; + virtual void enqueue(const WorkListUnit &U) = 0; void enqueue(ExplodedNode *N, const CFGBlock *B, unsigned idx) { enqueue(WorkListUnit(N, CurrentCounter, B, idx)); @@ -87,8 +81,8 @@ class WorkList { static std::unique_ptr makeUnexploredFirstPriorityLocationQueue(); }; -} // end ento namespace +} // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h index f3b1c1f206459..145473866eb4e 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h @@ -53,6 +53,6 @@ CreateAnalysisConsumer(CompilerInstance &CI); } // namespace ento -} // end clang namespace +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 43dbfb1585151..79c4a2c2a47ac 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -98,7 +98,6 @@ class CheckerRegistry { /// checkers that depend on them. void initializeRegistry(const CheckerManager &Mgr); - private: /// Default initialization function for checkers -- since CheckerManager /// includes this header, we need to make it a template parameter, and since diff --git a/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h b/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h index 7b7087622bc2f..59e6ce8c8a7f9 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h @@ -37,7 +37,7 @@ class ModelConsumer : public ASTConsumer { private: llvm::StringMap &Bodies; }; -} -} +} // namespace ento +} // namespace clang #endif diff --git a/clang/lib/Analysis/AnalysisDeclContext.cpp b/clang/lib/Analysis/AnalysisDeclContext.cpp index d3a1a993711fb..d4c4d518f0a38 100644 --- a/clang/lib/Analysis/AnalysisDeclContext.cpp +++ b/clang/lib/Analysis/AnalysisDeclContext.cpp @@ -50,7 +50,8 @@ using namespace clang; -using ManagedAnalysisMap = llvm::DenseMap>; +using ManagedAnalysisMap = + llvm::DenseMap>; AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr, const Decl *D, @@ -104,8 +105,7 @@ Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const { } } return Body; - } - else if (const auto *MD = dyn_cast(D)) { + } else if (const auto *MD = dyn_cast(D)) { Stmt *Body = MD->getBody(); if (ADCMgr && ADCMgr->synthesizeBodies()) { Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD); @@ -183,7 +183,7 @@ void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) { // Default construct an entry for 'stmt'. if (const auto *e = dyn_cast(stmt)) stmt = e->IgnoreParens(); - (void) (*forcedBlkExprs)[stmt]; + (void)(*forcedBlkExprs)[stmt]; } const CFGBlock * @@ -192,7 +192,7 @@ AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) { if (const auto *e = dyn_cast(stmt)) stmt = e->IgnoreParens(); CFG::BuildOptions::ForcedBlkExprs::const_iterator itr = - forcedBlkExprs->find(stmt); + forcedBlkExprs->find(stmt); assert(itr != forcedBlkExprs->end()); return itr->second; } @@ -259,7 +259,8 @@ CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() { return nullptr; } -CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() { +CFGReverseBlockReachabilityAnalysis * +AnalysisDeclContext::getCFGReachablityAnalysis() { if (CFA) return CFA.get(); @@ -400,8 +401,7 @@ LocationContextManager &AnalysisDeclContext::getLocationContextManager() { // FoldingSet profiling. //===----------------------------------------------------------------------===// -void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID, - ContextKind ck, +void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, AnalysisDeclContext *ctx, const LocationContext *parent, const void *data) { @@ -430,8 +430,8 @@ const StackFrameContext *LocationContextManager::getStackFrame( llvm::FoldingSetNodeID ID; StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx); void *InsertPos; - auto *L = - cast_or_null(Contexts.FindNodeOrInsertPos(ID, InsertPos)); + auto *L = cast_or_null( + Contexts.FindNodeOrInsertPos(ID, InsertPos)); if (!L) { L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID); Contexts.InsertNode(L, InsertPos); @@ -445,9 +445,8 @@ const BlockInvocationContext *LocationContextManager::getBlockInvocationContext( llvm::FoldingSetNodeID ID; BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data); void *InsertPos; - auto *L = - cast_or_null(Contexts.FindNodeOrInsertPos(ID, - InsertPos)); + auto *L = cast_or_null( + Contexts.FindNodeOrInsertPos(ID, InsertPos)); if (!L) { L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID); Contexts.InsertNode(L, InsertPos); @@ -588,14 +587,15 @@ LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); } namespace { -class FindBlockDeclRefExprsVals : public StmtVisitor{ +class FindBlockDeclRefExprsVals + : public StmtVisitor { BumpVector &BEVals; BumpVectorContext &BC; llvm::SmallPtrSet Visited; llvm::SmallPtrSet IgnoredContexts; public: - FindBlockDeclRefExprsVals(BumpVector &bevals, + FindBlockDeclRefExprsVals(BumpVector &bevals, BumpVectorContext &bc) : BEVals(bevals), BC(bc) {} @@ -623,7 +623,8 @@ class FindBlockDeclRefExprsVals : public StmtVisitor{ void VisitPseudoObjectExpr(PseudoObjectExpr *PE) { for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(), - et = PE->semantics_end(); it != et; ++it) { + et = PE->semantics_end(); + it != et; ++it) { Expr *Semantic = *it; if (auto *OVE = dyn_cast(Semantic)) Semantic = OVE->getSourceExpr(); @@ -636,14 +637,13 @@ class FindBlockDeclRefExprsVals : public StmtVisitor{ using DeclVec = BumpVector; -static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD, - void *&Vec, +static DeclVec *LazyInitializeReferencedDecls(const BlockDecl *BD, void *&Vec, llvm::BumpPtrAllocator &A) { if (Vec) - return (DeclVec*) Vec; + return (DeclVec *)Vec; BumpVectorContext BC(A); - DeclVec *BV = (DeclVec*) A.Allocate(); + DeclVec *BV = (DeclVec *)A.Allocate(); new (BV) DeclVec(BC, 10); // Go through the capture list. @@ -662,17 +662,18 @@ static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD, llvm::iterator_range AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) { if (!ReferencedBlockVars) - ReferencedBlockVars = new llvm::DenseMap(); + ReferencedBlockVars = new llvm::DenseMap(); const DeclVec *V = LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A); return llvm::make_range(V->begin(), V->end()); } -std::unique_ptr &AnalysisDeclContext::getAnalysisImpl(const void *tag) { +std::unique_ptr & +AnalysisDeclContext::getAnalysisImpl(const void *tag) { if (!ManagedAnalyses) ManagedAnalyses = new ManagedAnalysisMap(); - ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses; + ManagedAnalysisMap *M = (ManagedAnalysisMap *)ManagedAnalyses; return (*M)[tag]; } @@ -685,18 +686,17 @@ ManagedAnalysis::~ManagedAnalysis() = default; AnalysisDeclContext::~AnalysisDeclContext() { delete forcedBlkExprs; delete ReferencedBlockVars; - delete (ManagedAnalysisMap*) ManagedAnalyses; + delete (ManagedAnalysisMap *)ManagedAnalyses; } LocationContext::~LocationContext() = default; -LocationContextManager::~LocationContextManager() { - clear(); -} +LocationContextManager::~LocationContextManager() { clear(); } void LocationContextManager::clear() { for (llvm::FoldingSet::iterator I = Contexts.begin(), - E = Contexts.end(); I != E; ) { + E = Contexts.end(); + I != E;) { LocationContext *LC = &*I; ++I; delete LC; diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp index 127e843d4ead2..9a6f158bfde42 100644 --- a/clang/lib/Analysis/BodyFarm.cpp +++ b/clang/lib/Analysis/BodyFarm.cpp @@ -43,7 +43,7 @@ static bool isDispatchBlock(QualType Ty) { // Check if the block pointer type takes no arguments and // returns void. const FunctionProtoType *FT = - BPT->getPointeeType()->getAs(); + BPT->getPointeeType()->getAs(); return FT && FT->getReturnType()->isVoidType() && FT->getNumParams() == 0; } @@ -60,7 +60,7 @@ class ASTMaker { BinaryOperator::Opcode Op); /// Create a new compound stmt using the provided statements. - CompoundStmt *makeCompound(ArrayRef); + CompoundStmt *makeCompound(ArrayRef); /// Create a new DeclRefExpr for the referenced variable. DeclRefExpr *makeDeclRefExpr(const VarDecl *D, @@ -115,7 +115,7 @@ class ASTMaker { private: ASTContext &C; }; -} +} // namespace BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS, QualType Ty) { @@ -126,8 +126,7 @@ BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS, BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS, BinaryOperator::Opcode Op) { - assert(BinaryOperator::isLogicalOp(Op) || - BinaryOperator::isComparisonOp(Op)); + assert(BinaryOperator::isLogicalOp(Op) || BinaryOperator::isComparisonOp(Op)); return BinaryOperator::Create( C, const_cast(LHS), const_cast(RHS), Op, C.getLogicalOperationType(), VK_PRValue, OK_Ordinary, SourceLocation(), @@ -139,9 +138,9 @@ CompoundStmt *ASTMaker::makeCompound(ArrayRef Stmts) { SourceLocation()); } -DeclRefExpr *ASTMaker::makeDeclRefExpr( - const VarDecl *D, - bool RefersToEnclosingVariableOrCapture) { +DeclRefExpr * +ASTMaker::makeDeclRefExpr(const VarDecl *D, + bool RefersToEnclosingVariableOrCapture) { QualType Type = D->getType().getNonReferenceType(); DeclRefExpr *DR = DeclRefExpr::Create( @@ -164,9 +163,8 @@ ImplicitCastExpr * ASTMaker::makeLvalueToRvalue(const VarDecl *Arg, bool RefersToEnclosingVariableOrCapture) { QualType Type = Arg->getType().getNonReferenceType(); - return makeLvalueToRvalue(makeDeclRefExpr(Arg, - RefersToEnclosingVariableOrCapture), - Type); + return makeLvalueToRvalue( + makeDeclRefExpr(Arg, RefersToEnclosingVariableOrCapture), Type); } ImplicitCastExpr *ASTMaker::makeImplicitCast(const Expr *Arg, QualType Ty, @@ -191,7 +189,7 @@ CastExpr *ASTMaker::makeReferenceCast(const Expr *Arg, QualType Ty) { Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) { if (Arg->getType() == Ty) - return const_cast(Arg); + return const_cast(Arg); return makeImplicitCast(Arg, Ty, CK_IntegralCast); } @@ -206,9 +204,9 @@ ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) { ObjCIvarRefExpr *ASTMaker::makeObjCIvarRef(const Expr *Base, const ObjCIvarDecl *IVar) { - return new (C) ObjCIvarRefExpr(const_cast(IVar), + return new (C) ObjCIvarRefExpr(const_cast(IVar), IVar->getType(), SourceLocation(), - SourceLocation(), const_cast(Base), + SourceLocation(), const_cast(Base), /*arrow=*/true, /*free=*/false); } @@ -231,7 +229,7 @@ MemberExpr *ASTMaker::makeMemberExpression(Expr *base, ValueDecl *MemberDecl, C, base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), MemberDecl, FoundDecl, DeclarationNameInfo(MemberDecl->getDeclName(), SourceLocation()), - /* TemplateArgumentListInfo=*/ nullptr, MemberDecl->getType(), ValueKind, + /* TemplateArgumentListInfo=*/nullptr, MemberDecl->getType(), ValueKind, OK_Ordinary, NOUR_None); } @@ -240,7 +238,7 @@ ValueDecl *ASTMaker::findMemberField(const RecordDecl *RD, StringRef Name) { CXXBasePaths Paths( /* FindAmbiguities=*/false, /* RecordPaths=*/false, - /* DetectVirtual=*/ false); + /* DetectVirtual=*/false); const IdentifierInfo &II = C.Idents.get(Name); DeclarationName DeclName = C.DeclarationNames.getIdentifier(&II); @@ -266,15 +264,13 @@ static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M, DeclRefExpr *Call = M.makeDeclRefExpr(Callback); Expr *SubExpr; if (Ty->isRValueReferenceType()) { - SubExpr = M.makeImplicitCast( - Call, Ty.getNonReferenceType(), CK_LValueToRValue); - } else if (Ty->isLValueReferenceType() && - Call->getType()->isFunctionType()) { + SubExpr = + M.makeImplicitCast(Call, Ty.getNonReferenceType(), CK_LValueToRValue); + } else if (Ty->isLValueReferenceType() && Call->getType()->isFunctionType()) { Ty = C.getPointerType(Ty.getNonReferenceType()); SubExpr = M.makeImplicitCast(Call, Ty, CK_FunctionToPointerDecay); - } else if (Ty->isLValueReferenceType() - && Call->getType()->isPointerType() - && Call->getType()->getPointeeType()->isFunctionType()){ + } else if (Ty->isLValueReferenceType() && Call->getType()->isPointerType() && + Call->getType()->getPointeeType()->isFunctionType()) { SubExpr = Call; } else { llvm_unreachable("Unexpected state"); @@ -294,14 +290,14 @@ static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M, assert(callOperatorDecl != nullptr); DeclRefExpr *callOperatorDeclRef = - DeclRefExpr::Create(/* Ctx =*/ C, - /* QualifierLoc =*/ NestedNameSpecifierLoc(), - /* TemplateKWLoc =*/ SourceLocation(), + DeclRefExpr::Create(/* Ctx =*/C, + /* QualifierLoc =*/NestedNameSpecifierLoc(), + /* TemplateKWLoc =*/SourceLocation(), const_cast(callOperatorDecl), - /* RefersToEnclosingVariableOrCapture=*/ false, - /* NameLoc =*/ SourceLocation(), - /* T =*/ callOperatorDecl->getType(), - /* VK =*/ VK_LValue); + /* RefersToEnclosingVariableOrCapture=*/false, + /* NameLoc =*/SourceLocation(), + /* T =*/callOperatorDecl->getType(), + /* VK =*/VK_LValue); return CXXOperatorCallExpr::Create( /*AstContext=*/C, OO_Call, callOperatorDeclRef, @@ -410,7 +406,7 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { // Lambda requires callback itself inserted as a first parameter. CallArgs.push_back( M.makeDeclRefExpr(Callback, - /* RefersToEnclosingVariableOrCapture=*/ true)); + /* RefersToEnclosingVariableOrCapture=*/true)); CallbackFunctionType = CallbackRecordDecl->getLambdaCallOperator() ->getType() ->getAs(); @@ -426,9 +422,9 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { // First two arguments are used for the flag and for the callback. if (D->getNumParams() != CallbackFunctionType->getNumParams() + 2) { - LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match " - << "params passed to std::call_once, " - << "ignoring the call\n"); + LLVM_DEBUG(llvm::dbgs() + << "Types of params of the callback do not match " + << "params passed to std::call_once, " << "ignoring the call\n"); return nullptr; } @@ -439,9 +435,9 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { const ParmVarDecl *PDecl = D->getParamDecl(ParamIdx); assert(PDecl); if (CallbackFunctionType->getParamType(ParamIdx - 2) - .getNonReferenceType() - .getCanonicalType() != - PDecl->getType().getNonReferenceType().getCanonicalType()) { + .getNonReferenceType() + .getCanonicalType() != + PDecl->getType().getNonReferenceType().getCanonicalType()) { LLVM_DEBUG(llvm::dbgs() << "Types of params of the callback do not match " << "params passed to std::call_once, " << "ignoring the call\n"); @@ -470,7 +466,6 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { M.makeDeclRefExpr(Flag, /* RefersToEnclosingVariableOrCapture=*/true); - MemberExpr *Deref = M.makeMemberExpression(FlagDecl, FlagFieldDecl); assert(Deref->isLValue()); QualType DerefType = Deref->getType(); @@ -553,28 +548,22 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) { C.LongTy, VK_PRValue, OK_Ordinary, SourceLocation(), /*CanOverflow*/ false, FPOptionsOverride()); - BinaryOperator *B = - M.makeAssignment( - M.makeDereference( - M.makeLvalueToRvalue( - M.makeDeclRefExpr(Predicate), PredicateQPtrTy), - PredicateTy), - M.makeIntegralCast(DoneValue, PredicateTy), - PredicateTy); + BinaryOperator *B = M.makeAssignment( + M.makeDereference( + M.makeLvalueToRvalue(M.makeDeclRefExpr(Predicate), PredicateQPtrTy), + PredicateTy), + M.makeIntegralCast(DoneValue, PredicateTy), PredicateTy); // (3) Create the compound statement. - Stmt *Stmts[] = { B, CE }; + Stmt *Stmts[] = {B, CE}; CompoundStmt *CS = M.makeCompound(Stmts); // (4) Create the 'if' condition. - ImplicitCastExpr *LValToRval = - M.makeLvalueToRvalue( + ImplicitCastExpr *LValToRval = M.makeLvalueToRvalue( M.makeDereference( - M.makeLvalueToRvalue( - M.makeDeclRefExpr(Predicate), - PredicateQPtrTy), - PredicateTy), - PredicateTy); + M.makeLvalueToRvalue(M.makeDeclRefExpr(Predicate), PredicateQPtrTy), + PredicateTy), + PredicateTy); Expr *GuardCondition = M.makeComparison(LValToRval, DoneValue, BO_NE); // (5) Create the 'if' statement. @@ -615,8 +604,8 @@ static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) { return CE; } -static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D) -{ +static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, + const FunctionDecl *D) { // There are exactly 3 arguments. if (D->param_size() != 3) return nullptr; @@ -654,23 +643,21 @@ static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D) ASTMaker M(C); // Construct the comparison. - Expr *Comparison = - M.makeComparison( + Expr *Comparison = M.makeComparison( M.makeLvalueToRvalue(M.makeDeclRefExpr(OldValue), OldValueTy), M.makeLvalueToRvalue( - M.makeDereference( - M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy), + M.makeDereference( + M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy), + PointeeTy), PointeeTy), - PointeeTy), BO_EQ); // Construct the body of the IfStmt. Stmt *Stmts[2]; - Stmts[0] = - M.makeAssignment( + Stmts[0] = M.makeAssignment( M.makeDereference( - M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy), - PointeeTy), + M.makeLvalueToRvalue(M.makeDeclRefExpr(TheValue), TheValueTy), + PointeeTy), M.makeLvalueToRvalue(M.makeDeclRefExpr(NewValue), NewValueTy), NewValueTy); @@ -733,13 +720,16 @@ Stmt *BodyFarm::getBody(const FunctionDecl *D) { FF = create_call_once; } else { FF = llvm::StringSwitch(Name) - .Case("dispatch_sync", create_dispatch_sync) - .Case("dispatch_once", create_dispatch_once) - .Default(nullptr); + .Case("dispatch_sync", create_dispatch_sync) + .Case("dispatch_once", create_dispatch_once) + .Default(nullptr); } - if (FF) { Val = FF(C, D); } - else if (Injector) { Val = Injector->getBody(D); } + if (FF) { + Val = FF(C, D); + } else if (Injector) { + Val = Injector->getBody(D); + } return *Val; } diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index de70cbbf6cdb3..b1d09c8db0584 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -191,8 +191,7 @@ class AddStmtChoice { AddStmtChoice(Kind a_kind = NotAlwaysAdd) : kind(a_kind) {} - bool alwaysAdd(CFGBuilder &builder, - const Stmt *stmt) const; + bool alwaysAdd(CFGBuilder &builder, const Stmt *stmt) const; /// Return a copy of this object, except with the 'always-add' bit /// set as specified. @@ -232,7 +231,7 @@ class LocalScope { /// const_iterator - Iterates local scope backwards and jumps to previous /// scope on reaching the beginning of currently iterated scope. class const_iterator { - const LocalScope* Scope = nullptr; + const LocalScope *Scope = nullptr; /// VarIter is guaranteed to be greater then 0 for every valid iterator. /// Invalid iterator (with null Scope) has VarIter equal to 0. @@ -246,15 +245,14 @@ class LocalScope { /// Create valid iterator. In case when S.Prev is an invalid iterator and /// I is equal to 0, this will create invalid iterator. - const_iterator(const LocalScope& S, unsigned I) - : Scope(&S), VarIter(I) { + const_iterator(const LocalScope &S, unsigned I) : Scope(&S), VarIter(I) { // Iterator to "end" of scope is not allowed. Handle it by going up // in scopes tree possibly up to invalid iterator in the root. if (VarIter == 0 && Scope) *this = Scope->Prev; } - VarDecl *const* operator->() const { + VarDecl *const *operator->() const { assert(Scope && "Dereferencing invalid iterator is not allowed"); assert(VarIter != 0 && "Iterator has invalid value of VarIter member"); return &Scope->Vars[VarIter - 1]; @@ -266,9 +264,7 @@ class LocalScope { return Scope->Vars[0]; } - VarDecl *operator*() const { - return *this->operator->(); - } + VarDecl *operator*() const { return *this->operator->(); } const_iterator &operator++() { if (!Scope) @@ -289,13 +285,9 @@ class LocalScope { bool operator==(const const_iterator &rhs) const { return Scope == rhs.Scope && VarIter == rhs.VarIter; } - bool operator!=(const const_iterator &rhs) const { - return !(*this == rhs); - } + bool operator!=(const const_iterator &rhs) const { return !(*this == rhs); } - explicit operator bool() const { - return *this != const_iterator(); - } + explicit operator bool() const { return *this != const_iterator(); } int distance(const_iterator L); const_iterator shared_parent(const_iterator L); @@ -321,9 +313,7 @@ class LocalScope { /// Begin of scope in direction of CFG building (backwards). const_iterator begin() const { return const_iterator(*this, Vars.size()); } - void addVar(VarDecl *VD) { - Vars.push_back(VD, ctx); - } + void addVar(VarDecl *VD) { Vars.push_back(VD, ctx); } }; } // namespace @@ -449,15 +439,15 @@ reverse_children::reverse_children(Stmt *S) { return; } switch (S->getStmtClass()) { - // Note: Fill in this switch with more cases we want to optimize. - case Stmt::InitListExprClass: { - InitListExpr *IE = cast(S); - children = llvm::ArrayRef(reinterpret_cast(IE->getInits()), - IE->getNumInits()); - return; - } - default: - break; + // Note: Fill in this switch with more cases we want to optimize. + case Stmt::InitListExprClass: { + InitListExpr *IE = cast(S); + children = llvm::ArrayRef(reinterpret_cast(IE->getInits()), + IE->getNumInits()); + return; + } + default: + break; } // Default case for all other statements. @@ -586,8 +576,8 @@ class CFGBuilder { CFGBlock *VisitDeclSubExpr(DeclStmt *DS); CFGBlock *VisitDefaultStmt(DefaultStmt *D); CFGBlock *VisitDoStmt(DoStmt *D); - CFGBlock *VisitExprWithCleanups(ExprWithCleanups *E, - AddStmtChoice asc, bool ExternallyDestructed); + CFGBlock *VisitExprWithCleanups(ExprWithCleanups *E, AddStmtChoice asc, + bool ExternallyDestructed); CFGBlock *VisitForStmt(ForStmt *F); CFGBlock *VisitGotoStmt(GotoStmt *G); CFGBlock *VisitGCCAsmStmt(GCCAsmStmt *G, AddStmtChoice asc); @@ -703,16 +693,19 @@ class CFGBuilder { // full expression. CFGBlock *VisitForTemporaryDtors(Stmt *E, bool ExternallyDestructed, TempDtorContext &Context); - CFGBlock *VisitChildrenForTemporaryDtors(Stmt *E, bool ExternallyDestructed, + CFGBlock *VisitChildrenForTemporaryDtors(Stmt *E, bool ExternallyDestructed, TempDtorContext &Context); CFGBlock *VisitBinaryOperatorForTemporaryDtors(BinaryOperator *E, bool ExternallyDestructed, TempDtorContext &Context); - CFGBlock *VisitCXXBindTemporaryExprForTemporaryDtors( - CXXBindTemporaryExpr *E, bool ExternallyDestructed, TempDtorContext &Context); - CFGBlock *VisitConditionalOperatorForTemporaryDtors( - AbstractConditionalOperator *E, bool ExternallyDestructed, - TempDtorContext &Context); + CFGBlock * + VisitCXXBindTemporaryExprForTemporaryDtors(CXXBindTemporaryExpr *E, + bool ExternallyDestructed, + TempDtorContext &Context); + CFGBlock * + VisitConditionalOperatorForTemporaryDtors(AbstractConditionalOperator *E, + bool ExternallyDestructed, + TempDtorContext &Context); void InsertTempDtorDecisionBlock(const TempDtorContext &Context, CFGBlock *FalseSucc = nullptr); @@ -759,13 +752,14 @@ class CFGBuilder { // there's no need to do this manually in every Visit... function. void cleanupConstructionContext(Expr *E); - void autoCreateBlock() { if (!Block) Block = createBlock(); } + void autoCreateBlock() { + if (!Block) + Block = createBlock(); + } CFGBlock *createBlock(bool add_successor = true); CFGBlock *createNoReturnBlock(); - CFGBlock *addStmt(Stmt *S) { - return Visit(S, AddStmtChoice::AlwaysAdd); - } + CFGBlock *addStmt(Stmt *S) { return Visit(S, AddStmtChoice::AlwaysAdd); } CFGBlock *addInitializer(CXXCtorInitializer *I); void addLoopExit(const Stmt *LoopStmt); @@ -777,20 +771,19 @@ class CFGBuilder { LocalScope::const_iterator E, Stmt *S); void addImplicitDtorsForDestructor(const CXXDestructorDecl *DD); void addScopeChangesHandling(LocalScope::const_iterator SrcPos, - LocalScope::const_iterator DstPos, - Stmt *S); + LocalScope::const_iterator DstPos, Stmt *S); CFGBlock *createScopeChangesHandlingBlock(LocalScope::const_iterator SrcPos, CFGBlock *SrcBlk, LocalScope::const_iterator DstPost, CFGBlock *DstBlk); // Local scopes creation. - LocalScope* createOrReuseLocalScope(LocalScope* Scope); + LocalScope *createOrReuseLocalScope(LocalScope *Scope); void addLocalScopeForStmt(Stmt *S); - LocalScope* addLocalScopeForDeclStmt(DeclStmt *DS, - LocalScope* Scope = nullptr); - LocalScope* addLocalScopeForVarDecl(VarDecl *VD, LocalScope* Scope = nullptr); + LocalScope *addLocalScopeForDeclStmt(DeclStmt *DS, + LocalScope *Scope = nullptr); + LocalScope *addLocalScopeForVarDecl(VarDecl *VD, LocalScope *Scope = nullptr); void addLocalScopeAndDtors(Stmt *S); @@ -815,7 +808,7 @@ class CFGBuilder { // All block-level expressions should have already been IgnoreParens()ed. assert(!isa(S) || cast(S)->IgnoreParens() == S); - B->appendStmt(const_cast(S), cfg->getBumpVectorContext()); + B->appendStmt(const_cast(S), cfg->getBumpVectorContext()); } void appendConstructor(CFGBlock *B, CXXConstructExpr *CE) { @@ -978,8 +971,8 @@ class CFGBuilder { return TryResult(); const BinaryOperator *BitOp = dyn_cast(BoolExpr); - if (BitOp && (BitOp->getOpcode() == BO_And || - BitOp->getOpcode() == BO_Or)) { + if (BitOp && + (BitOp->getOpcode() == BO_And || BitOp->getOpcode() == BO_Or)) { const Expr *LHSExpr2 = BitOp->getLHS()->IgnoreParens(); const Expr *RHSExpr2 = BitOp->getRHS()->IgnoreParens(); @@ -1057,20 +1050,20 @@ class CFGBuilder { const llvm::APSInt &Value2) { assert(Value1.isSigned() == Value2.isSigned()); switch (Relation) { - default: - return TryResult(); - case BO_EQ: - return TryResult(Value1 == Value2); - case BO_NE: - return TryResult(Value1 != Value2); - case BO_LT: - return TryResult(Value1 < Value2); - case BO_LE: - return TryResult(Value1 <= Value2); - case BO_GT: - return TryResult(Value1 > Value2); - case BO_GE: - return TryResult(Value1 >= Value2); + default: + return TryResult(); + case BO_EQ: + return TryResult(Value1 == Value2); + case BO_NE: + return TryResult(Value1 != Value2); + case BO_LT: + return TryResult(Value1 < Value2); + case BO_LE: + return TryResult(Value1 <= Value2); + case BO_GT: + return TryResult(Value1 > Value2); + case BO_GE: + return TryResult(Value1 >= Value2); } } @@ -1102,10 +1095,10 @@ class CFGBuilder { TryResult Result = CheckLogicalOpWithNegatedVariable(LHSExpr, RHSExpr); if (Result.isKnown()) - return Result; + return Result; Result = CheckLogicalOpWithNegatedVariable(RHSExpr, LHSExpr); if (Result.isKnown()) - return Result; + return Result; const auto *LHS = dyn_cast(LHSExpr); const auto *RHS = dyn_cast(RHSExpr); @@ -1155,17 +1148,17 @@ class CFGBuilder { // Values that will be used to determine if result of logical // operator is always true/false const llvm::APSInt Values[] = { - // Value less than both Value1 and Value2 - llvm::APSInt::getMinValue(L1.getBitWidth(), L1.isUnsigned()), - // L1 - L1, - // Value between Value1 and Value2 - ((L1 < L2) ? L1 : L2) + llvm::APSInt(llvm::APInt(L1.getBitWidth(), 1), - L1.isUnsigned()), - // L2 - L2, - // Value greater than both Value1 and Value2 - llvm::APSInt::getMaxValue(L1.getBitWidth(), L1.isUnsigned()), + // Value less than both Value1 and Value2 + llvm::APSInt::getMinValue(L1.getBitWidth(), L1.isUnsigned()), + // L1 + L1, + // Value between Value1 and Value2 + ((L1 < L2) ? L1 : L2) + + llvm::APSInt(llvm::APInt(L1.getBitWidth(), 1), L1.isUnsigned()), + // L2 + L2, + // Value greater than both Value1 and Value2 + llvm::APSInt::getMaxValue(L1.getBitWidth(), L1.isUnsigned()), }; // Check whether expression is always true/false by evaluating the following @@ -1239,16 +1232,15 @@ class CFGBuilder { bool tryEvaluate(Expr *S, Expr::EvalResult &outResult) { if (!BuildOpts.PruneTriviallyFalseEdges) return false; - return !S->isTypeDependent() && - !S->isValueDependent() && + return !S->isTypeDependent() && !S->isValueDependent() && S->EvaluateAsRValue(outResult, *Context); } /// tryEvaluateBool - Try and evaluate the Stmt and return 0 or 1 /// if we can evaluate to a known value, otherwise return -1. TryResult tryEvaluateBool(Expr *S) { - if (!BuildOpts.PruneTriviallyFalseEdges || - S->isTypeDependent() || S->isValueDependent()) + if (!BuildOpts.PruneTriviallyFalseEdges || S->isTypeDependent() || + S->isValueDependent()) return {}; if (BinaryOperator *Bop = dyn_cast(S)) { @@ -1262,32 +1254,31 @@ class CFGBuilder { TryResult Result = evaluateAsBooleanConditionNoCache(S); CachedBoolEvals[S] = Result; // update or insert return Result; - } - else { + } else { switch (Bop->getOpcode()) { - default: break; - // For 'x & 0' and 'x * 0', we can determine that - // the value is always false. - case BO_Mul: - case BO_And: { - // If either operand is zero, we know the value - // must be false. - Expr::EvalResult LHSResult; - if (Bop->getLHS()->EvaluateAsInt(LHSResult, *Context)) { - llvm::APSInt IntVal = LHSResult.Val.getInt(); - if (!IntVal.getBoolValue()) { - return TryResult(false); - } + default: + break; + // For 'x & 0' and 'x * 0', we can determine that + // the value is always false. + case BO_Mul: + case BO_And: { + // If either operand is zero, we know the value + // must be false. + Expr::EvalResult LHSResult; + if (Bop->getLHS()->EvaluateAsInt(LHSResult, *Context)) { + llvm::APSInt IntVal = LHSResult.Val.getInt(); + if (!IntVal.getBoolValue()) { + return TryResult(false); } - Expr::EvalResult RHSResult; - if (Bop->getRHS()->EvaluateAsInt(RHSResult, *Context)) { - llvm::APSInt IntVal = RHSResult.Val.getInt(); - if (!IntVal.getBoolValue()) { - return TryResult(false); - } + } + Expr::EvalResult RHSResult; + if (Bop->getRHS()->EvaluateAsInt(RHSResult, *Context)) { + llvm::APSInt IntVal = RHSResult.Val.getInt(); + if (!IntVal.getBoolValue()) { + return TryResult(false); } } - break; + } break; } } } @@ -1329,9 +1320,9 @@ class CFGBuilder { return {}; } else if (Bop->isEqualityOp()) { - TryResult BopRes = checkIncorrectEqualityOperator(Bop); - if (BopRes.isKnown()) - return BopRes.isTrue(); + TryResult BopRes = checkIncorrectEqualityOperator(Bop); + if (BopRes.isKnown()) + return BopRes.isTrue(); } else if (Bop->isRelationalOp()) { TryResult BopRes = checkIncorrectRelationalOperator(Bop); if (BopRes.isKnown()) @@ -1425,7 +1416,8 @@ static const VariableArrayType *FindVA(const Type *t) { void CFGBuilder::consumeConstructionContext( const ConstructionContextLayer *Layer, Expr *E) { assert((isa(E) || isa(E) || - isa(E)) && "Expression cannot construct an object!"); + isa(E)) && + "Expression cannot construct an object!"); if (const ConstructionContextLayer *PreviouslyStoredLayer = ConstructionContextMap.lookup(E)) { (void)PreviouslyStoredLayer; @@ -1438,8 +1430,8 @@ void CFGBuilder::consumeConstructionContext( } } -void CFGBuilder::findConstructionContexts( - const ConstructionContextLayer *Layer, Stmt *Child) { +void CFGBuilder::findConstructionContexts(const ConstructionContextLayer *Layer, + Stmt *Child) { if (!BuildOpts.AddRichCXXConstructors) return; @@ -1451,7 +1443,7 @@ void CFGBuilder::findConstructionContexts( Layer); }; - switch(Child->getStmtClass()) { + switch (Child->getStmtClass()) { case Stmt::CXXConstructExprClass: case Stmt::CXXTemporaryObjectExprClass: { // Support pre-C++17 copy elision AST. @@ -1576,7 +1568,7 @@ std::unique_ptr CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) { // as the exit block. Succ = createBlock(); assert(Succ == &cfg->getExit()); - Block = nullptr; // the EXIT block is empty. Create all other blocks lazily. + Block = nullptr; // the EXIT block is empty. Create all other blocks lazily. if (BuildOpts.AddImplicitDtors) if (const CXXDestructorDecl *DD = dyn_cast_or_null(D)) @@ -1631,7 +1623,8 @@ std::unique_ptr CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) { // Backpatch the gotos whose label -> block mappings we didn't know when we // encountered them. for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(), - E = BackpatchBlocks.end(); I != E; ++I ) { + E = BackpatchBlocks.end(); + I != E; ++I) { CFGBlock *B = I->block; if (auto *G = dyn_cast(B->getTerminator())) { @@ -1646,7 +1639,7 @@ std::unique_ptr CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) { I->scopePosition, B, JT.scopePosition, JT.block); addSuccessor(B, SuccBlk); } else if (auto *G = dyn_cast(B->getTerminator())) { - CFGBlock *Successor = (I+1)->block; + CFGBlock *Successor = (I + 1)->block; for (auto *L : G->labels()) { LabelMapTy::iterator LI = LabelMap.find(L->getLabel()); // If there is no target for the goto, then we are looking at an @@ -1666,13 +1659,15 @@ std::unique_ptr CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) { // Add successors to the Indirect Goto Dispatch block (if we have one). if (CFGBlock *B = cfg->getIndirectGotoBlock()) for (LabelSetTy::iterator I = AddressTakenLabels.begin(), - E = AddressTakenLabels.end(); I != E; ++I ) { + E = AddressTakenLabels.end(); + I != E; ++I) { // Lookup the target block. LabelMapTy::iterator LI = LabelMap.find(*I); // If there is no target block that contains label, then we are looking // at an incomplete AST. Handle this by not registering a successor. - if (LI == LabelMap.end()) continue; + if (LI == LabelMap.end()) + continue; addSuccessor(B, LI->second.block); } @@ -1779,8 +1774,8 @@ static QualType getReferenceInitTemporaryType(const Expr *Init, } // Skip through the temporary-materialization expression. - if (const MaterializeTemporaryExpr *MTE - = dyn_cast(Init)) { + if (const MaterializeTemporaryExpr *MTE = + dyn_cast(Init)) { Init = MTE->getSubExpr(); if (FoundMTE) *FoundMTE = true; @@ -1802,8 +1797,8 @@ static QualType getReferenceInitTemporaryType(const Expr *Init, // TODO: Support adding LoopExit element to the CFG in case where the loop is // ended by ReturnStmt, GotoStmt or ThrowExpr. -void CFGBuilder::addLoopExit(const Stmt *LoopStmt){ - if(!BuildOpts.AddLoopExit) +void CFGBuilder::addLoopExit(const Stmt *LoopStmt) { + if (!BuildOpts.AddLoopExit) return; autoCreateBlock(); appendLoopExit(Block, LoopStmt); @@ -1866,7 +1861,7 @@ void CFGBuilder::addAutomaticObjDestruction(LocalScope::const_iterator B, SmallVector DeclsNeedDestruction; DeclsNeedDestruction.reserve(B.distance(E)); - for (VarDecl* D : llvm::make_range(B, E)) + for (VarDecl *D : llvm::make_range(B, E)) if (needsAutomaticDestruction(D)) DeclsNeedDestruction.push_back(D); @@ -1926,7 +1921,7 @@ void CFGBuilder::addScopeExitHandling(LocalScope::const_iterator B, // Objects with trivial destructor ends their lifetime when their storage // is destroyed, for automatic variables, this happens when the end of the // scope is added. - for (VarDecl* D : llvm::make_range(B, E)) + for (VarDecl *D : llvm::make_range(B, E)) if (!needsAutomaticDestruction(D)) DeclsTrivial.push_back(D); @@ -2054,7 +2049,7 @@ void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) { /// createOrReuseLocalScope - If Scope is NULL create new LocalScope. Either /// way return valid LocalScope object. -LocalScope* CFGBuilder::createOrReuseLocalScope(LocalScope* Scope) { +LocalScope *CFGBuilder::createOrReuseLocalScope(LocalScope *Scope) { if (Scope) return Scope; llvm::BumpPtrAllocator &alloc = cfg->getAllocator(); @@ -2088,8 +2083,8 @@ void CFGBuilder::addLocalScopeForStmt(Stmt *S) { /// addLocalScopeForDeclStmt - Add LocalScope for declaration statement. Will /// reuse Scope if not NULL. -LocalScope* CFGBuilder::addLocalScopeForDeclStmt(DeclStmt *DS, - LocalScope* Scope) { +LocalScope *CFGBuilder::addLocalScopeForDeclStmt(DeclStmt *DS, + LocalScope *Scope) { if (!BuildOpts.AddImplicitDtors && !BuildOpts.AddLifetime && !BuildOpts.AddScopes) return Scope; @@ -2147,8 +2142,8 @@ bool CFGBuilder::hasTrivialDestructor(const VarDecl *VD) const { /// addLocalScopeForVarDecl - Add LocalScope for variable declaration. It will /// create add scope for automatic objects and temporary objects bound to /// const reference. Will reuse Scope if not NULL. -LocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD, - LocalScope* Scope) { +LocalScope *CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD, + LocalScope *Scope) { if (!BuildOpts.AddImplicitDtors && !BuildOpts.AddLifetime && !BuildOpts.AddScopes) return Scope; @@ -2181,7 +2176,7 @@ void CFGBuilder::addLocalScopeAndDtors(Stmt *S) { /// Visit - Walk the subtree of a statement and add extra /// blocks for ternary operators, &&, and ||. We also process "," and /// DeclStmts (which may contain nested control-flow). -CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc, +CFGBlock *CFGBuilder::Visit(Stmt *S, AddStmtChoice asc, bool ExternallyDestructed) { if (!S) { badCFG = true; @@ -2196,216 +2191,216 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc, return VisitOMPExecutableDirective(D, asc); switch (S->getStmtClass()) { - default: - return VisitStmt(S, asc); + default: + return VisitStmt(S, asc); - case Stmt::ImplicitValueInitExprClass: - if (BuildOpts.OmitImplicitValueInitializers) - return Block; - return VisitStmt(S, asc); + case Stmt::ImplicitValueInitExprClass: + if (BuildOpts.OmitImplicitValueInitializers) + return Block; + return VisitStmt(S, asc); - case Stmt::InitListExprClass: - return VisitInitListExpr(cast(S), asc); + case Stmt::InitListExprClass: + return VisitInitListExpr(cast(S), asc); - case Stmt::AttributedStmtClass: - return VisitAttributedStmt(cast(S), asc); + case Stmt::AttributedStmtClass: + return VisitAttributedStmt(cast(S), asc); - case Stmt::AddrLabelExprClass: - return VisitAddrLabelExpr(cast(S), asc); + case Stmt::AddrLabelExprClass: + return VisitAddrLabelExpr(cast(S), asc); - case Stmt::BinaryConditionalOperatorClass: - return VisitConditionalOperator(cast(S), asc); + case Stmt::BinaryConditionalOperatorClass: + return VisitConditionalOperator(cast(S), asc); - case Stmt::BinaryOperatorClass: - return VisitBinaryOperator(cast(S), asc); + case Stmt::BinaryOperatorClass: + return VisitBinaryOperator(cast(S), asc); - case Stmt::BlockExprClass: - return VisitBlockExpr(cast(S), asc); + case Stmt::BlockExprClass: + return VisitBlockExpr(cast(S), asc); - case Stmt::BreakStmtClass: - return VisitBreakStmt(cast(S)); + case Stmt::BreakStmtClass: + return VisitBreakStmt(cast(S)); - case Stmt::CallExprClass: - case Stmt::CXXOperatorCallExprClass: - case Stmt::CXXMemberCallExprClass: - case Stmt::UserDefinedLiteralClass: - return VisitCallExpr(cast(S), asc); + case Stmt::CallExprClass: + case Stmt::CXXOperatorCallExprClass: + case Stmt::CXXMemberCallExprClass: + case Stmt::UserDefinedLiteralClass: + return VisitCallExpr(cast(S), asc); - case Stmt::CaseStmtClass: - return VisitCaseStmt(cast(S)); + case Stmt::CaseStmtClass: + return VisitCaseStmt(cast(S)); - case Stmt::ChooseExprClass: - return VisitChooseExpr(cast(S), asc); + case Stmt::ChooseExprClass: + return VisitChooseExpr(cast(S), asc); - case Stmt::CompoundStmtClass: - return VisitCompoundStmt(cast(S), ExternallyDestructed); + case Stmt::CompoundStmtClass: + return VisitCompoundStmt(cast(S), ExternallyDestructed); - case Stmt::ConditionalOperatorClass: - return VisitConditionalOperator(cast(S), asc); + case Stmt::ConditionalOperatorClass: + return VisitConditionalOperator(cast(S), asc); - case Stmt::ContinueStmtClass: - return VisitContinueStmt(cast(S)); + case Stmt::ContinueStmtClass: + return VisitContinueStmt(cast(S)); - case Stmt::CXXCatchStmtClass: - return VisitCXXCatchStmt(cast(S)); + case Stmt::CXXCatchStmtClass: + return VisitCXXCatchStmt(cast(S)); - case Stmt::ExprWithCleanupsClass: - return VisitExprWithCleanups(cast(S), - asc, ExternallyDestructed); + case Stmt::ExprWithCleanupsClass: + return VisitExprWithCleanups(cast(S), asc, + ExternallyDestructed); - case Stmt::CXXDefaultArgExprClass: - case Stmt::CXXDefaultInitExprClass: - // FIXME: The expression inside a CXXDefaultArgExpr is owned by the - // called function's declaration, not by the caller. If we simply add - // this expression to the CFG, we could end up with the same Expr - // appearing multiple times (PR13385). - // - // It's likewise possible for multiple CXXDefaultInitExprs for the same - // expression to be used in the same function (through aggregate - // initialization). - return VisitStmt(S, asc); + case Stmt::CXXDefaultArgExprClass: + case Stmt::CXXDefaultInitExprClass: + // FIXME: The expression inside a CXXDefaultArgExpr is owned by the + // called function's declaration, not by the caller. If we simply add + // this expression to the CFG, we could end up with the same Expr + // appearing multiple times (PR13385). + // + // It's likewise possible for multiple CXXDefaultInitExprs for the same + // expression to be used in the same function (through aggregate + // initialization). + return VisitStmt(S, asc); - case Stmt::CXXBindTemporaryExprClass: - return VisitCXXBindTemporaryExpr(cast(S), asc); + case Stmt::CXXBindTemporaryExprClass: + return VisitCXXBindTemporaryExpr(cast(S), asc); - case Stmt::CXXConstructExprClass: - return VisitCXXConstructExpr(cast(S), asc); + case Stmt::CXXConstructExprClass: + return VisitCXXConstructExpr(cast(S), asc); - case Stmt::CXXNewExprClass: - return VisitCXXNewExpr(cast(S), asc); + case Stmt::CXXNewExprClass: + return VisitCXXNewExpr(cast(S), asc); - case Stmt::CXXDeleteExprClass: - return VisitCXXDeleteExpr(cast(S), asc); + case Stmt::CXXDeleteExprClass: + return VisitCXXDeleteExpr(cast(S), asc); - case Stmt::CXXFunctionalCastExprClass: - return VisitCXXFunctionalCastExpr(cast(S), asc); + case Stmt::CXXFunctionalCastExprClass: + return VisitCXXFunctionalCastExpr(cast(S), asc); - case Stmt::CXXTemporaryObjectExprClass: - return VisitCXXTemporaryObjectExpr(cast(S), asc); + case Stmt::CXXTemporaryObjectExprClass: + return VisitCXXTemporaryObjectExpr(cast(S), asc); - case Stmt::CXXThrowExprClass: - return VisitCXXThrowExpr(cast(S)); + case Stmt::CXXThrowExprClass: + return VisitCXXThrowExpr(cast(S)); - case Stmt::CXXTryStmtClass: - return VisitCXXTryStmt(cast(S)); + case Stmt::CXXTryStmtClass: + return VisitCXXTryStmt(cast(S)); - case Stmt::CXXTypeidExprClass: - return VisitCXXTypeidExpr(cast(S), asc); + case Stmt::CXXTypeidExprClass: + return VisitCXXTypeidExpr(cast(S), asc); - case Stmt::CXXForRangeStmtClass: - return VisitCXXForRangeStmt(cast(S)); + case Stmt::CXXForRangeStmtClass: + return VisitCXXForRangeStmt(cast(S)); - case Stmt::DeclStmtClass: - return VisitDeclStmt(cast(S)); + case Stmt::DeclStmtClass: + return VisitDeclStmt(cast(S)); - case Stmt::DefaultStmtClass: - return VisitDefaultStmt(cast(S)); + case Stmt::DefaultStmtClass: + return VisitDefaultStmt(cast(S)); - case Stmt::DoStmtClass: - return VisitDoStmt(cast(S)); + case Stmt::DoStmtClass: + return VisitDoStmt(cast(S)); - case Stmt::ForStmtClass: - return VisitForStmt(cast(S)); + case Stmt::ForStmtClass: + return VisitForStmt(cast(S)); - case Stmt::GotoStmtClass: - return VisitGotoStmt(cast(S)); + case Stmt::GotoStmtClass: + return VisitGotoStmt(cast(S)); - case Stmt::GCCAsmStmtClass: - return VisitGCCAsmStmt(cast(S), asc); + case Stmt::GCCAsmStmtClass: + return VisitGCCAsmStmt(cast(S), asc); - case Stmt::IfStmtClass: - return VisitIfStmt(cast(S)); + case Stmt::IfStmtClass: + return VisitIfStmt(cast(S)); - case Stmt::ImplicitCastExprClass: - return VisitImplicitCastExpr(cast(S), asc); + case Stmt::ImplicitCastExprClass: + return VisitImplicitCastExpr(cast(S), asc); - case Stmt::ConstantExprClass: - return VisitConstantExpr(cast(S), asc); + case Stmt::ConstantExprClass: + return VisitConstantExpr(cast(S), asc); - case Stmt::IndirectGotoStmtClass: - return VisitIndirectGotoStmt(cast(S)); + case Stmt::IndirectGotoStmtClass: + return VisitIndirectGotoStmt(cast(S)); - case Stmt::LabelStmtClass: - return VisitLabelStmt(cast(S)); + case Stmt::LabelStmtClass: + return VisitLabelStmt(cast(S)); - case Stmt::LambdaExprClass: - return VisitLambdaExpr(cast(S), asc); + case Stmt::LambdaExprClass: + return VisitLambdaExpr(cast(S), asc); - case Stmt::MaterializeTemporaryExprClass: - return VisitMaterializeTemporaryExpr(cast(S), - asc); + case Stmt::MaterializeTemporaryExprClass: + return VisitMaterializeTemporaryExpr(cast(S), + asc); - case Stmt::MemberExprClass: - return VisitMemberExpr(cast(S), asc); + case Stmt::MemberExprClass: + return VisitMemberExpr(cast(S), asc); - case Stmt::NullStmtClass: - return Block; + case Stmt::NullStmtClass: + return Block; - case Stmt::ObjCAtCatchStmtClass: - return VisitObjCAtCatchStmt(cast(S)); + case Stmt::ObjCAtCatchStmtClass: + return VisitObjCAtCatchStmt(cast(S)); - case Stmt::ObjCAutoreleasePoolStmtClass: - return VisitObjCAutoreleasePoolStmt(cast(S)); + case Stmt::ObjCAutoreleasePoolStmtClass: + return VisitObjCAutoreleasePoolStmt(cast(S)); - case Stmt::ObjCAtSynchronizedStmtClass: - return VisitObjCAtSynchronizedStmt(cast(S)); + case Stmt::ObjCAtSynchronizedStmtClass: + return VisitObjCAtSynchronizedStmt(cast(S)); - case Stmt::ObjCAtThrowStmtClass: - return VisitObjCAtThrowStmt(cast(S)); + case Stmt::ObjCAtThrowStmtClass: + return VisitObjCAtThrowStmt(cast(S)); - case Stmt::ObjCAtTryStmtClass: - return VisitObjCAtTryStmt(cast(S)); + case Stmt::ObjCAtTryStmtClass: + return VisitObjCAtTryStmt(cast(S)); - case Stmt::ObjCForCollectionStmtClass: - return VisitObjCForCollectionStmt(cast(S)); + case Stmt::ObjCForCollectionStmtClass: + return VisitObjCForCollectionStmt(cast(S)); - case Stmt::ObjCMessageExprClass: - return VisitObjCMessageExpr(cast(S), asc); + case Stmt::ObjCMessageExprClass: + return VisitObjCMessageExpr(cast(S), asc); - case Stmt::OpaqueValueExprClass: - return Block; + case Stmt::OpaqueValueExprClass: + return Block; - case Stmt::PseudoObjectExprClass: - return VisitPseudoObjectExpr(cast(S)); + case Stmt::PseudoObjectExprClass: + return VisitPseudoObjectExpr(cast(S)); - case Stmt::ReturnStmtClass: - case Stmt::CoreturnStmtClass: - return VisitReturnStmt(S); + case Stmt::ReturnStmtClass: + case Stmt::CoreturnStmtClass: + return VisitReturnStmt(S); - case Stmt::CoyieldExprClass: - case Stmt::CoawaitExprClass: - return VisitCoroutineSuspendExpr(cast(S), asc); + case Stmt::CoyieldExprClass: + case Stmt::CoawaitExprClass: + return VisitCoroutineSuspendExpr(cast(S), asc); - case Stmt::SEHExceptStmtClass: - return VisitSEHExceptStmt(cast(S)); + case Stmt::SEHExceptStmtClass: + return VisitSEHExceptStmt(cast(S)); - case Stmt::SEHFinallyStmtClass: - return VisitSEHFinallyStmt(cast(S)); + case Stmt::SEHFinallyStmtClass: + return VisitSEHFinallyStmt(cast(S)); - case Stmt::SEHLeaveStmtClass: - return VisitSEHLeaveStmt(cast(S)); + case Stmt::SEHLeaveStmtClass: + return VisitSEHLeaveStmt(cast(S)); - case Stmt::SEHTryStmtClass: - return VisitSEHTryStmt(cast(S)); + case Stmt::SEHTryStmtClass: + return VisitSEHTryStmt(cast(S)); - case Stmt::UnaryExprOrTypeTraitExprClass: - return VisitUnaryExprOrTypeTraitExpr(cast(S), - asc); + case Stmt::UnaryExprOrTypeTraitExprClass: + return VisitUnaryExprOrTypeTraitExpr(cast(S), + asc); - case Stmt::StmtExprClass: - return VisitStmtExpr(cast(S), asc); + case Stmt::StmtExprClass: + return VisitStmtExpr(cast(S), asc); - case Stmt::SwitchStmtClass: - return VisitSwitchStmt(cast(S)); + case Stmt::SwitchStmtClass: + return VisitSwitchStmt(cast(S)); - case Stmt::UnaryOperatorClass: - return VisitUnaryOperator(cast(S), asc); + case Stmt::UnaryOperatorClass: + return VisitUnaryOperator(cast(S), asc); - case Stmt::WhileStmtClass: - return VisitWhileStmt(cast(S)); + case Stmt::WhileStmtClass: + return VisitWhileStmt(cast(S)); - case Stmt::ArrayInitLoopExprClass: - return VisitArrayInitLoopExpr(cast(S), asc); + case Stmt::ArrayInitLoopExprClass: + return VisitArrayInitLoopExpr(cast(S), asc); } } @@ -2456,8 +2451,7 @@ CFGBlock *CFGBuilder::VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc) { return B; } -CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A, - AddStmtChoice asc) { +CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc) { AddressTakenLabels.insert(A->getLabel()); if (asc.alwaysAdd(*this, A)) { @@ -2512,15 +2506,13 @@ CFGBlock *CFGBuilder::VisitLogicalOperator(BinaryOperator *B) { if (badCFG) return nullptr; - return VisitLogicalOperator(B, nullptr, ConfluenceBlock, - ConfluenceBlock).first; + return VisitLogicalOperator(B, nullptr, ConfluenceBlock, ConfluenceBlock) + .first; } -std::pair -CFGBuilder::VisitLogicalOperator(BinaryOperator *B, - Stmt *Term, - CFGBlock *TrueBlock, - CFGBlock *FalseBlock) { +std::pair +CFGBuilder::VisitLogicalOperator(BinaryOperator *B, Stmt *Term, + CFGBlock *TrueBlock, CFGBlock *FalseBlock) { // Introspect the RHS. If it is a nested logical operation, we recursively // build the CFG using this function. Otherwise, resort to default // CFG construction behavior. @@ -2531,7 +2523,7 @@ CFGBuilder::VisitLogicalOperator(BinaryOperator *B, if (BinaryOperator *B_RHS = dyn_cast(RHS)) if (B_RHS->isLogicalOp()) { std::tie(RHSBlock, ExitBlock) = - VisitLogicalOperator(B_RHS, Term, TrueBlock, FalseBlock); + VisitLogicalOperator(B_RHS, Term, TrueBlock, FalseBlock); break; } @@ -2551,8 +2543,7 @@ CFGBuilder::VisitLogicalOperator(BinaryOperator *B, if (!Term) { assert(TrueBlock == FalseBlock); addSuccessor(RHSBlock, TrueBlock); - } - else { + } else { RHSBlock->setTerminator(Term); addSuccessor(RHSBlock, TrueBlock, !KnownVal.isFalse()); addSuccessor(RHSBlock, FalseBlock, !KnownVal.isTrue()); @@ -2560,8 +2551,7 @@ CFGBuilder::VisitLogicalOperator(BinaryOperator *B, Block = RHSBlock; RHSBlock = addStmt(RHS); - } - while (false); + } while (false); if (badCFG) return std::make_pair(nullptr, nullptr); @@ -2611,7 +2601,7 @@ CFGBuilder::VisitLogicalOperator(BinaryOperator *B, CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B, AddStmtChoice asc) { - // && or || + // && or || if (B->isLogicalOp()) return VisitLogicalOperator(B); @@ -2699,7 +2689,8 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) { // We should only get a null bound type if processing a dependent // CFG. Recover by assuming nothing. - if (!boundType.isNull()) calleeType = boundType; + if (!boundType.isNull()) + calleeType = boundType; } // If this is a call to a no-return function, this stops the block here. @@ -2776,8 +2767,7 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) { return VisitChildren(C); } -CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C, - AddStmtChoice asc) { +CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C, AddStmtChoice asc) { CFGBlock *ConfluenceBlock = Block ? Block : createBlock(); appendStmt(ConfluenceBlock, C); if (badCFG) @@ -2798,7 +2788,7 @@ CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C, Block = createBlock(false); // See if this is a known constant. - const TryResult& KnownVal = tryEvaluateBool(C->getCond()); + const TryResult &KnownVal = tryEvaluateBool(C->getCond()); addSuccessor(Block, KnownVal.isFalse() ? nullptr : LHSBlock); addSuccessor(Block, KnownVal.isTrue() ? nullptr : RHSBlock); Block->setTerminator(C); @@ -2821,8 +2811,8 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C, for (Stmt *S : llvm::reverse(C->body())) { // If we hit a segment of code just containing ';' (NullStmts), we can // get a null block back. In such cases, just use the LastBlock - CFGBlock *newBlock = Visit(S, AddStmtChoice::AlwaysAdd, - ExternallyDestructed); + CFGBlock *newBlock = + Visit(S, AddStmtChoice::AlwaysAdd, ExternallyDestructed); if (newBlock) LastBlock = newBlock; @@ -2863,8 +2853,7 @@ CFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C, if (badCFG) return nullptr; Block = nullptr; - } - else + } else LHSBlock = ConfluenceBlock; // Create the block for the RHS expression. @@ -2875,7 +2864,7 @@ CFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C, // If the condition is a logical '&&' or '||', build a more accurate CFG. if (BinaryOperator *Cond = - dyn_cast(C->getCond()->IgnoreParens())) + dyn_cast(C->getCond()->IgnoreParens())) if (Cond->isLogicalOp()) return VisitLogicalOperator(Cond, C, LHSBlock, RHSBlock).first; @@ -2883,7 +2872,7 @@ CFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C, Block = createBlock(false); // See if this is a known constant. - const TryResult& KnownVal = tryEvaluateBool(C->getCond()); + const TryResult &KnownVal = tryEvaluateBool(C->getCond()); addSuccessor(Block, LHSBlock, !KnownVal.isFalse()); addSuccessor(Block, RHSBlock, !KnownVal.isTrue()); Block->setTerminator(C); @@ -2924,7 +2913,8 @@ CFGBlock *CFGBuilder::VisitDeclStmt(DeclStmt *DS) { // automatically freed with the CFG. DeclGroupRef DG(*I); Decl *D = *I; - DeclStmt *DSNew = new (Context) DeclStmt(DG, D->getLocation(), GetEndLoc(D)); + DeclStmt *DSNew = + new (Context) DeclStmt(DG, D->getLocation(), GetEndLoc(D)); cfg->addSyntheticDeclStmt(DSNew, DS); // Append the fake DeclStmt to block. @@ -3033,8 +3023,7 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) { ExprWithCleanups *EC = cast(Init); if (CFGBlock *newBlock = Visit(EC->getSubExpr())) LastBlock = newBlock; - } - else { + } else { if (CFGBlock *newBlock = Visit(Init)) LastBlock = newBlock; } @@ -3043,7 +3032,7 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) { // If the type of VD is a VLA, then we must process its size expressions. // FIXME: This does not find the VLA if it is embedded in other types, // like here: `int (*p_vla)[x];` - for (const VariableArrayType* VA = FindVA(VD->getType().getTypePtr()); + for (const VariableArrayType *VA = FindVA(VD->getType().getTypePtr()); VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) { if (CFGBlock *newBlock = addStmt(VA->getSizeExpr())) LastBlock = newBlock; @@ -3189,7 +3178,7 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) { // If the IfStmt contains a condition variable, add it and its // initializer to the CFG. - if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) { + if (const DeclStmt *DS = I->getConditionVariableDeclStmt()) { autoCreateBlock(); LastBlock = addStmt(const_cast(DS)); } @@ -3335,7 +3324,8 @@ CFGBlock *CFGBuilder::VisitSEHTryStmt(SEHTryStmt *Terminator) { if (badCFG) return nullptr; SEHTrySuccessor = Block; - } else SEHTrySuccessor = Succ; + } else + SEHTrySuccessor = Succ; // FIXME: Implement __finally support. if (Terminator->getFinallyHandler()) @@ -3544,7 +3534,6 @@ CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) { Block = Succ = TransitionBlock = createBlock(false); TransitionBlock->setLoopTarget(F); - // Loop iteration (after increment) should end with destructor of Condition // variable (if any). addAutomaticObjHandling(ScopePos, LoopBeginScopePos, F); @@ -3563,11 +3552,10 @@ CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) { Block = nullptr; } - // The starting block for the loop increment is the block that should - // represent the 'loop target' for looping back to the start of the loop. - ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos); - ContinueJumpTarget.block->setLoopTarget(F); - + // The starting block for the loop increment is the block that should + // represent the 'loop target' for looping back to the start of the loop. + ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos); + ContinueJumpTarget.block->setLoopTarget(F); // If body is not a compound statement create implicit scope // and add destructors. @@ -3582,8 +3570,7 @@ CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) { // In the case of "for (...;...;...);" we can have a null BodyBlock. // Use the continue jump target as the proxy for the body. BodyBlock = ContinueJumpTarget.block; - } - else if (badCFG) + } else if (badCFG) return nullptr; } @@ -3602,7 +3589,7 @@ CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) { dyn_cast_or_null(C ? C->IgnoreParens() : nullptr)) if (Cond->isLogicalOp()) { std::tie(EntryConditionBlock, ExitConditionBlock) = - VisitLogicalOperator(Cond, F, BodyBlock, LoopSuccessor); + VisitLogicalOperator(Cond, F, BodyBlock, LoopSuccessor); break; } @@ -3748,8 +3735,8 @@ CFGBlock *CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { // Walk the 'element' expression to see if there are any side-effects. We // generate new blocks as necessary. We DON'T add the statement by default to // the CFG unless it contains control-flow. - CFGBlock *EntryConditionBlock = Visit(S->getElement(), - AddStmtChoice::NotAlwaysAdd); + CFGBlock *EntryConditionBlock = + Visit(S->getElement(), AddStmtChoice::NotAlwaysAdd); if (Block) { if (badCFG) return nullptr; @@ -3839,7 +3826,7 @@ CFGBlock *CFGBuilder::VisitPseudoObjectExpr(PseudoObjectExpr *E) { // Before that, evaluate all of the semantics in order. In // CFG-land, that means appending them in reverse order. - for (unsigned i = E->getNumSemanticExprs(); i != 0; ) { + for (unsigned i = E->getNumSemanticExprs(); i != 0;) { Expr *Semantic = E->getSemanticExpr(--i); // If the semantic is an opaque value, we're being asked to bind @@ -3967,7 +3954,7 @@ CFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) { return nullptr; // See if this is a known constant. - const TryResult& KnownVal = tryEvaluateBool(C); + const TryResult &KnownVal = tryEvaluateBool(C); // Add the loop body entry as a successor to the condition. addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? nullptr : BodyBlock); @@ -3975,7 +3962,7 @@ CFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) { // false branch). addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? nullptr : LoopSuccessor); - } while(false); + } while (false); // Link up the loop-back block to the entry condition block. addSuccessor(TransitionBlock, EntryConditionBlock); @@ -4309,7 +4296,8 @@ CFGBlock *CFGBuilder::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E, CFGBlock *lastBlock = Block; if (E->isArgumentType()) { - for (const VariableArrayType *VA =FindVA(E->getArgumentType().getTypePtr()); + for (const VariableArrayType *VA = + FindVA(E->getArgumentType().getTypePtr()); VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) lastBlock = addStmt(VA->getSizeExpr()); } @@ -4350,7 +4338,8 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { if (badCFG) return nullptr; SwitchSuccessor = Block; - } else SwitchSuccessor = Succ; + } else + SwitchSuccessor = Succ; // Save the current "switch" context. SaveAndRestore save_switch(SwitchTerminatedBlock), @@ -4405,8 +4394,8 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { // case statements if the enumeration has no enumerators. bool SwitchAlwaysHasSuccessor = false; SwitchAlwaysHasSuccessor |= switchExclusivelyCovered; - SwitchAlwaysHasSuccessor |= Terminator->isAllEnumCasesCovered() && - Terminator->getSwitchCaseList(); + SwitchAlwaysHasSuccessor |= + Terminator->isAllEnumCasesCovered() && Terminator->getSwitchCaseList(); addSuccessor(SwitchTerminatedBlock, DefaultCaseBlock, !SwitchAlwaysHasSuccessor); @@ -4437,8 +4426,7 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { static bool shouldAddCase(bool &switchExclusivelyCovered, const Expr::EvalResult *switchCond, - const CaseStmt *CS, - ASTContext &Ctx) { + const CaseStmt *CS, ASTContext &Ctx) { if (!switchCond) return true; @@ -4453,8 +4441,7 @@ static bool shouldAddCase(bool &switchExclusivelyCovered, if (condInt == lhsInt) { addCase = true; switchExclusivelyCovered = true; - } - else if (condInt > lhsInt) { + } else if (condInt > lhsInt) { if (const Expr *RHS = CS->getRHS()) { // Evaluate the RHS of the case value. const llvm::APSInt &V2 = RHS->EvaluateKnownConstInt(Ctx); @@ -4464,8 +4451,7 @@ static bool shouldAddCase(bool &switchExclusivelyCovered, } } } - } - else + } else addCase = true; } return addCase; @@ -4489,10 +4475,11 @@ CFGBlock *CFGBuilder::VisitCaseStmt(CaseStmt *CS) { else TopBlock = currentBlock; - addSuccessor(SwitchTerminatedBlock, - shouldAddCase(switchExclusivelyCovered, switchCond, - CS, *Context) - ? currentBlock : nullptr); + addSuccessor( + SwitchTerminatedBlock, + shouldAddCase(switchExclusivelyCovered, switchCond, CS, *Context) + ? currentBlock + : nullptr); LastBlock = currentBlock; CS = cast(Sub); @@ -4516,9 +4503,9 @@ CFGBlock *CFGBuilder::VisitCaseStmt(CaseStmt *CS) { // Add this block to the list of successors for the block with the switch // statement. assert(SwitchTerminatedBlock); - addSuccessor(SwitchTerminatedBlock, CaseBlock, - shouldAddCase(switchExclusivelyCovered, switchCond, - CS, *Context)); + addSuccessor( + SwitchTerminatedBlock, CaseBlock, + shouldAddCase(switchExclusivelyCovered, switchCond, CS, *Context)); // We set Block to NULL to allow lazy creation of a new block (if necessary). Block = nullptr; @@ -4793,7 +4780,8 @@ CFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) { } CFGBlock *CFGBuilder::VisitExprWithCleanups(ExprWithCleanups *E, - AddStmtChoice asc, bool ExternallyDestructed) { + AddStmtChoice asc, + bool ExternallyDestructed) { if (BuildOpts.AddTemporaryDtors) { // If adding implicit destructors visit the full expression for adding // destructors of temporaries. @@ -4836,8 +4824,7 @@ CFGBlock *CFGBuilder::VisitCXXConstructExpr(CXXConstructExpr *C, return VisitChildren(C); } -CFGBlock *CFGBuilder::VisitCXXNewExpr(CXXNewExpr *NE, - AddStmtChoice asc) { +CFGBlock *CFGBuilder::VisitCXXNewExpr(CXXNewExpr *NE, AddStmtChoice asc) { autoCreateBlock(); appendStmt(Block, NE); @@ -4855,14 +4842,14 @@ CFGBlock *CFGBuilder::VisitCXXNewExpr(CXXNewExpr *NE, Block = Visit(*NE->getArraySize()); for (CXXNewExpr::arg_iterator I = NE->placement_arg_begin(), - E = NE->placement_arg_end(); I != E; ++I) + E = NE->placement_arg_end(); + I != E; ++I) Block = Visit(*I); return Block; } -CFGBlock *CFGBuilder::VisitCXXDeleteExpr(CXXDeleteExpr *DE, - AddStmtChoice asc) { +CFGBlock *CFGBuilder::VisitCXXDeleteExpr(CXXDeleteExpr *DE, AddStmtChoice asc) { autoCreateBlock(); appendStmt(Block, DE); QualType DTy = DE->getDestroyedType(); @@ -4948,94 +4935,93 @@ CFGBlock *CFGBuilder::VisitForTemporaryDtors(Stmt *E, bool ExternallyDestructed, return nullptr; } switch (E->getStmtClass()) { - default: - return VisitChildrenForTemporaryDtors(E, false, Context); - - case Stmt::InitListExprClass: - return VisitChildrenForTemporaryDtors(E, ExternallyDestructed, Context); - - case Stmt::BinaryOperatorClass: - return VisitBinaryOperatorForTemporaryDtors(cast(E), - ExternallyDestructed, - Context); - - case Stmt::CXXBindTemporaryExprClass: - return VisitCXXBindTemporaryExprForTemporaryDtors( - cast(E), ExternallyDestructed, Context); - - case Stmt::BinaryConditionalOperatorClass: - case Stmt::ConditionalOperatorClass: - return VisitConditionalOperatorForTemporaryDtors( - cast(E), ExternallyDestructed, Context); - - case Stmt::ImplicitCastExprClass: - // For implicit cast we want ExternallyDestructed to be passed further. - E = cast(E)->getSubExpr(); - goto tryAgain; - - case Stmt::CXXFunctionalCastExprClass: - // For functional cast we want ExternallyDestructed to be passed further. - E = cast(E)->getSubExpr(); - goto tryAgain; - - case Stmt::ConstantExprClass: - E = cast(E)->getSubExpr(); - goto tryAgain; - - case Stmt::ParenExprClass: - E = cast(E)->getSubExpr(); - goto tryAgain; - - case Stmt::MaterializeTemporaryExprClass: { - const MaterializeTemporaryExpr* MTE = cast(E); - ExternallyDestructed = (MTE->getStorageDuration() != SD_FullExpression); - SmallVector CommaLHSs; - SmallVector Adjustments; - // Find the expression whose lifetime needs to be extended. - E = const_cast( - cast(E) - ->getSubExpr() - ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments)); - // Visit the skipped comma operator left-hand sides for other temporaries. - for (const Expr *CommaLHS : CommaLHSs) { - VisitForTemporaryDtors(const_cast(CommaLHS), - /*ExternallyDestructed=*/false, Context); - } - goto tryAgain; + default: + return VisitChildrenForTemporaryDtors(E, false, Context); + + case Stmt::InitListExprClass: + return VisitChildrenForTemporaryDtors(E, ExternallyDestructed, Context); + + case Stmt::BinaryOperatorClass: + return VisitBinaryOperatorForTemporaryDtors(cast(E), + ExternallyDestructed, Context); + + case Stmt::CXXBindTemporaryExprClass: + return VisitCXXBindTemporaryExprForTemporaryDtors( + cast(E), ExternallyDestructed, Context); + + case Stmt::BinaryConditionalOperatorClass: + case Stmt::ConditionalOperatorClass: + return VisitConditionalOperatorForTemporaryDtors( + cast(E), ExternallyDestructed, Context); + + case Stmt::ImplicitCastExprClass: + // For implicit cast we want ExternallyDestructed to be passed further. + E = cast(E)->getSubExpr(); + goto tryAgain; + + case Stmt::CXXFunctionalCastExprClass: + // For functional cast we want ExternallyDestructed to be passed further. + E = cast(E)->getSubExpr(); + goto tryAgain; + + case Stmt::ConstantExprClass: + E = cast(E)->getSubExpr(); + goto tryAgain; + + case Stmt::ParenExprClass: + E = cast(E)->getSubExpr(); + goto tryAgain; + + case Stmt::MaterializeTemporaryExprClass: { + const MaterializeTemporaryExpr *MTE = cast(E); + ExternallyDestructed = (MTE->getStorageDuration() != SD_FullExpression); + SmallVector CommaLHSs; + SmallVector Adjustments; + // Find the expression whose lifetime needs to be extended. + E = const_cast( + cast(E) + ->getSubExpr() + ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments)); + // Visit the skipped comma operator left-hand sides for other temporaries. + for (const Expr *CommaLHS : CommaLHSs) { + VisitForTemporaryDtors(const_cast(CommaLHS), + /*ExternallyDestructed=*/false, Context); } + goto tryAgain; + } - case Stmt::BlockExprClass: - // Don't recurse into blocks; their subexpressions don't get evaluated - // here. - return Block; + case Stmt::BlockExprClass: + // Don't recurse into blocks; their subexpressions don't get evaluated + // here. + return Block; - case Stmt::LambdaExprClass: { - // For lambda expressions, only recurse into the capture initializers, - // and not the body. - auto *LE = cast(E); - CFGBlock *B = Block; - for (Expr *Init : LE->capture_inits()) { - if (Init) { - if (CFGBlock *R = VisitForTemporaryDtors( - Init, /*ExternallyDestructed=*/true, Context)) - B = R; - } + case Stmt::LambdaExprClass: { + // For lambda expressions, only recurse into the capture initializers, + // and not the body. + auto *LE = cast(E); + CFGBlock *B = Block; + for (Expr *Init : LE->capture_inits()) { + if (Init) { + if (CFGBlock *R = VisitForTemporaryDtors( + Init, /*ExternallyDestructed=*/true, Context)) + B = R; } - return B; } + return B; + } - case Stmt::StmtExprClass: - // Don't recurse into statement expressions; any cleanups inside them - // will be wrapped in their own ExprWithCleanups. - return Block; + case Stmt::StmtExprClass: + // Don't recurse into statement expressions; any cleanups inside them + // will be wrapped in their own ExprWithCleanups. + return Block; - case Stmt::CXXDefaultArgExprClass: - E = cast(E)->getExpr(); - goto tryAgain; + case Stmt::CXXDefaultArgExprClass: + E = cast(E)->getExpr(); + goto tryAgain; - case Stmt::CXXDefaultInitExprClass: - E = cast(E)->getExpr(); - goto tryAgain; + case Stmt::CXXDefaultInitExprClass: + E = cast(E)->getExpr(); + goto tryAgain; } } @@ -5054,7 +5040,8 @@ CFGBlock *CFGBuilder::VisitChildrenForTemporaryDtors(Stmt *E, CFGBlock *B = Block; for (Stmt *Child : E->children()) if (Child) - if (CFGBlock *R = VisitForTemporaryDtors(Child, ExternallyDestructed, Context)) + if (CFGBlock *R = + VisitForTemporaryDtors(Child, ExternallyDestructed, Context)) B = R; return B; @@ -5066,7 +5053,8 @@ CFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors( // For the comma operator, the LHS expression is evaluated before the RHS // expression, so prepend temporary destructors for the LHS first. CFGBlock *LHSBlock = VisitForTemporaryDtors(E->getLHS(), false, Context); - CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS(), ExternallyDestructed, Context); + CFGBlock *RHSBlock = + VisitForTemporaryDtors(E->getRHS(), ExternallyDestructed, Context); return RHSBlock ? RHSBlock : LHSBlock; } @@ -5100,7 +5088,8 @@ CFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors( } CFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors( - CXXBindTemporaryExpr *E, bool ExternallyDestructed, TempDtorContext &Context) { + CXXBindTemporaryExpr *E, bool ExternallyDestructed, + TempDtorContext &Context) { // First add destructors for temporaries in subexpression. // Because VisitCXXBindTemporaryExpr calls setDestructed: CFGBlock *B = VisitForTemporaryDtors(E->getSubExpr(), true, Context); @@ -5115,12 +5104,14 @@ CFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors( // create a new block for the destructor which does not have as a // successor anything built thus far. Control won't flow out of this // block. - if (B) Succ = B; + if (B) + Succ = B; Block = createNoReturnBlock(); } else if (Context.needsTempDtorBranch()) { // If we need to introduce a branch, we add a new block that we will hook // up to a decision block later. - if (B) Succ = B; + if (B) + Succ = B; Block = createBlock(); } else { autoCreateBlock(); @@ -5159,7 +5150,8 @@ CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors( CFGBlock *ConditionSucc = Succ; TryResult ConditionVal = tryEvaluateBool(E->getCond()); TryResult NegatedVal = ConditionVal; - if (NegatedVal.isKnown()) NegatedVal.negate(); + if (NegatedVal.isKnown()) + NegatedVal.negate(); TempDtorContext TrueContext( bothKnownTrue(Context.KnownExecuted, ConditionVal)); @@ -5287,73 +5279,73 @@ bool CFG::isLinear() const { const CXXDestructorDecl * CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const { switch (getKind()) { - case CFGElement::Initializer: - case CFGElement::NewAllocator: - case CFGElement::LoopExit: - case CFGElement::LifetimeEnds: - case CFGElement::Statement: - case CFGElement::Constructor: - case CFGElement::CXXRecordTypedCall: - case CFGElement::ScopeBegin: - case CFGElement::ScopeEnd: - case CFGElement::CleanupFunction: - llvm_unreachable("getDestructorDecl should only be used with " - "ImplicitDtors"); - case CFGElement::AutomaticObjectDtor: { - const VarDecl *var = castAs().getVarDecl(); - QualType ty = var->getType(); - - // FIXME: See CFGBuilder::addLocalScopeForVarDecl. - // - // Lifetime-extending constructs are handled here. This works for a single - // temporary in an initializer expression. - if (ty->isReferenceType()) { - if (const Expr *Init = var->getInit()) { - ty = getReferenceInitTemporaryType(Init); - } - } - - while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) { - ty = arrayType->getElementType(); + case CFGElement::Initializer: + case CFGElement::NewAllocator: + case CFGElement::LoopExit: + case CFGElement::LifetimeEnds: + case CFGElement::Statement: + case CFGElement::Constructor: + case CFGElement::CXXRecordTypedCall: + case CFGElement::ScopeBegin: + case CFGElement::ScopeEnd: + case CFGElement::CleanupFunction: + llvm_unreachable("getDestructorDecl should only be used with " + "ImplicitDtors"); + case CFGElement::AutomaticObjectDtor: { + const VarDecl *var = castAs().getVarDecl(); + QualType ty = var->getType(); + + // FIXME: See CFGBuilder::addLocalScopeForVarDecl. + // + // Lifetime-extending constructs are handled here. This works for a single + // temporary in an initializer expression. + if (ty->isReferenceType()) { + if (const Expr *Init = var->getInit()) { + ty = getReferenceInitTemporaryType(Init); } - - // The situation when the type of the lifetime-extending reference - // does not correspond to the type of the object is supposed - // to be handled by now. In particular, 'ty' is now the unwrapped - // record type. - const CXXRecordDecl *classDecl = ty->getAsCXXRecordDecl(); - assert(classDecl); - return classDecl->getDestructor(); - } - case CFGElement::DeleteDtor: { - const CXXDeleteExpr *DE = castAs().getDeleteExpr(); - QualType DTy = DE->getDestroyedType(); - DTy = DTy.getNonReferenceType(); - const CXXRecordDecl *classDecl = - astContext.getBaseElementType(DTy)->getAsCXXRecordDecl(); - return classDecl->getDestructor(); } - case CFGElement::TemporaryDtor: { - const CXXBindTemporaryExpr *bindExpr = - castAs().getBindTemporaryExpr(); - const CXXTemporary *temp = bindExpr->getTemporary(); - return temp->getDestructor(); + + while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) { + ty = arrayType->getElementType(); } - case CFGElement::MemberDtor: { - const FieldDecl *field = castAs().getFieldDecl(); - QualType ty = field->getType(); - while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) { - ty = arrayType->getElementType(); - } + // The situation when the type of the lifetime-extending reference + // does not correspond to the type of the object is supposed + // to be handled by now. In particular, 'ty' is now the unwrapped + // record type. + const CXXRecordDecl *classDecl = ty->getAsCXXRecordDecl(); + assert(classDecl); + return classDecl->getDestructor(); + } + case CFGElement::DeleteDtor: { + const CXXDeleteExpr *DE = castAs().getDeleteExpr(); + QualType DTy = DE->getDestroyedType(); + DTy = DTy.getNonReferenceType(); + const CXXRecordDecl *classDecl = + astContext.getBaseElementType(DTy)->getAsCXXRecordDecl(); + return classDecl->getDestructor(); + } + case CFGElement::TemporaryDtor: { + const CXXBindTemporaryExpr *bindExpr = + castAs().getBindTemporaryExpr(); + const CXXTemporary *temp = bindExpr->getTemporary(); + return temp->getDestructor(); + } + case CFGElement::MemberDtor: { + const FieldDecl *field = castAs().getFieldDecl(); + QualType ty = field->getType(); - const CXXRecordDecl *classDecl = ty->getAsCXXRecordDecl(); - assert(classDecl); - return classDecl->getDestructor(); + while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) { + ty = arrayType->getElementType(); } - case CFGElement::BaseDtor: - // Not yet supported. - return nullptr; + + const CXXRecordDecl *classDecl = ty->getAsCXXRecordDecl(); + assert(classDecl); + return classDecl->getDestructor(); + } + case CFGElement::BaseDtor: + // Not yet supported. + return nullptr; } llvm_unreachable("getKind() returned bogus value"); } @@ -5372,8 +5364,7 @@ CFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock) UnreachableBlock(B == AlternateBlock ? nullptr : AlternateBlock, B == AlternateBlock ? AB_Alternate : AB_Normal) {} -void CFGBlock::addSuccessor(AdjacentBlock Succ, - BumpVectorContext &C) { +void CFGBlock::addSuccessor(AdjacentBlock Succ, BumpVectorContext &C) { if (CFGBlock *B = Succ.getReachableBlock()) B->Preds.push_back(AdjacentBlock(this, Succ.isReachable()), C); @@ -5384,7 +5375,7 @@ void CFGBlock::addSuccessor(AdjacentBlock Succ, } bool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F, - const CFGBlock *From, const CFGBlock *To) { + const CFGBlock *From, const CFGBlock *To) { if (F.IgnoreNullPredecessors && !From) return true; @@ -5392,7 +5383,7 @@ bool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F, // If the 'To' has no label or is labeled but the label isn't a // CaseStmt then filter this edge. if (const SwitchStmt *S = - dyn_cast_or_null(From->getTerminatorStmt())) { + dyn_cast_or_null(From->getTerminatorStmt())) { if (S->isAllEnumCasesCovered()) { const Stmt *L = To->getLabel(); if (!L || !isa(L)) @@ -5410,7 +5401,7 @@ bool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F, namespace { -class StmtPrinterHelper : public PrinterHelper { +class StmtPrinterHelper : public PrinterHelper { using StmtMapTy = llvm::DenseMap>; using DeclMapTy = llvm::DenseMap>; @@ -5421,58 +5412,54 @@ class StmtPrinterHelper : public PrinterHelper { const LangOptions &LangOpts; public: - StmtPrinterHelper(const CFG* cfg, const LangOptions &LO) - : LangOpts(LO) { + StmtPrinterHelper(const CFG *cfg, const LangOptions &LO) : LangOpts(LO) { if (!cfg) return; - for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) { + for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) { unsigned j = 1; - for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ; - BI != BEnd; ++BI, ++j ) { + for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end(); + BI != BEnd; ++BI, ++j) { if (std::optional SE = BI->getAs()) { - const Stmt *stmt= SE->getStmt(); + const Stmt *stmt = SE->getStmt(); std::pair P((*I)->getBlockID(), j); StmtMap[stmt] = P; switch (stmt->getStmtClass()) { - case Stmt::DeclStmtClass: - DeclMap[cast(stmt)->getSingleDecl()] = P; - break; - case Stmt::IfStmtClass: { - const VarDecl *var = cast(stmt)->getConditionVariable(); - if (var) - DeclMap[var] = P; - break; - } - case Stmt::ForStmtClass: { - const VarDecl *var = cast(stmt)->getConditionVariable(); - if (var) - DeclMap[var] = P; - break; - } - case Stmt::WhileStmtClass: { - const VarDecl *var = - cast(stmt)->getConditionVariable(); - if (var) - DeclMap[var] = P; - break; - } - case Stmt::SwitchStmtClass: { - const VarDecl *var = - cast(stmt)->getConditionVariable(); - if (var) - DeclMap[var] = P; - break; - } - case Stmt::CXXCatchStmtClass: { - const VarDecl *var = - cast(stmt)->getExceptionDecl(); - if (var) - DeclMap[var] = P; - break; - } - default: - break; + case Stmt::DeclStmtClass: + DeclMap[cast(stmt)->getSingleDecl()] = P; + break; + case Stmt::IfStmtClass: { + const VarDecl *var = cast(stmt)->getConditionVariable(); + if (var) + DeclMap[var] = P; + break; + } + case Stmt::ForStmtClass: { + const VarDecl *var = cast(stmt)->getConditionVariable(); + if (var) + DeclMap[var] = P; + break; + } + case Stmt::WhileStmtClass: { + const VarDecl *var = cast(stmt)->getConditionVariable(); + if (var) + DeclMap[var] = P; + break; + } + case Stmt::SwitchStmtClass: { + const VarDecl *var = cast(stmt)->getConditionVariable(); + if (var) + DeclMap[var] = P; + break; + } + case Stmt::CXXCatchStmtClass: { + const VarDecl *var = cast(stmt)->getExceptionDecl(); + if (var) + DeclMap[var] = P; + break; + } + default: + break; } } } @@ -5491,8 +5478,8 @@ class StmtPrinterHelper : public PrinterHelper { if (I == StmtMap.end()) return false; - if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock - && I->second.second == currStmt) { + if (currentBlock >= 0 && I->second.first == (unsigned)currentBlock && + I->second.second == currStmt) { return false; } @@ -5506,8 +5493,8 @@ class StmtPrinterHelper : public PrinterHelper { if (I == DeclMap.end()) return false; - if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock - && I->second.second == currStmt) { + if (currentBlock >= 0 && I->second.first == (unsigned)currentBlock && + I->second.second == currStmt) { return false; } @@ -5517,13 +5504,13 @@ class StmtPrinterHelper : public PrinterHelper { }; class CFGBlockTerminatorPrint - : public StmtVisitor { + : public StmtVisitor { raw_ostream &OS; - StmtPrinterHelper* Helper; + StmtPrinterHelper *Helper; PrintingPolicy Policy; public: - CFGBlockTerminatorPrint(raw_ostream &os, StmtPrinterHelper* helper, + CFGBlockTerminatorPrint(raw_ostream &os, StmtPrinterHelper *helper, const PrintingPolicy &Policy) : OS(os), Helper(helper), Policy(Policy) { this->Policy.IncludeNewlines = false; @@ -5546,7 +5533,7 @@ class CFGBlockTerminatorPrint } void VisitForStmt(ForStmt *F) { - OS << "for (" ; + OS << "for ("; if (F->getInit()) OS << "..."; OS << "; "; @@ -5559,7 +5546,7 @@ class CFGBlockTerminatorPrint } void VisitWhileStmt(WhileStmt *W) { - OS << "while " ; + OS << "while "; if (Stmt *C = W->getCond()) C->printPretty(OS, Helper, Policy); } @@ -5581,7 +5568,7 @@ class CFGBlockTerminatorPrint void VisitSEHTryStmt(SEHTryStmt *CS) { OS << "__try ..."; } - void VisitAbstractConditionalOperator(AbstractConditionalOperator* C) { + void VisitAbstractConditionalOperator(AbstractConditionalOperator *C) { if (Stmt *Cond = C->getCond()) Cond->printPretty(OS, Helper, Policy); OS << " ? ... : ..."; @@ -5600,7 +5587,7 @@ class CFGBlockTerminatorPrint T->printPretty(OS, Helper, Policy); } - void VisitBinaryOperator(BinaryOperator* B) { + void VisitBinaryOperator(BinaryOperator *B) { if (!B->isLogicalOp()) { VisitExpr(B); return; @@ -5610,20 +5597,18 @@ class CFGBlockTerminatorPrint B->getLHS()->printPretty(OS, Helper, Policy); switch (B->getOpcode()) { - case BO_LOr: - OS << " || ..."; - return; - case BO_LAnd: - OS << " && ..."; - return; - default: - llvm_unreachable("Invalid logical operator."); + case BO_LOr: + OS << " || ..."; + return; + case BO_LAnd: + OS << " && ..."; + return; + default: + llvm_unreachable("Invalid logical operator."); } } - void VisitExpr(Expr *E) { - E->printPretty(OS, Helper, Policy); - } + void VisitExpr(Expr *E) { E->printPretty(OS, Helper, Policy); } public: void print(CFGTerminator T) { @@ -5672,7 +5657,8 @@ static void print_construction_context(raw_ostream &OS, switch (CC->getKind()) { case ConstructionContext::SimpleConstructorInitializerKind: { OS << ", "; - const auto *SICC = cast(CC); + const auto *SICC = + cast(CC); print_initializer(OS, Helper, SICC->getCXXCtorInitializer()); return; } @@ -5743,7 +5729,7 @@ static void print_construction_context(raw_ostream &OS, return; } } - for (auto I: Stmts) + for (auto I : Stmts) if (I) { OS << ", "; Helper.handledStmt(const_cast(I), OS); @@ -5776,16 +5762,16 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper, auto Children = Sub->children(); if (Children.begin() != Children.end()) { OS << "({ ... ; "; - Helper.handledStmt(*SE->getSubStmt()->body_rbegin(),OS); + Helper.handledStmt(*SE->getSubStmt()->body_rbegin(), OS); OS << " })\n"; return; } } // special printing for comma expressions. - if (const BinaryOperator* B = dyn_cast(S)) { + if (const BinaryOperator *B = dyn_cast(S)) { if (B->getOpcode() == BO_Comma) { OS << "... , "; - Helper.handledStmt(B->getRHS(),OS); + Helper.handledStmt(B->getRHS(), OS); OS << '\n'; return; } @@ -5851,7 +5837,8 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper, break; case CFGElement::Kind::LoopExit: - OS << E.castAs().getLoopStmt()->getStmtClassName() << " (LoopExit)\n"; + OS << E.castAs().getLoopStmt()->getStmtClassName() + << " (LoopExit)\n"; break; case CFGElement::Kind::ScopeBegin: @@ -5870,7 +5857,8 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper, case CFGElement::Kind::NewAllocator: OS << "CFGNewAllocator("; - if (const CXXNewExpr *AllocExpr = E.castAs().getAllocatorExpr()) + if (const CXXNewExpr *AllocExpr = + E.castAs().getAllocatorExpr()) AllocExpr->getType().print(OS, PrintingPolicy(Helper.getLangOpts())); OS << ")\n"; break; @@ -5880,8 +5868,7 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper, const CXXRecordDecl *RD = DE.getCXXRecordDecl(); if (!RD) return; - CXXDeleteExpr *DelExpr = - const_cast(DE.getDeleteExpr()); + CXXDeleteExpr *DelExpr = const_cast(DE.getDeleteExpr()); Helper.handledStmt(cast(DelExpr->getArgument()), OS); OS << "->~" << RD->getName().str() << "()"; OS << " (Implicit destructor)\n"; @@ -5915,8 +5902,7 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper, } } -static void print_block(raw_ostream &OS, const CFG* cfg, - const CFGBlock &B, +static void print_block(raw_ostream &OS, const CFG *cfg, const CFGBlock &B, StmtPrinterHelper &Helper, bool print_edges, bool ShowColors) { Helper.setBlockID(B.getBlockID()); @@ -5942,7 +5928,7 @@ static void print_block(raw_ostream &OS, const CFG* cfg, OS.resetColor(); // Print the label of this block. - if (Stmt *Label = const_cast(B.getLabel())) { + if (Stmt *Label = const_cast(B.getLabel())) { if (print_edges) OS << " "; @@ -5986,8 +5972,7 @@ static void print_block(raw_ostream &OS, const CFG* cfg, // Iterate through the statements in the block and print them. unsigned j = 1; - for (CFGBlock::const_iterator I = B.begin(), E = B.end() ; - I != E ; ++I, ++j ) { + for (CFGBlock::const_iterator I = B.begin(), E = B.end(); I != E; ++I, ++j) { // Print the statement # in the basic block and the statement itself. if (print_edges) OS << " "; @@ -6023,7 +6008,7 @@ static void print_block(raw_ostream &OS, const CFG* cfg, const raw_ostream::Colors Color = raw_ostream::BLUE; if (ShowColors) OS.changeColor(Color); - OS << " Preds " ; + OS << " Preds "; if (ShowColors) OS.resetColor(); OS << '(' << B.pred_size() << "):"; @@ -6086,8 +6071,7 @@ static void print_block(raw_ostream &OS, const CFG* cfg, OS << " B" << B->getBlockID(); if (!Reachable) OS << "(Unreachable)"; - } - else { + } else { OS << " NULL"; } } @@ -6112,7 +6096,7 @@ void CFG::print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const { print_block(OS, this, getEntry(), Helper, true, ShowColors); // Iterate through the CFGBlocks and print them one by one. - for (const_iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) { + for (const_iterator I = Blocks.begin(), E = Blocks.end(); I != E; ++I) { // Skip the entry block, because we already printed it. if (&(**I) == &getEntry() || &(**I) == &getExit()) continue; @@ -6131,7 +6115,7 @@ size_t CFGBlock::getIndexInCFG() const { } /// dump - A simply pretty printer of a CFGBlock that outputs to stderr. -void CFGBlock::dump(const CFG* cfg, const LangOptions &LO, +void CFGBlock::dump(const CFG *cfg, const LangOptions &LO, bool ShowColors) const { print(llvm::errs(), cfg, LO, ShowColors); } @@ -6142,16 +6126,15 @@ LLVM_DUMP_METHOD void CFGBlock::dump() const { /// print - A simple pretty printer of a CFGBlock that outputs to an ostream. /// Generally this will only be called from CFG::print. -void CFGBlock::print(raw_ostream &OS, const CFG* cfg, - const LangOptions &LO, bool ShowColors) const { +void CFGBlock::print(raw_ostream &OS, const CFG *cfg, const LangOptions &LO, + bool ShowColors) const { StmtPrinterHelper Helper(cfg, LO); print_block(OS, cfg, *this, Helper, true, ShowColors); OS << '\n'; } /// printTerminator - A simple pretty printer of the terminator of a CFGBlock. -void CFGBlock::printTerminator(raw_ostream &OS, - const LangOptions &LO) const { +void CFGBlock::printTerminator(raw_ostream &OS, const LangOptions &LO) const { CFGBlockTerminatorPrint TPrinter(OS, nullptr, PrintingPolicy(LO)); TPrinter.print(getTerminator()); } @@ -6268,55 +6251,55 @@ Stmt *CFGBlock::getTerminatorCondition(bool StripParens) { Expr *E = nullptr; switch (Terminator->getStmtClass()) { - default: - break; + default: + break; - case Stmt::CXXForRangeStmtClass: - E = cast(Terminator)->getCond(); - break; + case Stmt::CXXForRangeStmtClass: + E = cast(Terminator)->getCond(); + break; - case Stmt::ForStmtClass: - E = cast(Terminator)->getCond(); - break; + case Stmt::ForStmtClass: + E = cast(Terminator)->getCond(); + break; - case Stmt::WhileStmtClass: - E = cast(Terminator)->getCond(); - break; + case Stmt::WhileStmtClass: + E = cast(Terminator)->getCond(); + break; - case Stmt::DoStmtClass: - E = cast(Terminator)->getCond(); - break; + case Stmt::DoStmtClass: + E = cast(Terminator)->getCond(); + break; - case Stmt::IfStmtClass: - E = cast(Terminator)->getCond(); - break; + case Stmt::IfStmtClass: + E = cast(Terminator)->getCond(); + break; - case Stmt::ChooseExprClass: - E = cast(Terminator)->getCond(); - break; + case Stmt::ChooseExprClass: + E = cast(Terminator)->getCond(); + break; - case Stmt::IndirectGotoStmtClass: - E = cast(Terminator)->getTarget(); - break; + case Stmt::IndirectGotoStmtClass: + E = cast(Terminator)->getTarget(); + break; - case Stmt::SwitchStmtClass: - E = cast(Terminator)->getCond(); - break; + case Stmt::SwitchStmtClass: + E = cast(Terminator)->getCond(); + break; - case Stmt::BinaryConditionalOperatorClass: - E = cast(Terminator)->getCond(); - break; + case Stmt::BinaryConditionalOperatorClass: + E = cast(Terminator)->getCond(); + break; - case Stmt::ConditionalOperatorClass: - E = cast(Terminator)->getCond(); - break; + case Stmt::ConditionalOperatorClass: + E = cast(Terminator)->getCond(); + break; - case Stmt::BinaryOperatorClass: // '&&' and '||' - E = cast(Terminator)->getLHS(); - break; + case Stmt::BinaryOperatorClass: // '&&' and '||' + E = cast(Terminator)->getLHS(); + break; - case Stmt::ObjCForCollectionStmtClass: - return Terminator; + case Stmt::ObjCForCollectionStmtClass: + return Terminator; } if (!StripParens) @@ -6334,29 +6317,29 @@ static StmtPrinterHelper *GraphHelper; void CFG::viewCFG(const LangOptions &LO) const { StmtPrinterHelper H(this, LO); GraphHelper = &H; - llvm::ViewGraph(this,"CFG"); + llvm::ViewGraph(this, "CFG"); GraphHelper = nullptr; } namespace llvm { -template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits { +template <> struct DOTGraphTraits : public DefaultDOTGraphTraits { DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} static std::string getNodeLabel(const CFGBlock *Node, const CFG *Graph) { std::string OutSStr; llvm::raw_string_ostream Out(OutSStr); - print_block(Out,Graph, *Node, *GraphHelper, false, false); - std::string& OutStr = Out.str(); + print_block(Out, Graph, *Node, *GraphHelper, false, false); + std::string &OutStr = Out.str(); - if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); + if (OutStr[0] == '\n') + OutStr.erase(OutStr.begin()); // Process string output to make it nicer... for (unsigned i = 0; i != OutStr.length(); ++i) - if (OutStr[i] == '\n') { // Left justify + if (OutStr[i] == '\n') { // Left justify OutStr[i] = '\\'; - OutStr.insert(OutStr.begin()+i+1, 'l'); + OutStr.insert(OutStr.begin() + i + 1, 'l'); } return OutStr; diff --git a/clang/lib/Analysis/CFGReachabilityAnalysis.cpp b/clang/lib/Analysis/CFGReachabilityAnalysis.cpp index 2b5d6c466cde1..ed6d89ea45f46 100644 --- a/clang/lib/Analysis/CFGReachabilityAnalysis.cpp +++ b/clang/lib/Analysis/CFGReachabilityAnalysis.cpp @@ -24,7 +24,7 @@ CFGReverseBlockReachabilityAnalysis::CFGReverseBlockReachabilityAnalysis( : analyzed(cfg.getNumBlockIDs(), false) {} bool CFGReverseBlockReachabilityAnalysis::isReachable(const CFGBlock *Src, - const CFGBlock *Dst) { + const CFGBlock *Dst) { const unsigned DstBlockID = Dst->getBlockID(); // If we haven't analyzed the destination node, run the analysis now @@ -62,13 +62,13 @@ void CFGReverseBlockReachabilityAnalysis::mapReachability(const CFGBlock *Dst) { if (!firstRun) { // Don't insert Dst -> Dst unless it was a predecessor of itself DstReachability[block->getBlockID()] = true; - } - else + } else firstRun = false; // Add the predecessors to the worklist. for (CFGBlock::const_pred_iterator i = block->pred_begin(), - e = block->pred_end(); i != e; ++i) { + e = block->pred_end(); + i != e; ++i) { if (*i) worklist.push_back(*i); } diff --git a/clang/lib/Analysis/CFGStmtMap.cpp b/clang/lib/Analysis/CFGStmtMap.cpp index c3a4581e1fb10..a44f8e89f72e0 100644 --- a/clang/lib/Analysis/CFGStmtMap.cpp +++ b/clang/lib/Analysis/CFGStmtMap.cpp @@ -11,16 +11,16 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/DenseMap.h" +#include "clang/Analysis/CFGStmtMap.h" #include "clang/AST/ParentMap.h" #include "clang/Analysis/CFG.h" -#include "clang/Analysis/CFGStmtMap.h" +#include "llvm/ADT/DenseMap.h" #include using namespace clang; -typedef llvm::DenseMap SMap; -static SMap *AsMap(void *m) { return (SMap*) m; } +typedef llvm::DenseMap SMap; +static SMap *AsMap(void *m) { return (SMap *)m; } CFGStmtMap::~CFGStmtMap() { delete AsMap(M); } @@ -61,7 +61,6 @@ static void Accumulate(SMap &SM, CFGBlock *B) { continue; Entry = B; - } // Look at the label of the block. @@ -88,4 +87,3 @@ CFGStmtMap *CFGStmtMap::Build(CFG *C, ParentMap *PM) { return new CFGStmtMap(PM, SM); } - diff --git a/clang/lib/Analysis/CallGraph.cpp b/clang/lib/Analysis/CallGraph.cpp index f892980ed3138..04636076d9478 100644 --- a/clang/lib/Analysis/CallGraph.cpp +++ b/clang/lib/Analysis/CallGraph.cpp @@ -101,14 +101,10 @@ class CGBuilder : public StmtVisitor { } // Include the evaluation of the default argument. - void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { - Visit(E->getExpr()); - } + void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { Visit(E->getExpr()); } // Include the evaluation of the default initializers in a class. - void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { - Visit(E->getExpr()); - } + void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { Visit(E->getExpr()); } // Adds may-call edges for the ObjC message sends. void VisitObjCMessageExpr(ObjCMessageExpr *ME) { @@ -146,9 +142,7 @@ void CallGraph::addNodesForBlocks(DeclContext *D) { addNodesForBlocks(DC); } -CallGraph::CallGraph() { - Root = getOrInsertNode(nullptr); -} +CallGraph::CallGraph() { Root = getOrInsertNode(nullptr); } CallGraph::~CallGraph() = default; @@ -175,7 +169,7 @@ bool CallGraph::includeCalleeInGraph(const Decl *D) { return true; } -void CallGraph::addNodeForDecl(Decl* D, bool IsGlobal) { +void CallGraph::addNodeForDecl(Decl *D, bool IsGlobal) { assert(D); // Allocate a new node, mark it as root, and process its calls. @@ -196,7 +190,8 @@ void CallGraph::addNodeForDecl(Decl* D, bool IsGlobal) { CallGraphNode *CallGraph::getNode(const Decl *F) const { FunctionMapTy::const_iterator I = FunctionMap.find(F); - if (I == FunctionMap.end()) return nullptr; + if (I == FunctionMap.end()) + return nullptr; return I->second.get(); } @@ -222,7 +217,9 @@ void CallGraph::print(raw_ostream &OS) const { // sure the output is deterministic. llvm::ReversePostOrderTraversal RPOT(this); for (llvm::ReversePostOrderTraversal::rpo_iterator - I = RPOT.begin(), E = RPOT.end(); I != E; ++I) { + I = RPOT.begin(), + E = RPOT.end(); + I != E; ++I) { const CallGraphNode *N = *I; OS << " Function: "; @@ -232,8 +229,8 @@ void CallGraph::print(raw_ostream &OS) const { N->print(OS); OS << " calls: "; - for (CallGraphNode::const_iterator CI = N->begin(), - CE = N->end(); CI != CE; ++CI) { + for (CallGraphNode::const_iterator CI = N->begin(), CE = N->end(); CI != CE; + ++CI) { assert(CI->Callee != Root && "No one can call the root node."); CI->Callee->print(OS); OS << " "; @@ -243,29 +240,23 @@ void CallGraph::print(raw_ostream &OS) const { OS.flush(); } -LLVM_DUMP_METHOD void CallGraph::dump() const { - print(llvm::errs()); -} +LLVM_DUMP_METHOD void CallGraph::dump() const { print(llvm::errs()); } -void CallGraph::viewGraph() const { - llvm::ViewGraph(this, "CallGraph"); -} +void CallGraph::viewGraph() const { llvm::ViewGraph(this, "CallGraph"); } void CallGraphNode::print(raw_ostream &os) const { if (const NamedDecl *ND = dyn_cast_or_null(FD)) - return ND->printQualifiedName(os); + return ND->printQualifiedName(os); os << "< >"; } -LLVM_DUMP_METHOD void CallGraphNode::dump() const { - print(llvm::errs()); -} +LLVM_DUMP_METHOD void CallGraphNode::dump() const { print(llvm::errs()); } namespace llvm { template <> -struct DOTGraphTraits : public DefaultDOTGraphTraits { - DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} +struct DOTGraphTraits : public DefaultDOTGraphTraits { + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} static std::string getNodeLabel(const CallGraphNode *Node, const CallGraph *CG) { diff --git a/clang/lib/Analysis/CocoaConventions.cpp b/clang/lib/Analysis/CocoaConventions.cpp index 836859c223458..58ec28c0b6130 100644 --- a/clang/lib/Analysis/CocoaConventions.cpp +++ b/clang/lib/Analysis/CocoaConventions.cpp @@ -21,8 +21,7 @@ using namespace clang; using namespace ento; -bool cocoa::isRefType(QualType RetTy, StringRef Prefix, - StringRef Name) { +bool cocoa::isRefType(QualType RetTy, StringRef Prefix, StringRef Name) { // Recursively walk the typedef stack, allowing typedefs of reference types. while (const TypedefType *TD = RetTy->getAs()) { StringRef TDName = TD->getDecl()->getIdentifier()->getName(); @@ -38,7 +37,7 @@ bool cocoa::isRefType(QualType RetTy, StringRef Prefix, return false; // Is the type void*? - const PointerType* PT = RetTy->castAs(); + const PointerType *PT = RetTy->castAs(); if (!PT || !PT->getPointeeType().getUnqualifiedType()->isVoidType()) return false; @@ -49,9 +48,8 @@ bool cocoa::isRefType(QualType RetTy, StringRef Prefix, /// Returns true when the passed-in type is a CF-style reference-counted /// type from the DiskArbitration framework. static bool isDiskArbitrationAPIRefType(QualType T) { - return cocoa::isRefType(T, "DADisk") || - cocoa::isRefType(T, "DADissenter") || - cocoa::isRefType(T, "DASessionRef"); + return cocoa::isRefType(T, "DADisk") || cocoa::isRefType(T, "DADissenter") || + cocoa::isRefType(T, "DASessionRef"); } bool coreFoundation::isCFObjectRef(QualType T) { @@ -61,7 +59,6 @@ bool coreFoundation::isCFObjectRef(QualType T) { isDiskArbitrationAPIRefType(T); } - bool cocoa::isCocoaObjectRef(QualType Ty) { if (!Ty->isObjCObjectPointerType()) return false; @@ -87,7 +84,7 @@ bool cocoa::isCocoaObjectRef(QualType Ty) { if (!ID->hasDefinition()) return true; - for ( ; ID ; ID = ID->getSuperClass()) + for (; ID; ID = ID->getSuperClass()) if (ID->getIdentifier()->getName() == "NSObject") return true; @@ -98,7 +95,8 @@ bool coreFoundation::followsCreateRule(const FunctionDecl *fn) { // For now, *just* base this on the function name, not on anything else. const IdentifierInfo *ident = fn->getIdentifier(); - if (!ident) return false; + if (!ident) + return false; StringRef functionName = ident->getName(); StringRef::iterator it = functionName.begin(); @@ -107,7 +105,7 @@ bool coreFoundation::followsCreateRule(const FunctionDecl *fn) { while (true) { // Scan for the start of 'create' or 'copy'. - for ( ; it != endI ; ++it) { + for (; it != endI; ++it) { // Search for the first character. It can either be 'C' or 'c'. char ch = *it; if (ch == 'C' || ch == 'c') { diff --git a/clang/lib/Analysis/ConstructionContext.cpp b/clang/lib/Analysis/ConstructionContext.cpp index 8a862c06f13ad..38ff8962486e3 100644 --- a/clang/lib/Analysis/ConstructionContext.cpp +++ b/clang/lib/Analysis/ConstructionContext.cpp @@ -51,7 +51,9 @@ ConstructionContext::createMaterializedTemporaryFromLayers( // If the object requires destruction and is not lifetime-extended, // then it must have a BTE within its MTE, otherwise it shouldn't. // FIXME: This should be an assertion. - if (!BTE && !(MTE->getType().getCanonicalType()->getAsCXXRecordDecl() + if (!BTE && !(MTE->getType() + .getCanonicalType() + ->getAsCXXRecordDecl() ->hasTrivialDestructor() || MTE->getStorageDuration() != SD_FullExpression)) { return nullptr; @@ -83,8 +85,8 @@ ConstructionContext::createMaterializedTemporaryFromLayers( // In this case, skip copy elision entirely. return create(C, BTE, MTE); } - return create( - C, BTE, MTE, ElidedCE, ElidedCC); + return create(C, BTE, MTE, + ElidedCE, ElidedCC); } // This is a normal temporary. @@ -108,8 +110,11 @@ const ConstructionContext *ConstructionContext::createBoundTemporaryFromLayers( switch (ParentItem.getKind()) { case ConstructionContextItem::VariableKind: { const auto *DS = cast(ParentItem.getStmt()); - assert(!cast(DS->getSingleDecl())->getType().getCanonicalType() - ->getAsCXXRecordDecl()->hasTrivialDestructor()); + assert(!cast(DS->getSingleDecl()) + ->getType() + .getCanonicalType() + ->getAsCXXRecordDecl() + ->hasTrivialDestructor()); return create(C, DS, BTE); } case ConstructionContextItem::NewAllocatorKind: { @@ -118,10 +123,12 @@ const ConstructionContext *ConstructionContext::createBoundTemporaryFromLayers( case ConstructionContextItem::ReturnKind: { assert(ParentLayer->isLast()); const auto *RS = cast(ParentItem.getStmt()); - assert(!RS->getRetValue()->getType().getCanonicalType() - ->getAsCXXRecordDecl()->hasTrivialDestructor()); - return create(C, RS, - BTE); + assert(!RS->getRetValue() + ->getType() + .getCanonicalType() + ->getAsCXXRecordDecl() + ->hasTrivialDestructor()); + return create(C, RS, BTE); } case ConstructionContextItem::MaterializationKind: { @@ -151,8 +158,11 @@ const ConstructionContext *ConstructionContext::createBoundTemporaryFromLayers( case ConstructionContextItem::InitializerKind: { assert(ParentLayer->isLast()); const auto *I = ParentItem.getCXXCtorInitializer(); - assert(!I->getAnyMember()->getType().getCanonicalType() - ->getAsCXXRecordDecl()->hasTrivialDestructor()); + assert(!I->getAnyMember() + ->getType() + .getCanonicalType() + ->getAsCXXRecordDecl() + ->hasTrivialDestructor()); return create( C, I, BTE); } @@ -196,8 +206,10 @@ const ConstructionContext *ConstructionContext::createFromLayers( } case ConstructionContextItem::TemporaryDestructorKind: { const auto *BTE = cast(TopItem.getStmt()); - assert(BTE->getType().getCanonicalType()->getAsCXXRecordDecl() - ->hasNonTrivialDestructor()); + assert(BTE->getType() + .getCanonicalType() + ->getAsCXXRecordDecl() + ->hasNonTrivialDestructor()); return createBoundTemporaryFromLayers(C, BTE, TopLayer->getParent()); } case ConstructionContextItem::ElidedDestructorKind: { diff --git a/clang/lib/Analysis/Consumed.cpp b/clang/lib/Analysis/Consumed.cpp index d01c7f688e8b5..41bb960d7bf45 100644 --- a/clang/lib/Analysis/Consumed.cpp +++ b/clang/lib/Analysis/Consumed.cpp @@ -80,7 +80,8 @@ static SourceLocation getLastStmtLoc(const CFGBlock *Block) { return StmtNode->getBeginLoc(); } else { for (CFGBlock::const_reverse_iterator BI = Block->rbegin(), - BE = Block->rend(); BI != BE; ++BI) { + BE = Block->rend(); + BI != BE; ++BI) { if (std::optional CS = BI->getAs()) return CS->getStmt()->getBeginLoc(); } @@ -285,10 +286,7 @@ struct VarTestResult { namespace clang { namespace consumed { -enum EffectiveOp { - EO_And, - EO_Or -}; +enum EffectiveOp { EO_And, EO_Or }; class PropagationInfo { enum { @@ -322,33 +320,32 @@ class PropagationInfo { PropagationInfo(const VarDecl *Var, ConsumedState TestsFor) : InfoType(IT_VarTest) { - VarTest.Var = Var; + VarTest.Var = Var; VarTest.TestsFor = TestsFor; } PropagationInfo(const BinaryOperator *Source, EffectiveOp EOp, const VarTestResult <est, const VarTestResult &RTest) : InfoType(IT_BinTest) { - BinTest.Source = Source; - BinTest.EOp = EOp; - BinTest.LTest = LTest; - BinTest.RTest = RTest; + BinTest.Source = Source; + BinTest.EOp = EOp; + BinTest.LTest = LTest; + BinTest.RTest = RTest; } PropagationInfo(const BinaryOperator *Source, EffectiveOp EOp, const VarDecl *LVar, ConsumedState LTestsFor, const VarDecl *RVar, ConsumedState RTestsFor) : InfoType(IT_BinTest) { - BinTest.Source = Source; - BinTest.EOp = EOp; - BinTest.LTest.Var = LVar; + BinTest.Source = Source; + BinTest.EOp = EOp; + BinTest.LTest.Var = LVar; BinTest.LTest.TestsFor = LTestsFor; - BinTest.RTest.Var = RVar; + BinTest.RTest.Var = RVar; BinTest.RTest.TestsFor = RTestsFor; } - PropagationInfo(ConsumedState State) - : InfoType(IT_State), State(State) {} + PropagationInfo(ConsumedState State) : InfoType(IT_State), State(State) {} PropagationInfo(const VarDecl *Var) : InfoType(IT_Var), Var(Var) {} PropagationInfo(const CXXBindTemporaryExpr *Tmp) : InfoType(IT_Tmp), Tmp(Tmp) {} @@ -401,7 +398,7 @@ class PropagationInfo { return BinTest.EOp; } - const BinaryOperator * testSourceNode() const { + const BinaryOperator *testSourceNode() const { assert(InfoType == IT_BinTest); return BinTest.Source; } @@ -429,10 +426,10 @@ class PropagationInfo { invertConsumedUnconsumed(VarTest.TestsFor)); } else if (InfoType == IT_BinTest) { - return PropagationInfo(BinTest.Source, - BinTest.EOp == EO_And ? EO_Or : EO_And, - BinTest.LTest.Var, invertConsumedUnconsumed(BinTest.LTest.TestsFor), - BinTest.RTest.Var, invertConsumedUnconsumed(BinTest.RTest.TestsFor)); + return PropagationInfo( + BinTest.Source, BinTest.EOp == EO_And ? EO_Or : EO_And, + BinTest.LTest.Var, invertConsumedUnconsumed(BinTest.LTest.TestsFor), + BinTest.RTest.Var, invertConsumedUnconsumed(BinTest.RTest.TestsFor)); } else { return {}; } @@ -442,9 +439,9 @@ class PropagationInfo { } // namespace consumed } // namespace clang -static void -setStateForVarOrTmp(ConsumedStateMap *StateMap, const PropagationInfo &PInfo, - ConsumedState State) { +static void setStateForVarOrTmp(ConsumedStateMap *StateMap, + const PropagationInfo &PInfo, + ConsumedState State) { assert(PInfo.isVar() || PInfo.isTmp()); if (PInfo.isVar()) @@ -458,7 +455,7 @@ namespace consumed { class ConsumedStmtVisitor : public ConstStmtVisitor { using MapType = llvm::DenseMap; - using PairType= std::pair; + using PairType = std::pair; using InfoEntry = MapType::iterator; using ConstInfoEntry = MapType::const_iterator; @@ -492,8 +489,7 @@ class ConsumedStmtVisitor : public ConstStmtVisitor { public: void checkCallability(const PropagationInfo &PInfo, - const FunctionDecl *FunDecl, - SourceLocation BlameLoc); + const FunctionDecl *FunDecl, SourceLocation BlameLoc); bool handleCall(const CallExpr *Call, const Expr *ObjArg, const FunctionDecl *FunD); @@ -525,9 +521,7 @@ class ConsumedStmtVisitor : public ConstStmtVisitor { return {}; } - void reset(ConsumedStateMap *NewStateMap) { - StateMap = NewStateMap; - } + void reset(ConsumedStateMap *NewStateMap) { StateMap = NewStateMap; } }; } // namespace consumed @@ -545,7 +539,7 @@ void ConsumedStmtVisitor::copyInfo(const Expr *From, const Expr *To, ConsumedState NS) { InfoEntry Entry = findInfo(From); if (Entry != PropagationMap.end()) { - PropagationInfo& PInfo = Entry->second; + PropagationInfo &PInfo = Entry->second; ConsumedState CS = PInfo.getAsState(StateMap); if (CS != CS_None) insertInfo(To, PropagationInfo(CS)); @@ -558,7 +552,7 @@ void ConsumedStmtVisitor::copyInfo(const Expr *From, const Expr *To, ConsumedState ConsumedStmtVisitor::getInfo(const Expr *From) { InfoEntry Entry = findInfo(From); if (Entry != PropagationMap.end()) { - PropagationInfo& PInfo = Entry->second; + PropagationInfo &PInfo = Entry->second; return PInfo.getAsState(StateMap); } return CS_None; @@ -568,11 +562,11 @@ ConsumedState ConsumedStmtVisitor::getInfo(const Expr *From) { void ConsumedStmtVisitor::setInfo(const Expr *To, ConsumedState NS) { InfoEntry Entry = findInfo(To); if (Entry != PropagationMap.end()) { - PropagationInfo& PInfo = Entry->second; + PropagationInfo &PInfo = Entry->second; if (PInfo.isPointerToValue()) setStateForVarOrTmp(StateMap, PInfo, NS); } else if (NS != CS_None) { - insertInfo(To, PropagationInfo(NS)); + insertInfo(To, PropagationInfo(NS)); } } @@ -592,8 +586,8 @@ void ConsumedStmtVisitor::checkCallability(const PropagationInfo &PInfo, return; Analyzer.WarningsHandler.warnUseInInvalidState( - FunDecl->getNameAsString(), PInfo.getVar()->getNameAsString(), - stateToString(VarState), BlameLoc); + FunDecl->getNameAsString(), PInfo.getVar()->getNameAsString(), + stateToString(VarState), BlameLoc); } else { ConsumedState TmpState = PInfo.getAsState(StateMap); @@ -601,7 +595,7 @@ void ConsumedStmtVisitor::checkCallability(const PropagationInfo &PInfo, return; Analyzer.WarningsHandler.warnUseOfTempInInvalidState( - FunDecl->getNameAsString(), stateToString(TmpState), BlameLoc); + FunDecl->getNameAsString(), stateToString(TmpState), BlameLoc); } } @@ -612,7 +606,7 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg, const FunctionDecl *FunD) { unsigned Offset = 0; if (isa(Call) && isa(FunD)) - Offset = 1; // first argument is 'this' + Offset = 1; // first argument is 'this' // check explicit parameters for (unsigned Index = Offset; Index < Call->getNumArgs(); ++Index) { @@ -636,8 +630,8 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg, if (ParamState != ExpectedState) Analyzer.WarningsHandler.warnParamTypestateMismatch( - Call->getArg(Index)->getExprLoc(), - stateToString(ExpectedState), stateToString(ParamState)); + Call->getArg(Index)->getExprLoc(), stateToString(ExpectedState), + stateToString(ParamState)); } if (!(Entry->second.isVar() || Entry->second.isTmp())) @@ -667,15 +661,13 @@ bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg, if (PInfo.isVar()) { StateMap->setState(PInfo.getVar(), mapSetTypestateAttrState(STA)); return true; - } - else if (PInfo.isTmp()) { + } else if (PInfo.isTmp()) { StateMap->setState(PInfo.getTmp(), mapSetTypestateAttrState(STA)); return true; } - } - else if (isTestingFunction(FunD) && PInfo.isVar()) { - PropagationMap.insert(PairType(Call, - PropagationInfo(PInfo.getVar(), testsFor(FunD)))); + } else if (isTestingFunction(FunD) && PInfo.isVar()) { + PropagationMap.insert( + PairType(Call, PropagationInfo(PInfo.getVar(), testsFor(FunD)))); } } return false; @@ -701,7 +693,7 @@ void ConsumedStmtVisitor::propagateReturnType(const Expr *Call, void ConsumedStmtVisitor::VisitBinaryOperator(const BinaryOperator *BinOp) { switch (BinOp->getOpcode()) { case BO_LAnd: - case BO_LOr : { + case BO_LOr: { InfoEntry LEntry = findInfo(BinOp->getLHS()), REntry = findInfo(BinOp->getRHS()); @@ -710,20 +702,23 @@ void ConsumedStmtVisitor::VisitBinaryOperator(const BinaryOperator *BinOp) { if (LEntry != PropagationMap.end() && LEntry->second.isVarTest()) { LTest = LEntry->second.getVarTest(); } else { - LTest.Var = nullptr; + LTest.Var = nullptr; LTest.TestsFor = CS_None; } if (REntry != PropagationMap.end() && REntry->second.isVarTest()) { RTest = REntry->second.getVarTest(); } else { - RTest.Var = nullptr; + RTest.Var = nullptr; RTest.TestsFor = CS_None; } if (!(LTest.Var == nullptr && RTest.Var == nullptr)) - PropagationMap.insert(PairType(BinOp, PropagationInfo(BinOp, - static_cast(BinOp->getOpcode() == BO_LOr), LTest, RTest))); + PropagationMap.insert(PairType( + BinOp, + PropagationInfo( + BinOp, static_cast(BinOp->getOpcode() == BO_LOr), + LTest, RTest))); break; } @@ -758,7 +753,7 @@ void ConsumedStmtVisitor::VisitCastExpr(const CastExpr *Cast) { } void ConsumedStmtVisitor::VisitCXXBindTemporaryExpr( - const CXXBindTemporaryExpr *Temp) { + const CXXBindTemporaryExpr *Temp) { InfoEntry Entry = findInfo(Temp->getSubExpr()); @@ -782,15 +777,14 @@ void ConsumedStmtVisitor::VisitCXXConstructExpr(const CXXConstructExpr *Call) { ConsumedState RetState = mapReturnTypestateAttrState(RTA); PropagationMap.insert(PairType(Call, PropagationInfo(RetState))); } else if (Constructor->isDefaultConstructor()) { - PropagationMap.insert(PairType(Call, - PropagationInfo(consumed::CS_Consumed))); + PropagationMap.insert( + PairType(Call, PropagationInfo(consumed::CS_Consumed))); } else if (Constructor->isMoveConstructor()) { copyInfo(Call->getArg(0), Call, CS_Consumed); } else if (Constructor->isCopyConstructor()) { // Copy state from arg. If setStateOnRead then set arg to CS_Unknown. ConsumedState NS = - isSetOnReadPtrType(Constructor->getThisType()) ? - CS_Unknown : CS_None; + isSetOnReadPtrType(Constructor->getThisType()) ? CS_Unknown : CS_None; copyInfo(Call->getArg(0), Call, NS); } else { // TODO: Adjust state of args appropriately. @@ -801,7 +795,7 @@ void ConsumedStmtVisitor::VisitCXXConstructExpr(const CXXConstructExpr *Call) { void ConsumedStmtVisitor::VisitCXXMemberCallExpr( const CXXMemberCallExpr *Call) { - CXXMethodDecl* MD = Call->getMethodDecl(); + CXXMethodDecl *MD = Call->getMethodDecl(); if (!MD) return; @@ -812,7 +806,8 @@ void ConsumedStmtVisitor::VisitCXXMemberCallExpr( void ConsumedStmtVisitor::VisitCXXOperatorCallExpr( const CXXOperatorCallExpr *Call) { const auto *FunDecl = dyn_cast_or_null(Call->getDirectCallee()); - if (!FunDecl) return; + if (!FunDecl) + return; if (Call->getOperator() == OO_Equal) { ConsumedState CS = getInfo(Call->getArg(1)); @@ -846,7 +841,7 @@ void ConsumedStmtVisitor::VisitDeclStmt(const DeclStmt *DeclS) { } void ConsumedStmtVisitor::VisitMaterializeTemporaryExpr( - const MaterializeTemporaryExpr *Temp) { + const MaterializeTemporaryExpr *Temp) { forwardInfo(Temp->getSubExpr(), Temp); } @@ -884,8 +879,8 @@ void ConsumedStmtVisitor::VisitReturnStmt(const ReturnStmt *Ret) { if (RetState != ExpectedState) Analyzer.WarningsHandler.warnReturnTypestateMismatch( - Ret->getReturnLoc(), stateToString(ExpectedState), - stateToString(RetState)); + Ret->getReturnLoc(), stateToString(ExpectedState), + stateToString(RetState)); } } @@ -895,7 +890,8 @@ void ConsumedStmtVisitor::VisitReturnStmt(const ReturnStmt *Ret) { void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) { InfoEntry Entry = findInfo(UOp->getSubExpr()); - if (Entry == PropagationMap.end()) return; + if (Entry == PropagationMap.end()) + return; switch (UOp->getOpcode()) { case UO_AddrOf: @@ -950,8 +946,7 @@ static void splitVarStateForIf(const IfStmt *IfNode, const VarTestResult &Test, static void splitVarStateForIfBinOp(const PropagationInfo &PInfo, ConsumedStateMap *ThenStates, ConsumedStateMap *ElseStates) { - const VarTestResult <est = PInfo.getLTest(), - &RTest = PInfo.getRTest(); + const VarTestResult <est = PInfo.getLTest(), &RTest = PInfo.getRTest(); ConsumedState LState = LTest.Var ? ThenStates->getState(LTest.Var) : CS_None, RState = RTest.Var ? ThenStates->getState(RTest.Var) : CS_None; @@ -1007,8 +1002,9 @@ bool ConsumedBlockInfo::allBackEdgesVisited(const CFGBlock *CurrBlock, unsigned int CurrBlockOrder = VisitOrder[CurrBlock->getBlockID()]; for (CFGBlock::const_pred_iterator PI = TargetBlock->pred_begin(), - PE = TargetBlock->pred_end(); PI != PE; ++PI) { - if (*PI && CurrBlockOrder < VisitOrder[(*PI)->getBlockID()] ) + PE = TargetBlock->pred_end(); + PI != PE; ++PI) { + if (*PI && CurrBlockOrder < VisitOrder[(*PI)->getBlockID()]) return false; } return true; @@ -1042,7 +1038,7 @@ void ConsumedBlockInfo::addInfo(const CFGBlock *Block, } } -ConsumedStateMap* ConsumedBlockInfo::borrowInfo(const CFGBlock *Block) { +ConsumedStateMap *ConsumedBlockInfo::borrowInfo(const CFGBlock *Block) { assert(Block && "Block pointer must not be NULL"); assert(StateMapsArray[Block->getBlockID()] && "Block has no block info"); @@ -1064,7 +1060,7 @@ ConsumedBlockInfo::getInfo(const CFGBlock *Block) { bool ConsumedBlockInfo::isBackEdge(const CFGBlock *From, const CFGBlock *To) { assert(From && "From block must not be NULL"); - assert(To && "From block must not be NULL"); + assert(To && "From block must not be NULL"); return VisitOrder[From->getBlockID()] > VisitOrder[To->getBlockID()]; } @@ -1079,15 +1075,17 @@ bool ConsumedBlockInfo::isBackEdgeTarget(const CFGBlock *Block) { unsigned int BlockVisitOrder = VisitOrder[Block->getBlockID()]; for (CFGBlock::const_pred_iterator PI = Block->pred_begin(), - PE = Block->pred_end(); PI != PE; ++PI) { + PE = Block->pred_end(); + PI != PE; ++PI) { if (*PI && BlockVisitOrder < VisitOrder[(*PI)->getBlockID()]) return true; } return false; } -void ConsumedStateMap::checkParamsForReturnTypestate(SourceLocation BlameLoc, - ConsumedWarningsHandlerBase &WarningsHandler) const { +void ConsumedStateMap::checkParamsForReturnTypestate( + SourceLocation BlameLoc, + ConsumedWarningsHandlerBase &WarningsHandler) const { for (const auto &DM : VarMap) { if (isa(DM.first)) { @@ -1099,16 +1097,14 @@ void ConsumedStateMap::checkParamsForReturnTypestate(SourceLocation BlameLoc, ConsumedState ExpectedState = mapReturnTypestateAttrState(RTA); if (DM.second != ExpectedState) - WarningsHandler.warnParamReturnTypestateMismatch(BlameLoc, - Param->getNameAsString(), stateToString(ExpectedState), - stateToString(DM.second)); + WarningsHandler.warnParamReturnTypestateMismatch( + BlameLoc, Param->getNameAsString(), stateToString(ExpectedState), + stateToString(DM.second)); } } } -void ConsumedStateMap::clearTemporaries() { - TmpMap.clear(); -} +void ConsumedStateMap::clearTemporaries() { TmpMap.clear(); } ConsumedState ConsumedStateMap::getState(const VarDecl *Var) const { VarMapType::const_iterator Entry = VarMap.find(Var); @@ -1144,13 +1140,14 @@ void ConsumedStateMap::intersect(const ConsumedStateMap &Other) { continue; if (LocalState != DM.second) - VarMap[DM.first] = CS_Unknown; + VarMap[DM.first] = CS_Unknown; } } -void ConsumedStateMap::intersectAtLoopHead(const CFGBlock *LoopHead, - const CFGBlock *LoopBack, const ConsumedStateMap *LoopBackStates, - ConsumedWarningsHandlerBase &WarningsHandler) { +void ConsumedStateMap::intersectAtLoopHead( + const CFGBlock *LoopHead, const CFGBlock *LoopBack, + const ConsumedStateMap *LoopBackStates, + ConsumedWarningsHandlerBase &WarningsHandler) { ConsumedState LocalState; SourceLocation BlameLoc = getLastStmtLoc(LoopBack); @@ -1216,12 +1213,11 @@ void ConsumedAnalyzer::determineExpectedReturnState(AnalysisDeclContext &AC, } else ExpectedReturnState = mapReturnTypestateAttrState(RTSAttr); } else if (isConsumableType(ReturnType)) { - if (isAutoCastType(ReturnType)) // We can auto-cast the state to the - ExpectedReturnState = CS_None; // expected state. + if (isAutoCastType(ReturnType)) // We can auto-cast the state to the + ExpectedReturnState = CS_None; // expected state. else ExpectedReturnState = mapConsumableAttrState(ReturnType); - } - else + } else ExpectedReturnState = CS_None; } @@ -1251,8 +1247,8 @@ bool ConsumedAnalyzer::splitState(const CFGBlock *CurrBlock, } else { return false; } - } else if (const auto *BinOp = - dyn_cast_or_null(CurrBlock->getTerminator().getStmt())) { + } else if (const auto *BinOp = dyn_cast_or_null( + CurrBlock->getTerminator().getStmt())) { PInfo = Visitor.getInfo(BinOp->getLHS()); if (!PInfo.isVarTest()) { if ((BinOp = dyn_cast_or_null(BinOp->getLHS()))) { @@ -1384,8 +1380,10 @@ void ConsumedAnalyzer::run(AnalysisDeclContext &AC) { auto *RawState = CurrStates.get(); for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(), - SE = CurrBlock->succ_end(); SI != SE; ++SI) { - if (*SI == nullptr) continue; + SE = CurrBlock->succ_end(); + SI != SE; ++SI) { + if (*SI == nullptr) + continue; if (BlockInfo.isBackEdge(CurrBlock, *SI)) { BlockInfo.borrowInfo(*SI)->intersectAtLoopHead( diff --git a/clang/lib/Analysis/Dominators.cpp b/clang/lib/Analysis/Dominators.cpp index f7ad68673d0f2..6823b7f5876d7 100644 --- a/clang/lib/Analysis/Dominators.cpp +++ b/clang/lib/Analysis/Dominators.cpp @@ -10,10 +10,8 @@ namespace clang { -template <> -void CFGDominatorTreeImpl::anchor() {} +template <> void CFGDominatorTreeImpl::anchor() {} -template <> -void CFGDominatorTreeImpl::anchor() {} +template <> void CFGDominatorTreeImpl::anchor() {} } // end of namespace clang diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp index bb042760d297a..3cf1a456afd10 100644 --- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp +++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp @@ -181,8 +181,12 @@ const auto isMoveOnly = [] { }; template struct NodeID; -template <> struct NodeID { static constexpr StringRef value = "expr"; }; -template <> struct NodeID { static constexpr StringRef value = "decl"; }; +template <> struct NodeID { + static constexpr StringRef value = "expr"; +}; +template <> struct NodeID { + static constexpr StringRef value = "decl"; +}; constexpr StringRef NodeID::value; constexpr StringRef NodeID::value; diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp index f4c4af022f51f..c9a2db8c6ce7e 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -143,8 +143,7 @@ void DataflowAnalysisContext::addFlowConditionConstraint( Atom Token, const Formula &Constraint) { auto Res = FlowConditionConstraints.try_emplace(Token, &Constraint); if (!Res.second) { - Res.first->second = - &arena().makeAnd(*Res.first->second, Constraint); + Res.first->second = &arena().makeAnd(*Res.first->second, Constraint); } } @@ -155,9 +154,8 @@ Atom DataflowAnalysisContext::forkFlowCondition(Atom Token) { return ForkToken; } -Atom -DataflowAnalysisContext::joinFlowConditions(Atom FirstToken, - Atom SecondToken) { +Atom DataflowAnalysisContext::joinFlowConditions(Atom FirstToken, + Atom SecondToken) { Atom Token = arena().makeFlowConditionToken(); FlowConditionDeps[Token].insert(FirstToken); FlowConditionDeps[Token].insert(SecondToken); diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 0cfc26ea952cd..78fce2dc65012 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -446,7 +446,7 @@ void Environment::initFieldsGlobalsAndFuncs(const FunctionDecl *FuncDecl) { // Add all fields mentioned in default member initializers. for (const FieldDecl *F : CtorDecl->getParent()->fields()) if (const auto *I = F->getInClassInitializer()) - getFieldsGlobalsAndFuncs(*I, Fields, Vars, Funcs); + getFieldsGlobalsAndFuncs(*I, Fields, Vars, Funcs); } getFieldsGlobalsAndFuncs(*FuncDecl->getBody(), Fields, Vars, Funcs); @@ -486,8 +486,8 @@ Environment Environment::pushCall(const CallExpr *Call) const { if (const auto *MethodCall = dyn_cast(Call)) { if (const Expr *Arg = MethodCall->getImplicitObjectArgument()) { if (!isa(Arg)) - Env.ThisPointeeLoc = - cast(getStorageLocation(*Arg)); + Env.ThisPointeeLoc = + cast(getStorageLocation(*Arg)); // Otherwise (when the argument is `this`), retain the current // environment's `ThisPointeeLoc`. } @@ -972,7 +972,7 @@ StorageLocation &Environment::createObjectInternal(const ValueDecl *D, // be null. if (InitExpr) { if (auto *InitExprLoc = getStorageLocation(*InitExpr)) - return *InitExprLoc; + return *InitExprLoc; } // Even though we have an initializer, we might not get an @@ -1073,9 +1073,7 @@ void Environment::dump(raw_ostream &OS) const { DACtx->dumpFlowCondition(FlowConditionToken, OS); } -void Environment::dump() const { - dump(llvm::dbgs()); -} +void Environment::dump() const { dump(llvm::dbgs()); } RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE, const Environment &Env) { diff --git a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp index ff4e18de2c70f..83587e1f8b1c2 100644 --- a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp +++ b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp @@ -101,12 +101,12 @@ class ModelDumper { case Value::Kind::FormulaBool: break; case Value::Kind::Pointer: - JOS.attributeObject( - "pointee", [&] { dump(cast(V).getPointeeLoc()); }); + JOS.attributeObject("pointee", + [&] { dump(cast(V).getPointeeLoc()); }); break; } - for (const auto& Prop : V.properties()) + for (const auto &Prop : V.properties()) JOS.attributeObject(("p:" + Prop.first()).str(), [&] { dump(*Prop.second); }); @@ -143,7 +143,7 @@ class ModelDumper { } } - llvm::DenseSet Visited; + llvm::DenseSet Visited; llvm::json::OStream &JOS; const Environment &Env; }; @@ -241,9 +241,7 @@ class HTMLLogger : public Logger { BlockConverged[B.getBlockID()] = false; ElementIndex = 0; } - void enterElement(const CFGElement &E) override { - ++ElementIndex; - } + void enterElement(const CFGElement &E) override { ++ElementIndex; } static std::string blockID(unsigned Block) { return llvm::formatv("B{0}", Block); @@ -421,7 +419,7 @@ class HTMLLogger : public Logger { std::vector State(Code.size()); for (const auto *Block : CFC->getCFG()) { unsigned EltIndex = 0; - for (const auto& Elt : *Block) { + for (const auto &Elt : *Block) { ++EltIndex; if (const auto S = Elt.getAs()) { auto EltRange = clang::Lexer::makeFileCharRange( @@ -458,7 +456,7 @@ class HTMLLogger : public Logger { for (unsigned I = 0; I < Code.size(); ++I) { // Don't actually write a around each character, only break spans // when the TokenInfo changes. - bool NeedOpen = I == 0 || !(State[I] == State[I-1]); + bool NeedOpen = I == 0 || !(State[I] == State[I - 1]); bool NeedClose = I + 1 == Code.size() || !(State[I] == State[I + 1]); if (NeedOpen) { *OS << "\n"; else llvm::printHTMLEscaped(Code.substr(I, 1), *OS); - if (NeedClose) *OS << ""; + if (NeedClose) + *OS << ""; } *OS << "\n"; *OS << ""; diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index cd1f04e53cff6..32367135c76b5 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -689,7 +689,7 @@ class TransferVisitor : public ConstStmtVisitor { size_t InitIdx = 0; // Initialize base classes. - if (auto* R = S->getType()->getAsCXXRecordDecl()) { + if (auto *R = S->getType()->getAsCXXRecordDecl()) { assert(FieldsForInit.size() + R->getNumBases() == Inits.size()); for ([[maybe_unused]] const CXXBaseSpecifier &Base : R->bases()) { assert(InitIdx < Inits.size()); @@ -719,7 +719,7 @@ class TransferVisitor : public ConstStmtVisitor { (Field->getType()->isReferenceType() && Field->getType().getCanonicalType()->getPointeeType() == Init->getType().getCanonicalType())); - auto& Loc = Env.createObject(Field->getType(), Init); + auto &Loc = Env.createObject(Field->getType(), Init); FieldLocs.insert({Field, &Loc}); } diff --git a/clang/lib/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp b/clang/lib/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp index 3ef3637535324..d11048d98b7c2 100644 --- a/clang/lib/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp +++ b/clang/lib/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp @@ -23,9 +23,8 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" - +#include "llvm/ADT/SmallVector.h" namespace clang { namespace dataflow { @@ -191,8 +190,7 @@ struct CNFFormula { /// proper SAT solver. struct CNFFormulaBuilder { // Formula should outlive CNFFormulaBuilder. - explicit CNFFormulaBuilder(CNFFormula &CNF) - : Formula(CNF) {} + explicit CNFFormulaBuilder(CNFFormula &CNF) : Formula(CNF) {} /// Adds the `L1 v ... v Ln` clause to the formula. Applies /// simplifications, based on single-literal clauses. @@ -209,8 +207,7 @@ struct CNFFormulaBuilder { llvm::SmallVector Simplified; for (auto L : Literals) { assert(L != NullLit && - llvm::all_of(Simplified, - [L](Literal S) { return S != L; })); + llvm::all_of(Simplified, [L](Literal S) { return S != L; })); auto X = var(L); if (trueVars.contains(X)) { // X must be true if (isPosLit(L)) diff --git a/clang/lib/Analysis/IssueHash.cpp b/clang/lib/Analysis/IssueHash.cpp index 4d56e774b76aa..e77ad71554cc6 100644 --- a/clang/lib/Analysis/IssueHash.cpp +++ b/clang/lib/Analysis/IssueHash.cpp @@ -134,7 +134,8 @@ static StringRef GetNthLineOfFile(std::optional Buffer, return *LI; } -static std::string NormalizeLine(const SourceManager &SM, const FullSourceLoc &L, +static std::string NormalizeLine(const SourceManager &SM, + const FullSourceLoc &L, const LangOptions &LangOpts) { static StringRef Whitespaces = " \t\n"; @@ -192,8 +193,8 @@ std::string clang::getIssueString(const FullSourceLoc &IssueLoc, return (llvm::Twine(CheckerName) + Delimiter + GetEnclosingDeclContextSignature(IssueDecl) + Delimiter + Twine(IssueLoc.getExpansionColumnNumber()) + Delimiter + - NormalizeLine(IssueLoc.getManager(), IssueLoc, LangOpts) + - Delimiter + WarningMessage) + NormalizeLine(IssueLoc.getManager(), IssueLoc, LangOpts) + Delimiter + + WarningMessage) .str(); } diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp index 6d03dd05ca3d2..4381d6dc9e29b 100644 --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -31,22 +31,23 @@ class LiveVariablesImpl { llvm::ImmutableSet::Factory ESetFact; llvm::ImmutableSet::Factory DSetFact; llvm::ImmutableSet::Factory BSetFact; - llvm::DenseMap blocksEndToLiveness; - llvm::DenseMap blocksBeginToLiveness; + llvm::DenseMap + blocksEndToLiveness; + llvm::DenseMap + blocksBeginToLiveness; llvm::DenseMap stmtsToLiveness; llvm::DenseMap inAssignment; const bool killAtAssign; - LiveVariables::LivenessValues - merge(LiveVariables::LivenessValues valsA, - LiveVariables::LivenessValues valsB); + LiveVariables::LivenessValues merge(LiveVariables::LivenessValues valsA, + LiveVariables::LivenessValues valsB); LiveVariables::LivenessValues runOnBlock(const CFGBlock *block, LiveVariables::LivenessValues val, LiveVariables::Observer *obs = nullptr); - void dumpBlockLiveness(const SourceManager& M); - void dumpExprLiveness(const SourceManager& M); + void dumpBlockLiveness(const SourceManager &M); + void dumpExprLiveness(const SourceManager &M); LiveVariablesImpl(AnalysisDeclContext &ac, bool KillAtAssign) : analysisContext(ac), @@ -56,9 +57,7 @@ class LiveVariablesImpl { }; } // namespace -static LiveVariablesImpl &getImpl(void *x) { - return *((LiveVariablesImpl *) x); -} +static LiveVariablesImpl &getImpl(void *x) { return *((LiveVariablesImpl *)x); } //===----------------------------------------------------------------------===// // Operations and queries on LivenessValues. @@ -84,19 +83,18 @@ bool LiveVariables::LivenessValues::isLive(const VarDecl *D) const { } namespace { - template - SET mergeSets(SET A, SET B) { - if (A.isEmpty()) - return B; +template SET mergeSets(SET A, SET B) { + if (A.isEmpty()) + return B; - for (typename SET::iterator it = B.begin(), ei = B.end(); it != ei; ++it) { - A = A.add(*it); - } - return A; + for (typename SET::iterator it = B.begin(), ei = B.end(); it != ei; ++it) { + A = A.add(*it); } + return A; +} } // namespace -void LiveVariables::Observer::anchor() { } +void LiveVariables::Observer::anchor() {} LiveVariables::LivenessValues LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA, @@ -107,13 +105,15 @@ LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA, SSetRefB(valsB.liveExprs.getRootWithoutRetain(), ESetFact.getTreeFactory()); - llvm::ImmutableSetRef - DSetRefA(valsA.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()), - DSetRefB(valsB.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()); + llvm::ImmutableSetRef DSetRefA( + valsA.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()), + DSetRefB(valsB.liveDecls.getRootWithoutRetain(), + DSetFact.getTreeFactory()); - llvm::ImmutableSetRef - BSetRefA(valsA.liveBindings.getRootWithoutRetain(), BSetFact.getTreeFactory()), - BSetRefB(valsB.liveBindings.getRootWithoutRetain(), BSetFact.getTreeFactory()); + llvm::ImmutableSetRef BSetRefA( + valsA.liveBindings.getRootWithoutRetain(), BSetFact.getTreeFactory()), + BSetRefB(valsB.liveBindings.getRootWithoutRetain(), + BSetFact.getTreeFactory()); SSetRefA = mergeSets(SSetRefA, SSetRefB); DSetRefA = mergeSets(DSetRefA, DSetRefB); @@ -134,9 +134,7 @@ bool LiveVariables::LivenessValues::equals(const LivenessValues &V) const { // Query methods. //===----------------------------------------------------------------------===// -static bool isAlwaysAlive(const VarDecl *D) { - return D->hasGlobalStorage(); -} +static bool isAlwaysAlive(const VarDecl *D) { return D->hasGlobalStorage(); } bool LiveVariables::isLive(const CFGBlock *B, const VarDecl *D) { return isAlwaysAlive(D) || getImpl(impl).blocksEndToLiveness[B].isLive(D); @@ -160,12 +158,12 @@ class TransferFunctions : public StmtVisitor { LiveVariables::LivenessValues &val; LiveVariables::Observer *observer; const CFGBlock *currentBlock; + public: - TransferFunctions(LiveVariablesImpl &im, - LiveVariables::LivenessValues &Val, + TransferFunctions(LiveVariablesImpl &im, LiveVariables::LivenessValues &Val, LiveVariables::Observer *Observer, const CFGBlock *CurrentBlock) - : LV(im), val(Val), observer(Observer), currentBlock(CurrentBlock) {} + : LV(im), val(Val), observer(Observer), currentBlock(CurrentBlock) {} void VisitBinaryOperator(BinaryOperator *BO); void VisitBlockExpr(BlockExpr *BE); @@ -227,93 +225,93 @@ void TransferFunctions::Visit(Stmt *S) { // Mark all children expressions live. switch (S->getStmtClass()) { - default: - break; - case Stmt::StmtExprClass: { - // For statement expressions, look through the compound statement. - S = cast(S)->getSubStmt(); - break; - } - case Stmt::CXXMemberCallExprClass: { - // Include the implicit "this" pointer as being live. - CXXMemberCallExpr *CE = cast(S); - if (Expr *ImplicitObj = CE->getImplicitObjectArgument()) { - AddLiveExpr(val.liveExprs, LV.ESetFact, ImplicitObj); - } - break; - } - case Stmt::ObjCMessageExprClass: { - // In calls to super, include the implicit "self" pointer as being live. - ObjCMessageExpr *CE = cast(S); - if (CE->getReceiverKind() == ObjCMessageExpr::SuperInstance) - val.liveDecls = LV.DSetFact.add(val.liveDecls, - LV.analysisContext.getSelfDecl()); - break; + default: + break; + case Stmt::StmtExprClass: { + // For statement expressions, look through the compound statement. + S = cast(S)->getSubStmt(); + break; + } + case Stmt::CXXMemberCallExprClass: { + // Include the implicit "this" pointer as being live. + CXXMemberCallExpr *CE = cast(S); + if (Expr *ImplicitObj = CE->getImplicitObjectArgument()) { + AddLiveExpr(val.liveExprs, LV.ESetFact, ImplicitObj); } - case Stmt::DeclStmtClass: { - const DeclStmt *DS = cast(S); - if (const VarDecl *VD = dyn_cast(DS->getSingleDecl())) { - for (const VariableArrayType* VA = FindVA(VD->getType()); - VA != nullptr; VA = FindVA(VA->getElementType())) { - AddLiveExpr(val.liveExprs, LV.ESetFact, VA->getSizeExpr()); - } + break; + } + case Stmt::ObjCMessageExprClass: { + // In calls to super, include the implicit "self" pointer as being live. + ObjCMessageExpr *CE = cast(S); + if (CE->getReceiverKind() == ObjCMessageExpr::SuperInstance) + val.liveDecls = + LV.DSetFact.add(val.liveDecls, LV.analysisContext.getSelfDecl()); + break; + } + case Stmt::DeclStmtClass: { + const DeclStmt *DS = cast(S); + if (const VarDecl *VD = dyn_cast(DS->getSingleDecl())) { + for (const VariableArrayType *VA = FindVA(VD->getType()); VA != nullptr; + VA = FindVA(VA->getElementType())) { + AddLiveExpr(val.liveExprs, LV.ESetFact, VA->getSizeExpr()); } - break; - } - case Stmt::PseudoObjectExprClass: { - // A pseudo-object operation only directly consumes its result - // expression. - Expr *child = cast(S)->getResultExpr(); - if (!child) return; - if (OpaqueValueExpr *OV = dyn_cast(child)) - child = OV->getSourceExpr(); - child = child->IgnoreParens(); - val.liveExprs = LV.ESetFact.add(val.liveExprs, child); - return; - } - - // FIXME: These cases eventually shouldn't be needed. - case Stmt::ExprWithCleanupsClass: { - S = cast(S)->getSubExpr(); - break; - } - case Stmt::CXXBindTemporaryExprClass: { - S = cast(S)->getSubExpr(); - break; - } - case Stmt::UnaryExprOrTypeTraitExprClass: { - // No need to unconditionally visit subexpressions. - return; - } - case Stmt::IfStmtClass: { - // If one of the branches is an expression rather than a compound - // statement, it will be bad if we mark it as live at the terminator - // of the if-statement (i.e., immediately after the condition expression). - AddLiveExpr(val.liveExprs, LV.ESetFact, cast(S)->getCond()); - return; - } - case Stmt::WhileStmtClass: { - // If the loop body is an expression rather than a compound statement, - // it will be bad if we mark it as live at the terminator of the loop - // (i.e., immediately after the condition expression). - AddLiveExpr(val.liveExprs, LV.ESetFact, cast(S)->getCond()); - return; } - case Stmt::DoStmtClass: { - // If the loop body is an expression rather than a compound statement, - // it will be bad if we mark it as live at the terminator of the loop - // (i.e., immediately after the condition expression). - AddLiveExpr(val.liveExprs, LV.ESetFact, cast(S)->getCond()); - return; - } - case Stmt::ForStmtClass: { - // If the loop body is an expression rather than a compound statement, - // it will be bad if we mark it as live at the terminator of the loop - // (i.e., immediately after the condition expression). - AddLiveExpr(val.liveExprs, LV.ESetFact, cast(S)->getCond()); + break; + } + case Stmt::PseudoObjectExprClass: { + // A pseudo-object operation only directly consumes its result + // expression. + Expr *child = cast(S)->getResultExpr(); + if (!child) return; - } + if (OpaqueValueExpr *OV = dyn_cast(child)) + child = OV->getSourceExpr(); + child = child->IgnoreParens(); + val.liveExprs = LV.ESetFact.add(val.liveExprs, child); + return; + } + // FIXME: These cases eventually shouldn't be needed. + case Stmt::ExprWithCleanupsClass: { + S = cast(S)->getSubExpr(); + break; + } + case Stmt::CXXBindTemporaryExprClass: { + S = cast(S)->getSubExpr(); + break; + } + case Stmt::UnaryExprOrTypeTraitExprClass: { + // No need to unconditionally visit subexpressions. + return; + } + case Stmt::IfStmtClass: { + // If one of the branches is an expression rather than a compound + // statement, it will be bad if we mark it as live at the terminator + // of the if-statement (i.e., immediately after the condition expression). + AddLiveExpr(val.liveExprs, LV.ESetFact, cast(S)->getCond()); + return; + } + case Stmt::WhileStmtClass: { + // If the loop body is an expression rather than a compound statement, + // it will be bad if we mark it as live at the terminator of the loop + // (i.e., immediately after the condition expression). + AddLiveExpr(val.liveExprs, LV.ESetFact, cast(S)->getCond()); + return; + } + case Stmt::DoStmtClass: { + // If the loop body is an expression rather than a compound statement, + // it will be bad if we mark it as live at the terminator of the loop + // (i.e., immediately after the condition expression). + AddLiveExpr(val.liveExprs, LV.ESetFact, cast(S)->getCond()); + return; + } + case Stmt::ForStmtClass: { + // If the loop body is an expression rather than a compound statement, + // it will be bad if we mark it as live at the terminator of the loop + // (i.e., immediately after the condition expression). + AddLiveExpr(val.liveExprs, LV.ESetFact, cast(S)->getCond()); + return; + } } // HACK + FIXME: What is this? One could only guess that this is an attempt to @@ -326,8 +324,7 @@ void TransferFunctions::Visit(Stmt *S) { } static bool writeShouldKill(const VarDecl *VD) { - return VD && !VD->getType()->isReferenceType() && - !isAlwaysAlive(VD); + return VD && !VD->getType()->isReferenceType() && !isAlwaysAlive(VD); } void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) { @@ -344,10 +341,10 @@ void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) { Expr *LHS = B->getLHS()->IgnoreParens(); if (DeclRefExpr *DR = dyn_cast(LHS)) { - const Decl* D = DR->getDecl(); + const Decl *D = DR->getDecl(); bool Killed = false; - if (const BindingDecl* BD = dyn_cast(D)) { + if (const BindingDecl *BD = dyn_cast(D)) { Killed = !BD->getType()->isReferenceType(); if (Killed) { if (const auto *HV = BD->getHoldingVar()) @@ -359,7 +356,6 @@ void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) { Killed = writeShouldKill(VD); if (Killed) val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD); - } if (Killed && observer) @@ -378,7 +374,7 @@ void TransferFunctions::VisitBlockExpr(BlockExpr *BE) { } void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *DR) { - const Decl* D = DR->getDecl(); + const Decl *D = DR->getDecl(); bool InAssignment = LV.inAssignment[DR]; if (const auto *BD = dyn_cast(D)) { if (!InAssignment) { @@ -421,8 +417,8 @@ void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS) { Stmt *element = OS->getElement(); if (DeclStmt *DS = dyn_cast(element)) { VD = cast(DS->getSingleDecl()); - } - else if ((DR = dyn_cast(cast(element)->IgnoreParens()))) { + } else if ((DR = + dyn_cast(cast(element)->IgnoreParens()))) { VD = cast(DR->getDecl()); } @@ -433,9 +429,8 @@ void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS) { } } -void TransferFunctions:: -VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE) -{ +void TransferFunctions::VisitUnaryExprOrTypeTraitExpr( + UnaryExprOrTypeTraitExpr *UE) { // While sizeof(var) doesn't technically extend the liveness of 'var', it // does extent the liveness of metadata if 'var' is a VariableArrayType. // We handle that special case here. @@ -484,11 +479,12 @@ LiveVariablesImpl::runOnBlock(const CFGBlock *block, // Visit the terminator (if any). if (const Stmt *term = block->getTerminatorStmt()) - TF.Visit(const_cast(term)); + TF.Visit(const_cast(term)); // Apply the transfer function for all Stmts in the block. for (CFGBlock::const_reverse_iterator it = block->rbegin(), - ei = block->rend(); it != ei; ++it) { + ei = block->rend(); + it != ei; ++it) { const CFGElement &elem = *it; if (std::optional Dtor = @@ -501,7 +497,7 @@ LiveVariablesImpl::runOnBlock(const CFGBlock *block, continue; const Stmt *S = elem.castAs().getStmt(); - TF.Visit(const_cast(S)); + TF.Visit(const_cast(S)); stmtsToLiveness[S] = val; } return val; @@ -515,9 +511,7 @@ void LiveVariables::runOnAllBlocks(LiveVariables::Observer &obs) { LiveVariables::LiveVariables(void *im) : impl(im) {} -LiveVariables::~LiveVariables() { - delete (LiveVariablesImpl*) impl; -} +LiveVariables::~LiveVariables() { delete (LiveVariablesImpl *)impl; } std::unique_ptr LiveVariables::computeLiveness(AnalysisDeclContext &AC, bool killAtAssign) { @@ -552,7 +546,8 @@ LiveVariables::computeLiveness(AnalysisDeclContext &AC, bool killAtAssign) { // Merge the values of all successor blocks. LivenessValues val; for (CFGBlock::const_succ_iterator it = block->succ_begin(), - ei = block->succ_end(); it != ei; ++it) { + ei = block->succ_end(); + it != ei; ++it) { if (const CFGBlock *succ = *it) { val = LV->merge(val, LV->blocksBeginToLiveness[succ]); } @@ -582,7 +577,8 @@ void LiveVariables::dumpBlockLiveness(const SourceManager &M) { void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) { std::vector vec; for (llvm::DenseMap::iterator - it = blocksEndToLiveness.begin(), ei = blocksEndToLiveness.end(); + it = blocksEndToLiveness.begin(), + ei = blocksEndToLiveness.end(); it != ei; ++it) { vec.push_back(it->first); } @@ -590,19 +586,20 @@ void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) { return A->getBlockID() < B->getBlockID(); }); - std::vector declVec; + std::vector declVec; - for (std::vector::iterator - it = vec.begin(), ei = vec.end(); it != ei; ++it) { + for (std::vector::iterator it = vec.begin(), ei = vec.end(); + it != ei; ++it) { llvm::errs() << "\n[ B" << (*it)->getBlockID() << " (live variables at block exit) ]\n"; LiveVariables::LivenessValues vals = blocksEndToLiveness[*it]; declVec.clear(); - for (llvm::ImmutableSet::iterator si = - vals.liveDecls.begin(), - se = vals.liveDecls.end(); si != se; ++si) { + for (llvm::ImmutableSet::iterator + si = vals.liveDecls.begin(), + se = vals.liveDecls.end(); + si != se; ++si) { declVec.push_back(*si); } @@ -610,10 +607,10 @@ void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) { return A->getBeginLoc() < B->getBeginLoc(); }); - for (std::vector::iterator di = declVec.begin(), - de = declVec.end(); di != de; ++di) { - llvm::errs() << " " << (*di)->getDeclName().getAsString() - << " <"; + for (std::vector::iterator di = declVec.begin(), + de = declVec.end(); + di != de; ++di) { + llvm::errs() << " " << (*di)->getDeclName().getAsString() << " <"; (*di)->getLocation().print(llvm::errs(), M); llvm::errs() << ">\n"; } @@ -639,5 +636,11 @@ void LiveVariablesImpl::dumpExprLiveness(const SourceManager &M) { } } -const void *LiveVariables::getTag() { static int x; return &x; } -const void *RelaxedLiveVariables::getTag() { static int x; return &x; } +const void *LiveVariables::getTag() { + static int x; + return &x; +} +const void *RelaxedLiveVariables::getTag() { + static int x; + return &x; +} diff --git a/clang/lib/Analysis/MacroExpansionContext.cpp b/clang/lib/Analysis/MacroExpansionContext.cpp index 564e359668a51..a2a26a685fb19 100644 --- a/clang/lib/Analysis/MacroExpansionContext.cpp +++ b/clang/lib/Analysis/MacroExpansionContext.cpp @@ -229,4 +229,3 @@ void MacroExpansionContext::onTokenLexed(const Token &Tok) { if (!Inserted) It->getSecond().append(TokenAsString); } - diff --git a/clang/lib/Analysis/ObjCNoReturn.cpp b/clang/lib/Analysis/ObjCNoReturn.cpp index 9d7c365c3b992..fed2287788512 100644 --- a/clang/lib/Analysis/ObjCNoReturn.cpp +++ b/clang/lib/Analysis/ObjCNoReturn.cpp @@ -11,9 +11,9 @@ // //===----------------------------------------------------------------------===// +#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ExprObjC.h" -#include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" using namespace clang; @@ -26,25 +26,23 @@ static bool isSubclass(const ObjCInterfaceDecl *Class, IdentifierInfo *II) { } ObjCNoReturn::ObjCNoReturn(ASTContext &C) - : RaiseSel(GetNullarySelector("raise", C)), - NSExceptionII(&C.Idents.get("NSException")) -{ + : RaiseSel(GetNullarySelector("raise", C)), + NSExceptionII(&C.Idents.get("NSException")) { // Generate selectors. - SmallVector II; + SmallVector II; // raise:format: II.push_back(&C.Idents.get("raise")); II.push_back(&C.Idents.get("format")); NSExceptionInstanceRaiseSelectors[0] = - C.Selectors.getSelector(II.size(), &II[0]); + C.Selectors.getSelector(II.size(), &II[0]); // raise:format:arguments: II.push_back(&C.Idents.get("arguments")); NSExceptionInstanceRaiseSelectors[1] = - C.Selectors.getSelector(II.size(), &II[0]); + C.Selectors.getSelector(II.size(), &II[0]); } - bool ObjCNoReturn::isImplicitNoReturn(const ObjCMessageExpr *ME) { Selector S = ME->getSelector(); diff --git a/clang/lib/Analysis/PathDiagnostic.cpp b/clang/lib/Analysis/PathDiagnostic.cpp index 79f337a91ec8f..7a64ed8c0db8e 100644 --- a/clang/lib/Analysis/PathDiagnostic.cpp +++ b/clang/lib/Analysis/PathDiagnostic.cpp @@ -52,8 +52,7 @@ using namespace ento; static StringRef StripTrailingDots(StringRef s) { return s.rtrim('.'); } -PathDiagnosticPiece::PathDiagnosticPiece(StringRef s, - Kind k, DisplayHint hint) +PathDiagnosticPiece::PathDiagnosticPiece(StringRef s, Kind k, DisplayHint hint) : str(StripTrailingDots(s)), kind(k), Hint(hint) {} PathDiagnosticPiece::PathDiagnosticPiece(Kind k, DisplayHint hint) @@ -288,19 +287,19 @@ static std::optional comparePiece(const PathDiagnosticPiece &X, } switch (X.getKind()) { - case PathDiagnosticPiece::ControlFlow: - return compareControlFlow(cast(X), - cast(Y)); - case PathDiagnosticPiece::Macro: - return compareMacro(cast(X), - cast(Y)); - case PathDiagnosticPiece::Call: - return compareCall(cast(X), - cast(Y)); - case PathDiagnosticPiece::Event: - case PathDiagnosticPiece::Note: - case PathDiagnosticPiece::PopUp: - return std::nullopt; + case PathDiagnosticPiece::ControlFlow: + return compareControlFlow(cast(X), + cast(Y)); + case PathDiagnosticPiece::Macro: + return compareMacro(cast(X), + cast(Y)); + case PathDiagnosticPiece::Call: + return compareCall(cast(X), + cast(Y)); + case PathDiagnosticPiece::Event: + case PathDiagnosticPiece::Note: + case PathDiagnosticPiece::PopUp: + return std::nullopt; } llvm_unreachable("all cases handled"); } @@ -388,7 +387,7 @@ static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y) { PathDiagnostic::meta_iterator YI = Y.meta_begin(), YE = Y.meta_end(); if (XE - XI != YE - YI) return (XE - XI) < (YE - YI); - for ( ; XI != XE ; ++XI, ++YI) { + for (; XI != XE; ++XI, ++YI) { if (*XI != *YI) return (*XI) < (*YI); } @@ -396,7 +395,7 @@ static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y) { } void PathDiagnosticConsumer::FlushDiagnostics( - PathDiagnosticConsumer::FilesMade *Files) { + PathDiagnosticConsumer::FilesMade *Files) { if (flushed) return; @@ -447,12 +446,11 @@ void PathDiagnosticConsumer::FilesMade::addDiagnostic(const PathDiagnostic &PD, } // Allocate persistent storage for the file name. - char *FileName_cstr = (char*) Alloc.Allocate(FileName.size(), 1); + char *FileName_cstr = (char *)Alloc.Allocate(FileName.size(), 1); memcpy(FileName_cstr, FileName.data(), FileName.size()); - Entry->files.push_back(std::make_pair(ConsumerName, - StringRef(FileName_cstr, - FileName.size()))); + Entry->files.push_back( + std::make_pair(ConsumerName, StringRef(FileName_cstr, FileName.size()))); } PathDiagnosticConsumer::PDFileEntry::ConsumerFiles * @@ -481,10 +479,10 @@ SourceLocation PathDiagnosticLocation::getValidSourceLocation( // source code, so find an enclosing statement and use its location. if (!L.isValid()) { AnalysisDeclContext *ADC; - if (LAC.is()) - ADC = LAC.get()->getAnalysisDeclContext(); + if (LAC.is()) + ADC = LAC.get()->getAnalysisDeclContext(); else - ADC = LAC.get(); + ADC = LAC.get(); ParentMap &PM = ADC->getParentMap(); @@ -510,7 +508,7 @@ SourceLocation PathDiagnosticLocation::getValidSourceLocation( } // FIXME: Ironically, this assert actually fails in some cases. - //assert(L.isValid()); + // assert(L.isValid()); return L; } @@ -525,17 +523,17 @@ getLocationForCaller(const StackFrameContext *SFC, case CFGElement::Statement: case CFGElement::Constructor: case CFGElement::CXXRecordTypedCall: - return PathDiagnosticLocation(Source.castAs().getStmt(), - SM, CallerCtx); + return PathDiagnosticLocation(Source.castAs().getStmt(), SM, + CallerCtx); case CFGElement::Initializer: { const CFGInitializer &Init = Source.castAs(); - return PathDiagnosticLocation(Init.getInitializer()->getInit(), - SM, CallerCtx); + return PathDiagnosticLocation(Init.getInitializer()->getInit(), SM, + CallerCtx); } case CFGElement::AutomaticObjectDtor: { const CFGAutomaticObjDtor &Dtor = Source.castAs(); - return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(), - SM, CallerCtx); + return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(), SM, + CallerCtx); } case CFGElement::DeleteDtor: { const CFGDeleteDtor &Dtor = Source.castAs(); @@ -573,23 +571,19 @@ getLocationForCaller(const StackFrameContext *SFC, } PathDiagnosticLocation -PathDiagnosticLocation::createBegin(const Decl *D, - const SourceManager &SM) { +PathDiagnosticLocation::createBegin(const Decl *D, const SourceManager &SM) { return PathDiagnosticLocation(D->getBeginLoc(), SM, SingleLocK); } PathDiagnosticLocation -PathDiagnosticLocation::createBegin(const Stmt *S, - const SourceManager &SM, +PathDiagnosticLocation::createBegin(const Stmt *S, const SourceManager &SM, LocationOrAnalysisDeclContext LAC) { assert(S && "Statement cannot be null"); - return PathDiagnosticLocation(getValidSourceLocation(S, LAC), - SM, SingleLocK); + return PathDiagnosticLocation(getValidSourceLocation(S, LAC), SM, SingleLocK); } PathDiagnosticLocation -PathDiagnosticLocation::createEnd(const Stmt *S, - const SourceManager &SM, +PathDiagnosticLocation::createEnd(const Stmt *S, const SourceManager &SM, LocationOrAnalysisDeclContext LAC) { if (const auto *CS = dyn_cast(S)) return createEndBrace(CS, SM); @@ -604,9 +598,8 @@ PathDiagnosticLocation::createOperatorLoc(const BinaryOperator *BO, } PathDiagnosticLocation -PathDiagnosticLocation::createConditionalColonLoc( - const ConditionalOperator *CO, - const SourceManager &SM) { +PathDiagnosticLocation::createConditionalColonLoc(const ConditionalOperator *CO, + const SourceManager &SM) { return PathDiagnosticLocation(CO->getColonLoc(), SM, SingleLocK); } @@ -659,9 +652,9 @@ PathDiagnosticLocation::createDeclEnd(const LocationContext *LC, } PathDiagnosticLocation -PathDiagnosticLocation::create(const ProgramPoint& P, +PathDiagnosticLocation::create(const ProgramPoint &P, const SourceManager &SMng) { - const Stmt* S = nullptr; + const Stmt *S = nullptr; if (std::optional BE = P.getAs()) { const CFGBlock *BSrc = BE->getSrc(); if (BSrc->getTerminator().isVirtualBaseBranch()) { @@ -676,7 +669,8 @@ PathDiagnosticLocation::create(const ProgramPoint& P, // If the BlockEdge has no terminator condition statement but its // source is the entry of the CFG (e.g. a checker crated the branch at // the beginning of a function), use the function's declaration instead. - assert(BSrc == &BSrc->getParent()->getEntry() && "CFGBlock has no " + assert(BSrc == &BSrc->getParent()->getEntry() && + "CFGBlock has no " "TerminatorCondition and is not the enrty block of the CFG"); return PathDiagnosticLocation::createBegin( P.getLocationContext()->getDecl(), SMng); @@ -696,12 +690,10 @@ PathDiagnosticLocation::create(const ProgramPoint& P, return PathDiagnosticLocation(PIE->getLocation(), SMng); } else if (std::optional CE = P.getAs()) { return getLocationForCaller(CE->getCalleeContext(), - CE->getLocationContext(), - SMng); + CE->getLocationContext(), SMng); } else if (std::optional CEE = P.getAs()) { return getLocationForCaller(CEE->getCalleeContext(), - CEE->getLocationContext(), - SMng); + CEE->getLocationContext(), SMng); } else if (auto CEB = P.getAs()) { if (const ReturnStmt *RS = CEB->getReturnStmt()) return PathDiagnosticLocation::createBegin(RS, SMng, @@ -733,93 +725,92 @@ PathDiagnosticLocation::create(const ProgramPoint& P, } PathDiagnosticLocation PathDiagnosticLocation::createSingleLocation( - const PathDiagnosticLocation &PDL) { + const PathDiagnosticLocation &PDL) { FullSourceLoc L = PDL.asLocation(); return PathDiagnosticLocation(L, L.getManager(), SingleLocK); } FullSourceLoc - PathDiagnosticLocation::genLocation(SourceLocation L, - LocationOrAnalysisDeclContext LAC) const { +PathDiagnosticLocation::genLocation(SourceLocation L, + LocationOrAnalysisDeclContext LAC) const { assert(isValid()); // Note that we want a 'switch' here so that the compiler can warn us in // case we add more cases. switch (K) { - case SingleLocK: - case RangeK: + case SingleLocK: + case RangeK: + break; + case StmtK: + // Defensive checking. + if (!S) break; - case StmtK: - // Defensive checking. - if (!S) - break; - return FullSourceLoc(getValidSourceLocation(S, LAC), - const_cast(*SM)); - case DeclK: - // Defensive checking. - if (!D) - break; - return FullSourceLoc(D->getLocation(), const_cast(*SM)); + return FullSourceLoc(getValidSourceLocation(S, LAC), + const_cast(*SM)); + case DeclK: + // Defensive checking. + if (!D) + break; + return FullSourceLoc(D->getLocation(), const_cast(*SM)); } - return FullSourceLoc(L, const_cast(*SM)); + return FullSourceLoc(L, const_cast(*SM)); } PathDiagnosticRange - PathDiagnosticLocation::genRange(LocationOrAnalysisDeclContext LAC) const { +PathDiagnosticLocation::genRange(LocationOrAnalysisDeclContext LAC) const { assert(isValid()); // Note that we want a 'switch' here so that the compiler can warn us in // case we add more cases. switch (K) { - case SingleLocK: - return PathDiagnosticRange(SourceRange(Loc,Loc), true); - case RangeK: + case SingleLocK: + return PathDiagnosticRange(SourceRange(Loc, Loc), true); + case RangeK: + break; + case StmtK: { + const Stmt *S = asStmt(); + switch (S->getStmtClass()) { + default: break; - case StmtK: { - const Stmt *S = asStmt(); - switch (S->getStmtClass()) { - default: - break; - case Stmt::DeclStmtClass: { - const auto *DS = cast(S); - if (DS->isSingleDecl()) { - // Should always be the case, but we'll be defensive. - return SourceRange(DS->getBeginLoc(), - DS->getSingleDecl()->getLocation()); - } - break; - } - // FIXME: Provide better range information for different - // terminators. - case Stmt::IfStmtClass: - case Stmt::WhileStmtClass: - case Stmt::DoStmtClass: - case Stmt::ForStmtClass: - case Stmt::ChooseExprClass: - case Stmt::IndirectGotoStmtClass: - case Stmt::SwitchStmtClass: - case Stmt::BinaryConditionalOperatorClass: - case Stmt::ConditionalOperatorClass: - case Stmt::ObjCForCollectionStmtClass: { - SourceLocation L = getValidSourceLocation(S, LAC); - return SourceRange(L, L); - } + case Stmt::DeclStmtClass: { + const auto *DS = cast(S); + if (DS->isSingleDecl()) { + // Should always be the case, but we'll be defensive. + return SourceRange(DS->getBeginLoc(), + DS->getSingleDecl()->getLocation()); } - SourceRange R = S->getSourceRange(); - if (R.isValid()) - return R; break; } - case DeclK: - if (const auto *MD = dyn_cast(D)) - return MD->getSourceRange(); - if (const auto *FD = dyn_cast(D)) { - if (Stmt *Body = FD->getBody()) - return Body->getSourceRange(); - } - else { - SourceLocation L = D->getLocation(); - return PathDiagnosticRange(SourceRange(L, L), true); - } + // FIXME: Provide better range information for different + // terminators. + case Stmt::IfStmtClass: + case Stmt::WhileStmtClass: + case Stmt::DoStmtClass: + case Stmt::ForStmtClass: + case Stmt::ChooseExprClass: + case Stmt::IndirectGotoStmtClass: + case Stmt::SwitchStmtClass: + case Stmt::BinaryConditionalOperatorClass: + case Stmt::ConditionalOperatorClass: + case Stmt::ObjCForCollectionStmtClass: { + SourceLocation L = getValidSourceLocation(S, LAC); + return SourceRange(L, L); + } + } + SourceRange R = S->getSourceRange(); + if (R.isValid()) + return R; + break; + } + case DeclK: + if (const auto *MD = dyn_cast(D)) + return MD->getSourceRange(); + if (const auto *FD = dyn_cast(D)) { + if (Stmt *Body = FD->getBody()) + return Body->getSourceRange(); + } else { + SourceLocation L = D->getLocation(); + return PathDiagnosticRange(SourceRange(L, L), true); + } } return SourceRange(Loc, Loc); @@ -830,8 +821,7 @@ void PathDiagnosticLocation::flatten() { K = RangeK; S = nullptr; D = nullptr; - } - else if (K == DeclK) { + } else if (K == DeclK) { K = SingleLocK; S = nullptr; D = nullptr; @@ -846,16 +836,14 @@ std::shared_ptr PathDiagnosticCallPiece::construct(const CallExitEnd &CE, const SourceManager &SM) { const Decl *caller = CE.getLocationContext()->getDecl(); - PathDiagnosticLocation pos = getLocationForCaller(CE.getCalleeContext(), - CE.getLocationContext(), - SM); + PathDiagnosticLocation pos = + getLocationForCaller(CE.getCalleeContext(), CE.getLocationContext(), SM); return std::shared_ptr( new PathDiagnosticCallPiece(caller, pos)); } PathDiagnosticCallPiece * -PathDiagnosticCallPiece::construct(PathPieces &path, - const Decl *caller) { +PathDiagnosticCallPiece::construct(PathPieces &path, const Decl *caller) { std::shared_ptr C( new PathDiagnosticCallPiece(path, caller)); path.clear(); @@ -879,9 +867,9 @@ void PathDiagnosticCallPiece::setCallee(const CallEnter &CE, // Unless set here, the IsCalleeAnAutosynthesizedPropertyAccessor flag // defaults to false. if (const auto *MD = dyn_cast(Callee)) - IsCalleeAnAutosynthesizedPropertyAccessor = ( - MD->isPropertyAccessor() && - CalleeCtx->getAnalysisDeclContext()->isBodyAutosynthesized()); + IsCalleeAnAutosynthesizedPropertyAccessor = + (MD->isPropertyAccessor() && + CalleeCtx->getAnalysisDeclContext()->isBodyAutosynthesized()); } static void describeTemplateParameters(raw_ostream &Out, @@ -903,8 +891,8 @@ static void describeTemplateParameter(raw_ostream &Out, static void describeTemplateParameters(raw_ostream &Out, const ArrayRef TAList, - const LangOptions &LO, - StringRef Prefix, StringRef Postfix) { + const LangOptions &LO, StringRef Prefix, + StringRef Postfix) { if (TAList.empty()) return; @@ -969,11 +957,11 @@ static bool describeCodeDecl(raw_ostream &Out, const Decl *D, Out << "'" << *MD << "'"; } } else if (MD->isCopyAssignmentOperator()) { - Out << "copy assignment operator"; - describeClass(Out, MD->getParent(), " for "); + Out << "copy assignment operator"; + describeClass(Out, MD->getParent(), " for "); } else if (MD->isMoveAssignmentOperator()) { - Out << "move assignment operator"; - describeClass(Out, MD->getParent(), " for "); + Out << "move assignment operator"; + describeClass(Out, MD->getParent(), " for "); } else { if (MD->getParent()->getIdentifier()) Out << "'" << *MD->getParent() << "::" << *MD << "'"; @@ -989,7 +977,7 @@ static bool describeCodeDecl(raw_ostream &Out, const Decl *D, // Adding template parameters. if (const auto FD = dyn_cast(D)) if (const TemplateArgumentList *TAList = - FD->getTemplateSpecializationArgs()) + FD->getTemplateSpecializationArgs()) describeTemplateParameters(Out, TAList->asArray(), FD->getLangOpts(), "<", ">"); @@ -1050,9 +1038,9 @@ PathDiagnosticCallPiece::getCallExitEvent() const { if (!CallStackMessage.empty()) { Out << CallStackMessage; } else { - bool DidDescribe = describeCodeDecl(Out, Callee, - /*ExtendedDescription=*/false, - "Returning from "); + bool DidDescribe = + describeCodeDecl(Out, Callee, + /*ExtendedDescription=*/false, "Returning from "); if (!DidDescribe) Out << "Returning to caller"; } @@ -1088,10 +1076,10 @@ void PathDiagnosticLocation::Profile(llvm::FoldingSetNodeID &ID) const { } void PathDiagnosticPiece::Profile(llvm::FoldingSetNodeID &ID) const { - ID.AddInteger((unsigned) getKind()); + ID.AddInteger((unsigned)getKind()); ID.AddString(str); // FIXME: Add profiling support for code hints. - ID.AddInteger((unsigned) getDisplayHint()); + ID.AddInteger((unsigned)getDisplayHint()); ArrayRef Ranges = getRanges(); for (const auto &I : Ranges) { ID.Add(I.getBegin()); diff --git a/clang/lib/Analysis/PostOrderCFGView.cpp b/clang/lib/Analysis/PostOrderCFGView.cpp index 0c09c0f97ff68..6ba64ed99bfce 100644 --- a/clang/lib/Analysis/PostOrderCFGView.cpp +++ b/clang/lib/Analysis/PostOrderCFGView.cpp @@ -23,7 +23,8 @@ PostOrderCFGView::PostOrderCFGView(const CFG *cfg) { CFGBlockSet BSet(cfg); for (po_iterator I = po_iterator::begin(cfg, BSet), - E = po_iterator::end(cfg, BSet); I != E; ++I) { + E = po_iterator::end(cfg, BSet); + I != E; ++I) { BlockOrder[*I] = Blocks.size() + 1; Blocks.push_back(*I); } @@ -37,7 +38,10 @@ PostOrderCFGView::create(AnalysisDeclContext &ctx) { return std::make_unique(cfg); } -const void *PostOrderCFGView::getTag() { static int x; return &x; } +const void *PostOrderCFGView::getTag() { + static int x; + return &x; +} bool PostOrderCFGView::BlockOrderCompare::operator()(const CFGBlock *b1, const CFGBlock *b2) const { diff --git a/clang/lib/Analysis/ProgramPoint.cpp b/clang/lib/Analysis/ProgramPoint.cpp index 2a91749affd2a..1404f1d401e52 100644 --- a/clang/lib/Analysis/ProgramPoint.cpp +++ b/clang/lib/Analysis/ProgramPoint.cpp @@ -21,26 +21,26 @@ ProgramPointTag::~ProgramPointTag() {} ProgramPoint ProgramPoint::getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const LocationContext *LC, - const ProgramPointTag *tag){ + const ProgramPointTag *tag) { switch (K) { - default: - llvm_unreachable("Unhandled ProgramPoint kind"); - case ProgramPoint::PreStmtKind: - return PreStmt(S, LC, tag); - case ProgramPoint::PostStmtKind: - return PostStmt(S, LC, tag); - case ProgramPoint::PreLoadKind: - return PreLoad(S, LC, tag); - case ProgramPoint::PostLoadKind: - return PostLoad(S, LC, tag); - case ProgramPoint::PreStoreKind: - return PreStore(S, LC, tag); - case ProgramPoint::PostLValueKind: - return PostLValue(S, LC, tag); - case ProgramPoint::PostStmtPurgeDeadSymbolsKind: - return PostStmtPurgeDeadSymbols(S, LC, tag); - case ProgramPoint::PreStmtPurgeDeadSymbolsKind: - return PreStmtPurgeDeadSymbols(S, LC, tag); + default: + llvm_unreachable("Unhandled ProgramPoint kind"); + case ProgramPoint::PreStmtKind: + return PreStmt(S, LC, tag); + case ProgramPoint::PostStmtKind: + return PostStmt(S, LC, tag); + case ProgramPoint::PreLoadKind: + return PreLoad(S, LC, tag); + case ProgramPoint::PostLoadKind: + return PostLoad(S, LC, tag); + case ProgramPoint::PreStoreKind: + return PreStore(S, LC, tag); + case ProgramPoint::PostLValueKind: + return PostLValue(S, LC, tag); + case ProgramPoint::PostStmtPurgeDeadSymbolsKind: + return PostStmtPurgeDeadSymbols(S, LC, tag); + case ProgramPoint::PreStmtPurgeDeadSymbolsKind: + return PreStmtPurgeDeadSymbols(S, LC, tag); } } @@ -58,8 +58,7 @@ void ProgramPoint::printJson(llvm::raw_ostream &Out, const char *NL) const { Out << "\"kind\": \""; switch (getKind()) { case ProgramPoint::BlockEntranceKind: - Out << "BlockEntrance\"" - << ", \"block_id\": " + Out << "BlockEntrance\"" << ", \"block_id\": " << castAs().getBlock()->getBlockID(); break; @@ -157,7 +156,7 @@ void ProgramPoint::printJson(llvm::raw_ostream &Out, const char *NL) const { LHS->printJson(Out, nullptr, PP, AddQuotes); } else { Out << "null"; - } + } Out << ", \"rhs\": "; if (const Stmt *RHS = C->getRHS()) { @@ -188,8 +187,8 @@ void ProgramPoint::printJson(llvm::raw_ostream &Out, const char *NL) const { assert(S != nullptr && "Expecting non-null Stmt"); Out << "Statement\", \"stmt_kind\": \"" << S->getStmtClassName() - << "\", \"stmt_id\": " << S->getID(Context) - << ", \"pointer\": \"" << (const void *)S << "\", "; + << "\", \"stmt_id\": " << S->getID(Context) << ", \"pointer\": \"" + << (const void *)S << "\", "; if (const auto *CS = dyn_cast(S)) Out << "\"cast_kind\": \"" << CS->getCastKindName() << "\", "; @@ -236,8 +235,6 @@ void ProgramPoint::printJson(llvm::raw_ostream &Out, const char *NL) const { SimpleProgramPointTag::SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg) - : Desc((MsgProvider + " : " + Msg).str()) {} + : Desc((MsgProvider + " : " + Msg).str()) {} -StringRef SimpleProgramPointTag::getTagDescription() const { - return Desc; -} +StringRef SimpleProgramPointTag::getTagDescription() const { return Desc; } diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp index acbe1470b3899..3c7f112258946 100644 --- a/clang/lib/Analysis/ReachableCode.cpp +++ b/clang/lib/Analysis/ReachableCode.cpp @@ -45,8 +45,7 @@ static bool isTrivialExpression(const Expr *Ex) { Ex = Ex->IgnoreParenCasts(); return isa(Ex) || isa(Ex) || isa(Ex) || isa(Ex) || - isa(Ex) || - isEnumConstant(Ex); + isa(Ex) || isEnumConstant(Ex); } static bool isTrivialDoWhile(const CFGBlock *B, const Stmt *S) { @@ -71,7 +70,7 @@ static bool isBuiltinUnreachable(const Stmt *S) { static bool isBuiltinAssumeFalse(const CFGBlock *B, const Stmt *S, ASTContext &C) { - if (B->empty()) { + if (B->empty()) { // Happens if S is B's terminator and B contains nothing else // (e.g. a CFGBlock containing only a goto). return false; @@ -147,8 +146,7 @@ static SourceLocation getTopMostMacro(SourceLocation Loc, SourceManager &SM) { } /// Returns true if the statement is expanded from a configuration macro. -static bool isExpandedFromConfigurationMacro(const Stmt *S, - Preprocessor &PP, +static bool isExpandedFromConfigurationMacro(const Stmt *S, Preprocessor &PP, bool IgnoreYES_NO = false) { // FIXME: This is not very precise. Here we just check to see if the // value comes from a macro, but we can do much better. This is likely @@ -186,8 +184,7 @@ static bool isConfigurationValue(const ValueDecl *D, Preprocessor &PP); /// "sometimes unreachable" code. Such code is usually not interesting /// to report as unreachable, and may mask truly unreachable code within /// those blocks. -static bool isConfigurationValue(const Stmt *S, - Preprocessor &PP, +static bool isConfigurationValue(const Stmt *S, Preprocessor &PP, SourceRange *SilenceableCondVal = nullptr, bool IncludeIntegers = true, bool WrappedInParens = false) { @@ -212,62 +209,61 @@ static bool isConfigurationValue(const Stmt *S, bool IgnoreYES_NO = false; switch (S->getStmtClass()) { - case Stmt::CallExprClass: { - const FunctionDecl *Callee = + case Stmt::CallExprClass: { + const FunctionDecl *Callee = dyn_cast_or_null(cast(S)->getCalleeDecl()); - return Callee ? Callee->isConstexpr() : false; - } - case Stmt::DeclRefExprClass: - return isConfigurationValue(cast(S)->getDecl(), PP); - case Stmt::ObjCBoolLiteralExprClass: - IgnoreYES_NO = true; - [[fallthrough]]; - case Stmt::CXXBoolLiteralExprClass: - case Stmt::IntegerLiteralClass: { - const Expr *E = cast(S); - if (IncludeIntegers) { - if (SilenceableCondVal && !SilenceableCondVal->getBegin().isValid()) - *SilenceableCondVal = E->getSourceRange(); - return WrappedInParens || - isExpandedFromConfigurationMacro(E, PP, IgnoreYES_NO); - } - return false; - } - case Stmt::MemberExprClass: - return isConfigurationValue(cast(S)->getMemberDecl(), PP); - case Stmt::UnaryExprOrTypeTraitExprClass: - return true; - case Stmt::BinaryOperatorClass: { - const BinaryOperator *B = cast(S); - // Only include raw integers (not enums) as configuration - // values if they are used in a logical or comparison operator - // (not arithmetic). - IncludeIntegers &= (B->isLogicalOp() || B->isComparisonOp()); - return isConfigurationValue(B->getLHS(), PP, SilenceableCondVal, - IncludeIntegers) || - isConfigurationValue(B->getRHS(), PP, SilenceableCondVal, - IncludeIntegers); - } - case Stmt::UnaryOperatorClass: { - const UnaryOperator *UO = cast(S); - if (UO->getOpcode() != UO_LNot && UO->getOpcode() != UO_Minus) - return false; - bool SilenceableCondValNotSet = - SilenceableCondVal && SilenceableCondVal->getBegin().isInvalid(); - bool IsSubExprConfigValue = - isConfigurationValue(UO->getSubExpr(), PP, SilenceableCondVal, - IncludeIntegers, WrappedInParens); - // Update the silenceable condition value source range only if the range - // was set directly by the child expression. - if (SilenceableCondValNotSet && - SilenceableCondVal->getBegin().isValid() && - *SilenceableCondVal == - UO->getSubExpr()->IgnoreCasts()->getSourceRange()) - *SilenceableCondVal = UO->getSourceRange(); - return IsSubExprConfigValue; + return Callee ? Callee->isConstexpr() : false; + } + case Stmt::DeclRefExprClass: + return isConfigurationValue(cast(S)->getDecl(), PP); + case Stmt::ObjCBoolLiteralExprClass: + IgnoreYES_NO = true; + [[fallthrough]]; + case Stmt::CXXBoolLiteralExprClass: + case Stmt::IntegerLiteralClass: { + const Expr *E = cast(S); + if (IncludeIntegers) { + if (SilenceableCondVal && !SilenceableCondVal->getBegin().isValid()) + *SilenceableCondVal = E->getSourceRange(); + return WrappedInParens || + isExpandedFromConfigurationMacro(E, PP, IgnoreYES_NO); } - default: + return false; + } + case Stmt::MemberExprClass: + return isConfigurationValue(cast(S)->getMemberDecl(), PP); + case Stmt::UnaryExprOrTypeTraitExprClass: + return true; + case Stmt::BinaryOperatorClass: { + const BinaryOperator *B = cast(S); + // Only include raw integers (not enums) as configuration + // values if they are used in a logical or comparison operator + // (not arithmetic). + IncludeIntegers &= (B->isLogicalOp() || B->isComparisonOp()); + return isConfigurationValue(B->getLHS(), PP, SilenceableCondVal, + IncludeIntegers) || + isConfigurationValue(B->getRHS(), PP, SilenceableCondVal, + IncludeIntegers); + } + case Stmt::UnaryOperatorClass: { + const UnaryOperator *UO = cast(S); + if (UO->getOpcode() != UO_LNot && UO->getOpcode() != UO_Minus) return false; + bool SilenceableCondValNotSet = + SilenceableCondVal && SilenceableCondVal->getBegin().isInvalid(); + bool IsSubExprConfigValue = + isConfigurationValue(UO->getSubExpr(), PP, SilenceableCondVal, + IncludeIntegers, WrappedInParens); + // Update the silenceable condition value source range only if the range + // was set directly by the child expression. + if (SilenceableCondValNotSet && SilenceableCondVal->getBegin().isValid() && + *SilenceableCondVal == + UO->getSubExpr()->IgnoreCasts()->getSourceRange()) + *SilenceableCondVal = UO->getSourceRange(); + return IsSubExprConfigValue; + } + default: + return false; } } @@ -314,14 +310,13 @@ static bool shouldTreatSuccessorsAsReachable(const CFGBlock *B, return isConfigurationValue(Cond, PP); } -static unsigned scanFromBlock(const CFGBlock *Start, - llvm::BitVector &Reachable, +static unsigned scanFromBlock(const CFGBlock *Start, llvm::BitVector &Reachable, Preprocessor *PP, bool IncludeSometimesUnreachableEdges) { unsigned count = 0; // Prep work queue - SmallVector WL; + SmallVector WL; // The entry block may have already been marked reachable // by the caller. @@ -347,25 +342,26 @@ static unsigned scanFromBlock(const CFGBlock *Start, TreatAllSuccessorsAsReachable = false; for (CFGBlock::const_succ_iterator I = item->succ_begin(), - E = item->succ_end(); I != E; ++I) { + E = item->succ_end(); + I != E; ++I) { const CFGBlock *B = *I; - if (!B) do { - const CFGBlock *UB = I->getPossiblyUnreachableBlock(); - if (!UB) - break; - - if (!TreatAllSuccessorsAsReachable) { - assert(PP); - TreatAllSuccessorsAsReachable = - shouldTreatSuccessorsAsReachable(item, *PP); - } + if (!B) + do { + const CFGBlock *UB = I->getPossiblyUnreachableBlock(); + if (!UB) + break; + + if (!TreatAllSuccessorsAsReachable) { + assert(PP); + TreatAllSuccessorsAsReachable = + shouldTreatSuccessorsAsReachable(item, *PP); + } - if (*TreatAllSuccessorsAsReachable) { - B = UB; - break; - } - } - while (false); + if (*TreatAllSuccessorsAsReachable) { + B = UB; + break; + } + } while (false); if (B) { unsigned blockID = B->getBlockID(); @@ -391,37 +387,34 @@ static unsigned scanMaybeReachableFromBlock(const CFGBlock *Start, //===----------------------------------------------------------------------===// namespace { - class DeadCodeScan { - llvm::BitVector Visited; - llvm::BitVector &Reachable; - SmallVector WorkList; - Preprocessor &PP; - ASTContext &C; +class DeadCodeScan { + llvm::BitVector Visited; + llvm::BitVector &Reachable; + SmallVector WorkList; + Preprocessor &PP; + ASTContext &C; - typedef SmallVector, 12> - DeferredLocsTy; + typedef SmallVector, 12> + DeferredLocsTy; - DeferredLocsTy DeferredLocs; + DeferredLocsTy DeferredLocs; - public: - DeadCodeScan(llvm::BitVector &reachable, Preprocessor &PP, ASTContext &C) - : Visited(reachable.size()), - Reachable(reachable), - PP(PP), C(C) {} +public: + DeadCodeScan(llvm::BitVector &reachable, Preprocessor &PP, ASTContext &C) + : Visited(reachable.size()), Reachable(reachable), PP(PP), C(C) {} - void enqueue(const CFGBlock *block); - unsigned scanBackwards(const CFGBlock *Start, - clang::reachable_code::Callback &CB); + void enqueue(const CFGBlock *block); + unsigned scanBackwards(const CFGBlock *Start, + clang::reachable_code::Callback &CB); - bool isDeadCodeRoot(const CFGBlock *Block); + bool isDeadCodeRoot(const CFGBlock *Block); - const Stmt *findDeadCode(const CFGBlock *Block); + const Stmt *findDeadCode(const CFGBlock *Block); - void reportDeadCode(const CFGBlock *B, - const Stmt *S, - clang::reachable_code::Callback &CB); - }; -} + void reportDeadCode(const CFGBlock *B, const Stmt *S, + clang::reachable_code::Callback &CB); +}; +} // namespace void DeadCodeScan::enqueue(const CFGBlock *block) { unsigned blockID = block->getBlockID(); @@ -435,7 +428,8 @@ bool DeadCodeScan::isDeadCodeRoot(const clang::CFGBlock *Block) { bool isDeadRoot = true; for (CFGBlock::const_pred_iterator I = Block->pred_begin(), - E = Block->pred_end(); I != E; ++I) { + E = Block->pred_end(); + I != E; ++I) { if (const CFGBlock *PredBlock = *I) { unsigned blockID = PredBlock->getBlockID(); if (Visited[blockID]) { @@ -505,7 +499,8 @@ static bool isValidDeadStmt(const Stmt *S, const clang::CFGBlock *Block) { } const Stmt *DeadCodeScan::findDeadCode(const clang::CFGBlock *Block) { - for (CFGBlock::const_iterator I = Block->begin(), E = Block->end(); I!=E; ++I) + for (CFGBlock::const_iterator I = Block->begin(), E = Block->end(); I != E; + ++I) if (std::optional CS = I->getAs()) { const Stmt *S = CS->getStmt(); if (isValidDeadStmt(S, Block)) @@ -551,7 +546,8 @@ unsigned DeadCodeScan::scanBackwards(const clang::CFGBlock *Start, if (!S) { // No dead code. Possibly an empty block. Look at dead predecessors. for (CFGBlock::const_pred_iterator I = Block->pred_begin(), - E = Block->pred_end(); I != E; ++I) { + E = Block->pred_end(); + I != E; ++I) { if (const CFGBlock *predBlock = *I) enqueue(predBlock); } @@ -567,8 +563,7 @@ unsigned DeadCodeScan::scanBackwards(const clang::CFGBlock *Start, if (isDeadCodeRoot(Block)) { reportDeadCode(Block, S, CB); count += scanMaybeReachableFromBlock(Block, PP, Reachable); - } - else { + } else { // Record this statement as the possibly best location in a // strongly-connected component of dead code for emitting a // warning. @@ -592,8 +587,7 @@ unsigned DeadCodeScan::scanBackwards(const clang::CFGBlock *Start, return count; } -static SourceLocation GetUnreachableLoc(const Stmt *S, - SourceRange &R1, +static SourceLocation GetUnreachableLoc(const Stmt *S, SourceRange &R1, SourceRange &R2) { R1 = R2 = SourceRange(); @@ -601,64 +595,63 @@ static SourceLocation GetUnreachableLoc(const Stmt *S, S = Ex->IgnoreParenImpCasts(); switch (S->getStmtClass()) { - case Expr::BinaryOperatorClass: { - const BinaryOperator *BO = cast(S); - return BO->getOperatorLoc(); - } - case Expr::UnaryOperatorClass: { - const UnaryOperator *UO = cast(S); - R1 = UO->getSubExpr()->getSourceRange(); - return UO->getOperatorLoc(); - } - case Expr::CompoundAssignOperatorClass: { - const CompoundAssignOperator *CAO = cast(S); - R1 = CAO->getLHS()->getSourceRange(); - R2 = CAO->getRHS()->getSourceRange(); - return CAO->getOperatorLoc(); - } - case Expr::BinaryConditionalOperatorClass: - case Expr::ConditionalOperatorClass: { - const AbstractConditionalOperator *CO = - cast(S); - return CO->getQuestionLoc(); - } - case Expr::MemberExprClass: { - const MemberExpr *ME = cast(S); - R1 = ME->getSourceRange(); - return ME->getMemberLoc(); - } - case Expr::ArraySubscriptExprClass: { - const ArraySubscriptExpr *ASE = cast(S); - R1 = ASE->getLHS()->getSourceRange(); - R2 = ASE->getRHS()->getSourceRange(); - return ASE->getRBracketLoc(); - } - case Expr::CStyleCastExprClass: { - const CStyleCastExpr *CSC = cast(S); - R1 = CSC->getSubExpr()->getSourceRange(); - return CSC->getLParenLoc(); - } - case Expr::CXXFunctionalCastExprClass: { - const CXXFunctionalCastExpr *CE = cast (S); - R1 = CE->getSubExpr()->getSourceRange(); - return CE->getBeginLoc(); - } - case Stmt::CXXTryStmtClass: { - return cast(S)->getHandler(0)->getCatchLoc(); - } - case Expr::ObjCBridgedCastExprClass: { - const ObjCBridgedCastExpr *CSC = cast(S); - R1 = CSC->getSubExpr()->getSourceRange(); - return CSC->getLParenLoc(); - } - default: ; + case Expr::BinaryOperatorClass: { + const BinaryOperator *BO = cast(S); + return BO->getOperatorLoc(); + } + case Expr::UnaryOperatorClass: { + const UnaryOperator *UO = cast(S); + R1 = UO->getSubExpr()->getSourceRange(); + return UO->getOperatorLoc(); + } + case Expr::CompoundAssignOperatorClass: { + const CompoundAssignOperator *CAO = cast(S); + R1 = CAO->getLHS()->getSourceRange(); + R2 = CAO->getRHS()->getSourceRange(); + return CAO->getOperatorLoc(); + } + case Expr::BinaryConditionalOperatorClass: + case Expr::ConditionalOperatorClass: { + const AbstractConditionalOperator *CO = + cast(S); + return CO->getQuestionLoc(); + } + case Expr::MemberExprClass: { + const MemberExpr *ME = cast(S); + R1 = ME->getSourceRange(); + return ME->getMemberLoc(); + } + case Expr::ArraySubscriptExprClass: { + const ArraySubscriptExpr *ASE = cast(S); + R1 = ASE->getLHS()->getSourceRange(); + R2 = ASE->getRHS()->getSourceRange(); + return ASE->getRBracketLoc(); + } + case Expr::CStyleCastExprClass: { + const CStyleCastExpr *CSC = cast(S); + R1 = CSC->getSubExpr()->getSourceRange(); + return CSC->getLParenLoc(); + } + case Expr::CXXFunctionalCastExprClass: { + const CXXFunctionalCastExpr *CE = cast(S); + R1 = CE->getSubExpr()->getSourceRange(); + return CE->getBeginLoc(); + } + case Stmt::CXXTryStmtClass: { + return cast(S)->getHandler(0)->getCatchLoc(); + } + case Expr::ObjCBridgedCastExprClass: { + const ObjCBridgedCastExpr *CSC = cast(S); + R1 = CSC->getSubExpr()->getSourceRange(); + return CSC->getLParenLoc(); + } + default:; } R1 = S->getSourceRange(); return S->getBeginLoc(); } -void DeadCodeScan::reportDeadCode(const CFGBlock *B, - const Stmt *S, +void DeadCodeScan::reportDeadCode(const CFGBlock *B, const Stmt *S, clang::reachable_code::Callback &CB) { // Classify the unreachable code found, or suppress it in some cases. reachable_code::UnreachableKind UK = reachable_code::UK_Other; @@ -668,8 +661,7 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B, } else if (isTrivialDoWhile(B, S) || isBuiltinUnreachable(S) || isBuiltinAssumeFalse(B, S, C)) { return; - } - else if (isDeadReturn(B, S)) { + } else if (isDeadReturn(B, S)) { UK = reachable_code::UK_Return; } @@ -721,9 +713,10 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B, // Reachability APIs. //===----------------------------------------------------------------------===// -namespace clang { namespace reachable_code { +namespace clang { +namespace reachable_code { -void Callback::anchor() { } +void Callback::anchor() {} unsigned ScanReachableFromBlock(const CFGBlock *Start, llvm::BitVector &Reachable) { @@ -741,7 +734,7 @@ void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP, // If there are no unreachable blocks, we're done. llvm::BitVector reachable(cfg->getNumBlockIDs()); unsigned numReachable = - scanMaybeReachableFromBlock(&cfg->getEntry(), PP, reachable); + scanMaybeReachableFromBlock(&cfg->getEntry(), PP, reachable); if (numReachable == cfg->getNumBlockIDs()) return; @@ -769,4 +762,5 @@ void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP, } } -}} // end namespace clang::reachable_code +} // namespace reachable_code +} // namespace clang diff --git a/clang/lib/Analysis/RetainSummaryManager.cpp b/clang/lib/Analysis/RetainSummaryManager.cpp index 8d279d969b613..c3d1153356b41 100644 --- a/clang/lib/Analysis/RetainSummaryManager.cpp +++ b/clang/lib/Analysis/RetainSummaryManager.cpp @@ -12,22 +12,19 @@ // //===----------------------------------------------------------------------===// -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "clang/Analysis/RetainSummaryManager.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ParentMap.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include using namespace clang; using namespace ento; -template -constexpr static bool isOneOf() { - return false; -} +template constexpr static bool isOneOf() { return false; } /// Helper function to check whether the class is one of the /// rest of varargs. @@ -63,7 +60,7 @@ struct GeneralizedConsumedAttr { } }; -} +} // namespace template std::optional RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D, @@ -125,7 +122,7 @@ RetainSummaryManager::getPersistentSummary(const RetainSummary &OldSumm) { CachedSummaryNode *N = SimpleSummaries.FindNodeOrInsertPos(ID, Pos); if (!N) { - N = (CachedSummaryNode *) BPAlloc.Allocate(); + N = (CachedSummaryNode *)BPAlloc.Allocate(); new (N) CachedSummaryNode(OldSumm); SimpleSummaries.InsertNode(N, Pos); } @@ -133,13 +130,12 @@ RetainSummaryManager::getPersistentSummary(const RetainSummary &OldSumm) { return &N->getValue(); } - RetainSummary *Summ = (RetainSummary *) BPAlloc.Allocate(); + RetainSummary *Summ = (RetainSummary *)BPAlloc.Allocate(); new (Summ) RetainSummary(OldSumm); return Summ; } -static bool isSubclass(const Decl *D, - StringRef ClassName) { +static bool isSubclass(const Decl *D, StringRef ClassName) { using namespace ast_matchers; DeclarationMatcher SubclassM = cxxRecordDecl(isSameOrDerivedFrom(std::string(ClassName))); @@ -164,10 +160,7 @@ static bool isOSObjectRequiredCast(StringRef S) { return S == "requiredMetaCast"; } -static bool isOSObjectThisCast(StringRef S) { - return S == "metaCast"; -} - +static bool isOSObjectThisCast(StringRef S) { return S == "metaCast"; } static bool isOSObjectPtr(QualType QT) { return isOSObjectSubclass(QT->getPointeeCXXRecordDecl()); @@ -225,8 +218,7 @@ static bool isOSObjectRelated(const CXXMethodDecl *MD) { return false; } -bool -RetainSummaryManager::isKnownSmartPointer(QualType QT) { +bool RetainSummaryManager::isKnownSmartPointer(QualType QT) { QT = QT.getCanonicalType(); const auto *RD = QT->getAsCXXRecordDecl(); if (!RD) @@ -291,11 +283,8 @@ RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD, } const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( - const FunctionDecl *FD, - StringRef FName, - QualType RetTy, - const FunctionType *FT, - bool &AllowAnnotations) { + const FunctionDecl *FD, StringRef FName, QualType RetTy, + const FunctionType *FT, bool &AllowAnnotations) { ArgEffects ScratchArgs(AF.getEmptyMap()); @@ -305,7 +294,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( // as 'void *arg', and then release it inside the thread. // FIXME: We could build a much more precise model for these functions. return getPersistentStopSummary(); - } else if(FName == "NSMakeCollectable") { + } else if (FName == "NSMakeCollectable") { // Handle: id NSMakeCollectable(CFTypeRef) AllowAnnotations = false; return RetTy->isObjCIdType() ? getUnarySummary(FT, DoNothing) @@ -314,10 +303,8 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( FName == "CMBufferQueueDequeueIfDataReadyAndRetain") { // These API functions are known to NOT act as a CFRetain wrapper. // They simply make a new object owned by the caller. - return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), - ScratchArgs, - ArgEffect(DoNothing), - ArgEffect(DoNothing)); + return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs, + ArgEffect(DoNothing), ArgEffect(DoNothing)); } else if (FName == "CFPlugInInstanceCreate") { return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs); } else if (FName == "IORegistryEntrySearchCFProperty" || @@ -335,16 +322,14 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( // These IOKit functions accept CF objects as arguments. // They also consume them without an appropriate annotation. ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(DecRef, ObjKind::CF)); - return getPersistentSummary(RetEffect::MakeNoRet(), - ScratchArgs, + return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, ArgEffect(DoNothing), ArgEffect(DoNothing)); } else if (FName == "IOServiceAddNotification" || FName == "IOServiceAddMatchingNotification") { // More IOKit functions suddenly accepting (and even more suddenly, // consuming) CF objects. ScratchArgs = AF.add(ScratchArgs, 2, ArgEffect(DecRef, ObjKind::CF)); - return getPersistentSummary(RetEffect::MakeNoRet(), - ScratchArgs, + return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, ArgEffect(DoNothing), ArgEffect(DoNothing)); } else if (FName == "CVPixelBufferCreateWithBytes") { // Eventually this can be improved by recognizing that the pixel @@ -354,8 +339,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( // FIXME: This function also has an out parameter that returns an // allocated object. ScratchArgs = AF.add(ScratchArgs, 7, ArgEffect(StopTracking)); - return getPersistentSummary(RetEffect::MakeNoRet(), - ScratchArgs, + return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, ArgEffect(DoNothing), ArgEffect(DoNothing)); } else if (FName == "CGBitmapContextCreateWithData") { // This is similar to the CVPixelBufferCreateWithBytes situation above. @@ -368,8 +352,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( } else if (FName == "CVPixelBufferCreateWithPlanarBytes") { // Same as CVPixelBufferCreateWithBytes, just more arguments. ScratchArgs = AF.add(ScratchArgs, 12, ArgEffect(StopTracking)); - return getPersistentSummary(RetEffect::MakeNoRet(), - ScratchArgs, + return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, ArgEffect(DoNothing), ArgEffect(DoNothing)); } else if (FName == "VTCompressionSessionEncodeFrame" || FName == "VTCompressionSessionEncodeMultiImageFrame") { @@ -379,8 +362,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( // To account for this possibility, conservatively stop tracking // the context. ScratchArgs = AF.add(ScratchArgs, 5, ArgEffect(StopTracking)); - return getPersistentSummary(RetEffect::MakeNoRet(), - ScratchArgs, + return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, ArgEffect(DoNothing), ArgEffect(DoNothing)); } else if (FName == "dispatch_set_context" || FName == "xpc_connection_set_context") { @@ -389,8 +371,7 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( // If we pass a context object that is memory managed, stop tracking it. // Same with xpc_connection_set_finalizer_f(). ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking)); - return getPersistentSummary(RetEffect::MakeNoRet(), - ScratchArgs, + return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, ArgEffect(DoNothing), ArgEffect(DoNothing)); } else if (FName.starts_with("NSLog")) { return getDoNothingSummary(); @@ -399,9 +380,8 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( // be deallocated by NSMapRemove. ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking)); ScratchArgs = AF.add(ScratchArgs, 2, ArgEffect(StopTracking)); - return getPersistentSummary(RetEffect::MakeNoRet(), - ScratchArgs, ArgEffect(DoNothing), - ArgEffect(DoNothing)); + return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, + ArgEffect(DoNothing), ArgEffect(DoNothing)); } if (RetTy->isPointerType()) { @@ -486,7 +466,8 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject( : DoNothing; return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, - ArgEffect(DoNothing), ArgEffect(E, ObjKind::CF)); + ArgEffect(DoNothing), + ArgEffect(E, ObjKind::CF)); } } @@ -518,11 +499,9 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD, if (const auto *MD = dyn_cast(FD)) if (!isOSObjectRelated(MD)) - return getPersistentSummary(RetEffect::MakeNoRet(), - ArgEffects(AF.getEmptyMap()), - ArgEffect(DoNothing), - ArgEffect(StopTracking), - ArgEffect(DoNothing)); + return getPersistentSummary( + RetEffect::MakeNoRet(), ArgEffects(AF.getEmptyMap()), + ArgEffect(DoNothing), ArgEffect(StopTracking), ArgEffect(DoNothing)); if (TrackObjCAndCFObjects) if (const RetainSummary *S = @@ -626,9 +605,8 @@ void RetainSummaryManager::updateSummaryForReceiverUnconsumedSelf( Template->setRetEffect(RetEffect::MakeNoRet()); } - void RetainSummaryManager::updateSummaryForArgumentTypes( - const AnyCall &C, const RetainSummary *&RS) { + const AnyCall &C, const RetainSummary *&RS) { RetainSummaryTemplate Template(RS, *this); unsigned parm_idx = 0; @@ -659,8 +637,7 @@ void RetainSummaryManager::updateSummaryForArgumentTypes( } const RetainSummary * -RetainSummaryManager::getSummary(AnyCall C, - bool HasNonZeroCallbackArg, +RetainSummaryManager::getSummary(AnyCall C, bool HasNonZeroCallbackArg, bool IsReceiverUnconsumedSelf, QualType ReceiverType) { const RetainSummary *Summ; @@ -701,7 +678,6 @@ RetainSummaryManager::getSummary(AnyCall C, return Summ; } - const RetainSummary * RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl *FD) { if (coreFoundation::followsCreateRule(FD)) @@ -764,7 +740,7 @@ RetainSummaryManager::canEval(const CallExpr *CE, const FunctionDecl *FD, } } - const FunctionDecl* FDD = FD->getDefinition(); + const FunctionDecl *FDD = FD->getDefinition(); if (FDD && isTrustedReferenceCountImplementation(FDD)) { hasTrustedImplementationAnnotation = true; return BehaviorSummary::Identity; @@ -782,7 +758,7 @@ RetainSummaryManager::canEval(const CallExpr *CE, const FunctionDecl *FD, } const RetainSummary * -RetainSummaryManager::getUnarySummary(const FunctionType* FT, +RetainSummaryManager::getUnarySummary(const FunctionType *FT, ArgEffectKind AE) { // Unary functions have no arg effects by definition. @@ -790,22 +766,20 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT, // Verify that this is *really* a unary function. This can // happen if people do weird things. - const FunctionProtoType* FTP = dyn_cast(FT); + const FunctionProtoType *FTP = dyn_cast(FT); if (!FTP || FTP->getNumParams() != 1) return getPersistentStopSummary(); ArgEffect Effect(AE, ObjKind::CF); ScratchArgs = AF.add(ScratchArgs, 0, Effect); - return getPersistentSummary(RetEffect::MakeNoRet(), - ScratchArgs, + return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs, ArgEffect(DoNothing), ArgEffect(DoNothing)); } const RetainSummary * RetainSummaryManager::getOSSummaryRetainRule(const FunctionDecl *FD) { - return getPersistentSummary(RetEffect::MakeNoRet(), - AF.getEmptyMap(), + return getPersistentSummary(RetEffect::MakeNoRet(), AF.getEmptyMap(), /*ReceiverEff=*/ArgEffect(DoNothing), /*DefaultEff=*/ArgEffect(DoNothing), /*ThisEff=*/ArgEffect(IncRef, ObjKind::OS)); @@ -813,8 +787,7 @@ RetainSummaryManager::getOSSummaryRetainRule(const FunctionDecl *FD) { const RetainSummary * RetainSummaryManager::getOSSummaryReleaseRule(const FunctionDecl *FD) { - return getPersistentSummary(RetEffect::MakeNoRet(), - AF.getEmptyMap(), + return getPersistentSummary(RetEffect::MakeNoRet(), AF.getEmptyMap(), /*ReceiverEff=*/ArgEffect(DoNothing), /*DefaultEff=*/ArgEffect(DoNothing), /*ThisEff=*/ArgEffect(DecRef, ObjKind::OS)); @@ -822,8 +795,7 @@ RetainSummaryManager::getOSSummaryReleaseRule(const FunctionDecl *FD) { const RetainSummary * RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) { - return getPersistentSummary(RetEffect::MakeNoRet(), - AF.getEmptyMap(), + return getPersistentSummary(RetEffect::MakeNoRet(), AF.getEmptyMap(), /*ReceiverEff=*/ArgEffect(DoNothing), /*DefaultEff=*/ArgEffect(DoNothing), /*ThisEff=*/ArgEffect(Dealloc, ObjKind::OS)); @@ -854,9 +826,6 @@ RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) { ArgEffect(DoNothing), ArgEffect(DoNothing)); } - - - //===----------------------------------------------------------------------===// // Summary creation for Selectors. //===----------------------------------------------------------------------===// @@ -887,8 +856,7 @@ RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy, /// \return Whether the chain of typedefs starting from @c QT /// has a typedef with a given name @c Name. -static bool hasTypedefNamed(QualType QT, - StringRef Name) { +static bool hasTypedefNamed(QualType QT, StringRef Name) { while (auto *T = QT->getAs()) { const auto &Context = T->getDecl()->getASTContext(); if (T->getDecl()->getIdentifier() == &Context.Idents.get(Name)) @@ -971,9 +939,8 @@ bool RetainSummaryManager::applyParamAnnotationEffect( return false; } -void -RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, - const FunctionDecl *FD) { +void RetainSummaryManager::updateSummaryFromAnnotations( + const RetainSummary *&Summ, const FunctionDecl *FD) { if (!FD) return; @@ -982,8 +949,8 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, // Effects on the parameters. unsigned parm_idx = 0; - for (auto pi = FD->param_begin(), - pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) + for (auto pi = FD->param_begin(), pe = FD->param_end(); pi != pe; + ++pi, ++parm_idx) applyParamAnnotationEffect(*pi, parm_idx, FD, Template); QualType RetTy = FD->getReturnType(); @@ -994,9 +961,8 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, Template->setThisEffect(ArgEffect(DecRef, ObjKind::OS)); } -void -RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, - const ObjCMethodDecl *MD) { +void RetainSummaryManager::updateSummaryFromAnnotations( + const RetainSummary *&Summ, const ObjCMethodDecl *MD) { if (!MD) return; @@ -1027,68 +993,68 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD, // Check the method family, and apply any default annotations. switch (MD ? MD->getMethodFamily() : S.getMethodFamily()) { - case OMF_None: - case OMF_initialize: - case OMF_performSelector: - // Assume all Objective-C methods follow Cocoa Memory Management rules. - // FIXME: Does the non-threaded performSelector family really belong here? - // The selector could be, say, @selector(copy). - if (cocoa::isCocoaObjectRef(RetTy)) - ResultEff = RetEffect::MakeNotOwned(ObjKind::ObjC); - else if (coreFoundation::isCFObjectRef(RetTy)) { - // ObjCMethodDecl currently doesn't consider CF objects as valid return - // values for alloc, new, copy, or mutableCopy, so we have to - // double-check with the selector. This is ugly, but there aren't that - // many Objective-C methods that return CF objects, right? - if (MD) { - switch (S.getMethodFamily()) { - case OMF_alloc: - case OMF_new: - case OMF_copy: - case OMF_mutableCopy: - ResultEff = RetEffect::MakeOwned(ObjKind::CF); - break; - default: - ResultEff = RetEffect::MakeNotOwned(ObjKind::CF); - break; - } - } else { + case OMF_None: + case OMF_initialize: + case OMF_performSelector: + // Assume all Objective-C methods follow Cocoa Memory Management rules. + // FIXME: Does the non-threaded performSelector family really belong here? + // The selector could be, say, @selector(copy). + if (cocoa::isCocoaObjectRef(RetTy)) + ResultEff = RetEffect::MakeNotOwned(ObjKind::ObjC); + else if (coreFoundation::isCFObjectRef(RetTy)) { + // ObjCMethodDecl currently doesn't consider CF objects as valid return + // values for alloc, new, copy, or mutableCopy, so we have to + // double-check with the selector. This is ugly, but there aren't that + // many Objective-C methods that return CF objects, right? + if (MD) { + switch (S.getMethodFamily()) { + case OMF_alloc: + case OMF_new: + case OMF_copy: + case OMF_mutableCopy: + ResultEff = RetEffect::MakeOwned(ObjKind::CF); + break; + default: ResultEff = RetEffect::MakeNotOwned(ObjKind::CF); + break; } + } else { + ResultEff = RetEffect::MakeNotOwned(ObjKind::CF); } - break; - case OMF_init: - ResultEff = ObjCInitRetE; - ReceiverEff = ArgEffect(DecRef, ObjKind::ObjC); - break; - case OMF_alloc: - case OMF_new: - case OMF_copy: - case OMF_mutableCopy: - if (cocoa::isCocoaObjectRef(RetTy)) - ResultEff = ObjCAllocRetE; - else if (coreFoundation::isCFObjectRef(RetTy)) - ResultEff = RetEffect::MakeOwned(ObjKind::CF); - break; - case OMF_autorelease: - ReceiverEff = ArgEffect(Autorelease, ObjKind::ObjC); - break; - case OMF_retain: - ReceiverEff = ArgEffect(IncRef, ObjKind::ObjC); - break; - case OMF_release: - ReceiverEff = ArgEffect(DecRef, ObjKind::ObjC); - break; - case OMF_dealloc: - ReceiverEff = ArgEffect(Dealloc, ObjKind::ObjC); - break; - case OMF_self: - // -self is handled specially by the ExprEngine to propagate the receiver. - break; - case OMF_retainCount: - case OMF_finalize: - // These methods don't return objects. - break; + } + break; + case OMF_init: + ResultEff = ObjCInitRetE; + ReceiverEff = ArgEffect(DecRef, ObjKind::ObjC); + break; + case OMF_alloc: + case OMF_new: + case OMF_copy: + case OMF_mutableCopy: + if (cocoa::isCocoaObjectRef(RetTy)) + ResultEff = ObjCAllocRetE; + else if (coreFoundation::isCFObjectRef(RetTy)) + ResultEff = RetEffect::MakeOwned(ObjKind::CF); + break; + case OMF_autorelease: + ReceiverEff = ArgEffect(Autorelease, ObjKind::ObjC); + break; + case OMF_retain: + ReceiverEff = ArgEffect(IncRef, ObjKind::ObjC); + break; + case OMF_release: + ReceiverEff = ArgEffect(DecRef, ObjKind::ObjC); + break; + case OMF_dealloc: + ReceiverEff = ArgEffect(Dealloc, ObjKind::ObjC); + break; + case OMF_self: + // -self is handled specially by the ExprEngine to propagate the receiver. + break; + case OMF_retainCount: + case OMF_finalize: + // These methods don't return objects. + break; } // If one of the arguments in the selector has the keyword 'delegate' we @@ -1124,9 +1090,9 @@ RetainSummaryManager::getClassMethodSummary(const ObjCMessageExpr *ME) { ME->getType(), ObjCClassMethodSummaries); } -const RetainSummary *RetainSummaryManager::getInstanceMethodSummary( - const ObjCMessageExpr *ME, - QualType ReceiverType) { +const RetainSummary * +RetainSummaryManager::getInstanceMethodSummary(const ObjCMessageExpr *ME, + QualType ReceiverType) { const ObjCInterfaceDecl *ReceiverClass = nullptr; // We do better tracking of the type of the object than the core ExprEngine. @@ -1153,8 +1119,7 @@ const RetainSummary *RetainSummaryManager::getInstanceMethodSummary( } const RetainSummary * -RetainSummaryManager::getMethodSummary(Selector S, - const ObjCInterfaceDecl *ID, +RetainSummaryManager::getMethodSummary(Selector S, const ObjCInterfaceDecl *ID, const ObjCMethodDecl *MD, QualType RetTy, ObjCMethodSummariesTy &CachedSummaries) { @@ -1183,8 +1148,8 @@ void RetainSummaryManager::InitializeClassMethodSummaries() { // Create the [NSAssertionHandler currentHander] summary. addClassMethSummary("NSAssertionHandler", "currentHandler", - getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::ObjC), - ScratchArgs)); + getPersistentSummary( + RetEffect::MakeNotOwned(ObjKind::ObjC), ScratchArgs)); // Create the [NSAutoreleasePool addObject:] summary. ScratchArgs = AF.add(ScratchArgs, 0, ArgEffect(Autorelease)); @@ -1209,10 +1174,10 @@ void RetainSummaryManager::InitializeMethodSummaries() { InitSumm); // The next methods are allocators. - const RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE, - ScratchArgs); + const RetainSummary *AllocSumm = + getPersistentSummary(ObjCAllocRetE, ScratchArgs); const RetainSummary *CFAllocSumm = - getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs); + getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs); // Create the "retain" selector. RetEffect NoRet = RetEffect::MakeNoRet(); @@ -1226,13 +1191,13 @@ void RetainSummaryManager::InitializeMethodSummaries() { addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ); // Create the -dealloc summary. - Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Dealloc, - ObjKind::ObjC)); + Summ = getPersistentSummary(NoRet, ScratchArgs, + ArgEffect(Dealloc, ObjKind::ObjC)); addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ); // Create the "autorelease" selector. - Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Autorelease, - ObjKind::ObjC)); + Summ = getPersistentSummary(NoRet, ScratchArgs, + ArgEffect(Autorelease, ObjKind::ObjC)); addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ); // For NSWindow, allocated objects are (initially) self-owned. diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index e25b843c9bf83..da0c359ed7252 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -65,9 +65,9 @@ using namespace threadSafety; ThreadSafetyHandler::~ThreadSafetyHandler() = default; /// Issue a warning about an invalid lock expression -static void warnInvalidLock(ThreadSafetyHandler &Handler, - const Expr *MutexExp, const NamedDecl *D, - const Expr *DeclExp, StringRef Kind) { +static void warnInvalidLock(ThreadSafetyHandler &Handler, const Expr *MutexExp, + const NamedDecl *D, const Expr *DeclExp, + StringRef Kind) { SourceLocation Loc; if (DeclExp) Loc = DeclExp->getExprLoc(); @@ -127,7 +127,7 @@ class FactEntry : public CapabilityExpr { : CapabilityExpr(CE), LKind(LK), Source(Src), AcquireLoc(Loc) {} virtual ~FactEntry() = default; - LockKind kind() const { return LKind; } + LockKind kind() const { return LKind; } SourceLocation loc() const { return AcquireLoc; } bool asserted() const { return Source == Asserted; } @@ -148,7 +148,7 @@ class FactEntry : public CapabilityExpr { // Return true if LKind >= LK, where exclusive > shared bool isAtLeast(LockKind LK) const { - return (LKind == LK_Exclusive) || (LK == LK_Shared); + return (LKind == LK_Exclusive) || (LK == LK_Shared); } }; @@ -211,19 +211,19 @@ class FactSet { return F; } - bool removeLock(FactManager& FM, const CapabilityExpr &CapE) { + bool removeLock(FactManager &FM, const CapabilityExpr &CapE) { unsigned n = FactIDs.size(); if (n == 0) return false; - for (unsigned i = 0; i < n-1; ++i) { + for (unsigned i = 0; i < n - 1; ++i) { if (FM[FactIDs[i]].matches(CapE)) { - FactIDs[i] = FactIDs[n-1]; + FactIDs[i] = FactIDs[n - 1]; FactIDs.pop_back(); return true; } } - if (FM[FactIDs[n-1]].matches(CapE)) { + if (FM[FactIDs[n - 1]].matches(CapE)) { FactIDs.pop_back(); return true; } @@ -231,15 +231,13 @@ class FactSet { } iterator findLockIter(FactManager &FM, const CapabilityExpr &CapE) { - return std::find_if(begin(), end(), [&](FactID ID) { - return FM[ID].matches(CapE); - }); + return std::find_if(begin(), end(), + [&](FactID ID) { return FM[ID].matches(CapE); }); } const FactEntry *findLock(FactManager &FM, const CapabilityExpr &CapE) const { - auto I = std::find_if(begin(), end(), [&](FactID ID) { - return FM[ID].matches(CapE); - }); + auto I = std::find_if(begin(), end(), + [&](FactID ID) { return FM[ID].matches(CapE); }); return I != end() ? &FM[*I] : nullptr; } @@ -259,7 +257,7 @@ class FactSet { return I != end() ? &FM[*I] : nullptr; } - bool containsMutexDecl(FactManager &FM, const ValueDecl* Vd) const { + bool containsMutexDecl(FactManager &FM, const ValueDecl *Vd) const { auto I = std::find_if(begin(), end(), [&](FactID ID) -> bool { return FM[ID].valueDecl() == Vd; }); @@ -293,16 +291,15 @@ class BeforeSet { public: BeforeSet() = default; - BeforeInfo* insertAttrExprs(const ValueDecl* Vd, - ThreadSafetyAnalyzer& Analyzer); + BeforeInfo *insertAttrExprs(const ValueDecl *Vd, + ThreadSafetyAnalyzer &Analyzer); BeforeInfo *getBeforeInfoForDecl(const ValueDecl *Vd, ThreadSafetyAnalyzer &Analyzer); - void checkBeforeAfter(const ValueDecl* Vd, - const FactSet& FSet, - ThreadSafetyAnalyzer& Analyzer, - SourceLocation Loc, StringRef CapKind); + void checkBeforeAfter(const ValueDecl *Vd, const FactSet &FSet, + ThreadSafetyAnalyzer &Analyzer, SourceLocation Loc, + StringRef CapKind); private: BeforeMap BMap; @@ -426,7 +423,7 @@ class LocalVariableMap { } /// Look up a definition, within the given context. - const VarDefinition* lookup(const NamedDecl *D, Context Ctx) { + const VarDefinition *lookup(const NamedDecl *D, Context Ctx) { const unsigned *i = Ctx.lookup(D); if (!i) return nullptr; @@ -437,7 +434,7 @@ class LocalVariableMap { /// Look up the definition for D within the given context. Returns /// NULL if the expression is not statically known. If successful, also /// modifies Ctx to hold the context of the return Expr. - const Expr* lookupExpr(const NamedDecl *D, Context &Ctx) { + const Expr *lookupExpr(const NamedDecl *D, Context &Ctx) { const unsigned *P = Ctx.lookup(D); if (!P) return nullptr; @@ -459,7 +456,7 @@ class LocalVariableMap { /// clients of the class to get the appropriate context when traversing the /// CFG. It must be called for every assignment or DeclStmt. Context getNextContext(unsigned &CtxIndex, const Stmt *S, Context C) { - if (SavedContexts[CtxIndex+1].first == S) { + if (SavedContexts[CtxIndex + 1].first == S) { CtxIndex++; Context Result = SavedContexts[CtxIndex].second; return Result; @@ -478,7 +475,7 @@ class LocalVariableMap { return; } Dec->printName(llvm::errs()); - llvm::errs() << "." << i << " " << ((const void*) Dec); + llvm::errs() << "." << i << " " << ((const void *)Dec); } /// Dumps an ASCII representation of the variable map to llvm::errs() @@ -489,7 +486,8 @@ class LocalVariableMap { dumpVarDefinitionName(i); llvm::errs() << " = "; - if (Exp) Exp->dump(); + if (Exp) + Exp->dump(); else { dumpVarDefinitionName(Ref); llvm::errs() << "\n"; @@ -516,7 +514,7 @@ class LocalVariableMap { friend class VarMapBuilder; // Get the current context index - unsigned getContextIndex() { return SavedContexts.size()-1; } + unsigned getContextIndex() { return SavedContexts.size() - 1; } // Save the current context for later replay void saveContext(const Stmt *S, Context C) { @@ -591,7 +589,7 @@ namespace { /// Visitor which builds a LocalVariableMap class VarMapBuilder : public ConstStmtVisitor { public: - LocalVariableMap* VMap; + LocalVariableMap *VMap; LocalVariableMap::Context Ctx; VarMapBuilder(LocalVariableMap *VM, LocalVariableMap::Context C) @@ -647,15 +645,15 @@ void VarMapBuilder::VisitBinaryOperator(const BinaryOperator *BO) { // Computes the intersection of two contexts. The intersection is the // set of variables which have the same definition in both contexts; // variables with different definitions are discarded. -LocalVariableMap::Context -LocalVariableMap::intersectContexts(Context C1, Context C2) { +LocalVariableMap::Context LocalVariableMap::intersectContexts(Context C1, + Context C2) { Context Result = C1; for (const auto &P : C1) { const NamedDecl *Dec = P.first; const unsigned *i2 = C2.lookup(Dec); - if (!i2) // variable doesn't exist on second path + if (!i2) // variable doesn't exist on second path Result = removeDefinition(Dec, Result); - else if (*i2 != P.second) // variable exists, but has different definition + else if (*i2 != P.second) // variable exists, but has different definition Result = clearDefinition(Dec, Result); } return Result; @@ -682,7 +680,7 @@ void LocalVariableMap::intersectBackEdge(Context C1, Context C2) { const unsigned *i2 = C2.lookup(P.first); if (!i2 || (*i2 != i1)) - VDef->Ref = 0; // Mark this variable as undefined + VDef->Ref = 0; // Mark this variable as undefined } } @@ -738,7 +736,8 @@ void LocalVariableMap::traverseCFG(CFG *CFGraph, bool HasBackEdges = false; bool CtxInit = true; for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(), - PE = CurrBlock->pred_end(); PI != PE; ++PI) { + PE = CurrBlock->pred_end(); + PI != PE; ++PI) { // if *PI -> CurrBlock is a back edge, so skip it if (*PI == nullptr || !VisitedBlocks.alreadySet(*PI)) { HasBackEdges = true; @@ -751,11 +750,9 @@ void LocalVariableMap::traverseCFG(CFG *CFGraph, if (CtxInit) { CurrBlockInfo->EntryContext = PrevBlockInfo->ExitContext; CtxInit = false; - } - else { - CurrBlockInfo->EntryContext = - intersectContexts(CurrBlockInfo->EntryContext, - PrevBlockInfo->ExitContext); + } else { + CurrBlockInfo->EntryContext = intersectContexts( + CurrBlockInfo->EntryContext, PrevBlockInfo->ExitContext); } } @@ -763,7 +760,7 @@ void LocalVariableMap::traverseCFG(CFG *CFGraph, // intersectBackEdges later. if (HasBackEdges) CurrBlockInfo->EntryContext = - createReferenceContext(CurrBlockInfo->EntryContext); + createReferenceContext(CurrBlockInfo->EntryContext); // Create a starting context index for the current block saveContext(nullptr, CurrBlockInfo->EntryContext); @@ -773,27 +770,28 @@ void LocalVariableMap::traverseCFG(CFG *CFGraph, VarMapBuilder VMapBuilder(this, CurrBlockInfo->EntryContext); for (const auto &BI : *CurrBlock) { switch (BI.getKind()) { - case CFGElement::Statement: { - CFGStmt CS = BI.castAs(); - VMapBuilder.Visit(CS.getStmt()); - break; - } - default: - break; + case CFGElement::Statement: { + CFGStmt CS = BI.castAs(); + VMapBuilder.Visit(CS.getStmt()); + break; + } + default: + break; } } CurrBlockInfo->ExitContext = VMapBuilder.Ctx; // Mark variables on back edges as "unknown" if they've been changed. for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(), - SE = CurrBlock->succ_end(); SI != SE; ++SI) { + SE = CurrBlock->succ_end(); + SI != SE; ++SI) { // if CurrBlock -> *SI is *not* a back edge if (*SI == nullptr || !VisitedBlocks.alreadySet(*SI)) continue; CFGBlock *FirstLoopBlock = *SI; Context LoopBegin = BlockInfo[FirstLoopBlock->getBlockID()].EntryContext; - Context LoopEnd = CurrBlockInfo->ExitContext; + Context LoopEnd = CurrBlockInfo->ExitContext; intersectBackEdge(LoopBegin, LoopEnd); } } @@ -817,7 +815,8 @@ static void findBlockLocations(CFG *CFGraph, CurrBlockInfo->EntryLoc = CurrBlockInfo->ExitLoc = S->getBeginLoc(); } else { for (CFGBlock::const_reverse_iterator BI = CurrBlock->rbegin(), - BE = CurrBlock->rend(); BI != BE; ++BI) { + BE = CurrBlock->rend(); + BI != BE; ++BI) { // FIXME: Handle other CFGElement kinds. if (std::optional CS = BI->getAs()) { CurrBlockInfo->ExitLoc = CS->getStmt()->getBeginLoc(); @@ -987,8 +986,8 @@ class ScopedLockableFactEntry : public FactEntry { SourceLocation loc, ThreadSafetyHandler *Handler) const { if (FSet.findLock(FactMan, Cp)) { FSet.removeLock(FactMan, Cp); - FSet.addLock(FactMan, std::make_unique( - !Cp, LK_Exclusive, loc)); + FSet.addLock(FactMan, + std::make_unique(!Cp, LK_Exclusive, loc)); } else if (Handler) { SourceLocation PrevLoc; if (const FactEntry *Neg = FSet.findLock(FactMan, !Cp)) @@ -1018,7 +1017,7 @@ class ThreadSafetyAnalyzer { BeforeSet *GlobalBeforeSet; public: - ThreadSafetyAnalyzer(ThreadSafetyHandler &H, BeforeSet* Bset) + ThreadSafetyAnalyzer(ThreadSafetyHandler &H, BeforeSet *Bset) : Arena(&Bpa), SxBuilder(Arena), Handler(H), GlobalBeforeSet(Bset) {} bool inCurrentScope(const CapabilityExpr &CapE); @@ -1034,16 +1033,14 @@ class ThreadSafetyAnalyzer { template void getMutexIDs(CapExprSet &Mtxs, AttrType *Attr, const Expr *Exp, - const NamedDecl *D, - const CFGBlock *PredBlock, const CFGBlock *CurrBlock, - Expr *BrE, bool Neg); + const NamedDecl *D, const CFGBlock *PredBlock, + const CFGBlock *CurrBlock, Expr *BrE, bool Neg); - const CallExpr* getTrylockCallExpr(const Stmt *Cond, LocalVarContext C, + const CallExpr *getTrylockCallExpr(const Stmt *Cond, LocalVarContext C, bool &Negate); void getEdgeLockset(FactSet &Result, const FactSet &ExitSet, - const CFGBlock* PredBlock, - const CFGBlock *CurrBlock); + const CFGBlock *PredBlock, const CFGBlock *CurrBlock); bool join(const FactEntry &a, const FactEntry &b, bool CanModify); @@ -1075,8 +1072,9 @@ class ThreadSafetyAnalyzer { } // namespace /// Process acquired_before and acquired_after attributes on Vd. -BeforeSet::BeforeInfo* BeforeSet::insertAttrExprs(const ValueDecl* Vd, - ThreadSafetyAnalyzer& Analyzer) { +BeforeSet::BeforeInfo * +BeforeSet::insertAttrExprs(const ValueDecl *Vd, + ThreadSafetyAnalyzer &Analyzer) { // Create a new entry for Vd. BeforeInfo *Info = nullptr; { @@ -1090,39 +1088,37 @@ BeforeSet::BeforeInfo* BeforeSet::insertAttrExprs(const ValueDecl* Vd, for (const auto *At : Vd->attrs()) { switch (At->getKind()) { - case attr::AcquiredBefore: { - const auto *A = cast(At); - - // Read exprs from the attribute, and add them to BeforeVect. - for (const auto *Arg : A->args()) { - CapabilityExpr Cp = - Analyzer.SxBuilder.translateAttrExpr(Arg, nullptr); - if (const ValueDecl *Cpvd = Cp.valueDecl()) { - Info->Vect.push_back(Cpvd); - const auto It = BMap.find(Cpvd); - if (It == BMap.end()) - insertAttrExprs(Cpvd, Analyzer); - } + case attr::AcquiredBefore: { + const auto *A = cast(At); + + // Read exprs from the attribute, and add them to BeforeVect. + for (const auto *Arg : A->args()) { + CapabilityExpr Cp = Analyzer.SxBuilder.translateAttrExpr(Arg, nullptr); + if (const ValueDecl *Cpvd = Cp.valueDecl()) { + Info->Vect.push_back(Cpvd); + const auto It = BMap.find(Cpvd); + if (It == BMap.end()) + insertAttrExprs(Cpvd, Analyzer); } - break; } - case attr::AcquiredAfter: { - const auto *A = cast(At); - - // Read exprs from the attribute, and add them to BeforeVect. - for (const auto *Arg : A->args()) { - CapabilityExpr Cp = - Analyzer.SxBuilder.translateAttrExpr(Arg, nullptr); - if (const ValueDecl *ArgVd = Cp.valueDecl()) { - // Get entry for mutex listed in attribute - BeforeInfo *ArgInfo = getBeforeInfoForDecl(ArgVd, Analyzer); - ArgInfo->Vect.push_back(Vd); - } + break; + } + case attr::AcquiredAfter: { + const auto *A = cast(At); + + // Read exprs from the attribute, and add them to BeforeVect. + for (const auto *Arg : A->args()) { + CapabilityExpr Cp = Analyzer.SxBuilder.translateAttrExpr(Arg, nullptr); + if (const ValueDecl *ArgVd = Cp.valueDecl()) { + // Get entry for mutex listed in attribute + BeforeInfo *ArgInfo = getBeforeInfoForDecl(ArgVd, Analyzer); + ArgInfo->Vect.push_back(Vd); } - break; } - default: - break; + break; + } + default: + break; } } @@ -1143,15 +1139,14 @@ BeforeSet::getBeforeInfoForDecl(const ValueDecl *Vd, } /// Return true if any mutexes in FSet are in the acquired_before set of Vd. -void BeforeSet::checkBeforeAfter(const ValueDecl* StartVd, - const FactSet& FSet, - ThreadSafetyAnalyzer& Analyzer, +void BeforeSet::checkBeforeAfter(const ValueDecl *StartVd, const FactSet &FSet, + ThreadSafetyAnalyzer &Analyzer, SourceLocation Loc, StringRef CapKind) { - SmallVector InfoVect; + SmallVector InfoVect; // Do a depth-first traversal of Vd. // Return true if there are cycles. - std::function traverse = [&](const ValueDecl* Vd) { + std::function traverse = [&](const ValueDecl *Vd) { if (!Vd) return false; @@ -1210,16 +1205,14 @@ static const ValueDecl *getValueDecl(const Expr *Exp) { namespace { -template -class has_arg_iterator_range { +template class has_arg_iterator_range { using yes = char[1]; using no = char[2]; template - static yes& test(Inner *I, decltype(I->args()) * = nullptr); + static yes &test(Inner *I, decltype(I->args()) * = nullptr); - template - static no& test(...); + template static no &test(...); public: static const bool value = sizeof(test(nullptr)) == sizeof(yes); @@ -1268,8 +1261,7 @@ void ThreadSafetyAnalyzer::addLock(FactSet &FSet, const FactEntry *Nen = FSet.findLock(FactMan, NegC); if (Nen) { FSet.removeLock(FactMan, NegC); - } - else { + } else { if (inCurrentScope(*Entry) && !Entry->asserted()) Handler.handleNegativeNotHeld(Entry->getKind(), Entry->toString(), NegC.toString(), Entry->loc()); @@ -1277,8 +1269,7 @@ void ThreadSafetyAnalyzer::addLock(FactSet &FSet, } // Check before/after constraints - if (Handler.issueBetaWarnings() && - !Entry->asserted() && !Entry->declared()) { + if (Handler.issueBetaWarnings() && !Entry->asserted() && !Entry->declared()) { GlobalBeforeSet->checkBeforeAfter(Entry->valueDecl(), FSet, *this, Entry->loc(), Entry->getKind()); } @@ -1333,7 +1324,7 @@ void ThreadSafetyAnalyzer::getMutexIDs(CapExprSet &Mtxs, AttrType *Attr, warnInvalidLock(Handler, nullptr, D, Exp, Cp.getKind()); return; } - //else + // else if (!Cp.shouldIgnore()) Mtxs.push_back_nodup(Cp); return; @@ -1345,7 +1336,7 @@ void ThreadSafetyAnalyzer::getMutexIDs(CapExprSet &Mtxs, AttrType *Attr, warnInvalidLock(Handler, nullptr, D, Exp, Cp.getKind()); continue; } - //else + // else if (!Cp.shouldIgnore()) Mtxs.push_back_nodup(Cp); } @@ -1358,8 +1349,8 @@ template void ThreadSafetyAnalyzer::getMutexIDs(CapExprSet &Mtxs, AttrType *Attr, const Expr *Exp, const NamedDecl *D, const CFGBlock *PredBlock, - const CFGBlock *CurrBlock, - Expr *BrE, bool Neg) { + const CFGBlock *CurrBlock, Expr *BrE, + bool Neg) { // Find out which branch has the lock bool branch = false; if (const auto *BLE = dyn_cast_or_null(BrE)) @@ -1374,7 +1365,8 @@ void ThreadSafetyAnalyzer::getMutexIDs(CapExprSet &Mtxs, AttrType *Attr, // If we've taken the trylock branch, then add the lock int i = 0; for (CFGBlock::const_succ_iterator SI = PredBlock->succ_begin(), - SE = PredBlock->succ_end(); SI != SE && i < 2; ++SI, ++i) { + SE = PredBlock->succ_end(); + SI != SE && i < 2; ++SI, ++i) { if (*SI == CurrBlock && i == branchnum) getMutexIDs(Mtxs, Attr, Exp, D); } @@ -1398,7 +1390,7 @@ static bool getStaticBooleanValue(Expr *E, bool &TCond) { // If Cond can be traced back to a function call, return the call expression. // The negate variable should be called with false, and will be set to true // if the function call is negated, e.g. if (!mu.tryLock(...)) -const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond, +const CallExpr *ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond, LocalVarContext C, bool &Negate) { if (!Cond) @@ -1408,8 +1400,7 @@ const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond, if (CallExp->getBuiltinCallee() == Builtin::BI__builtin_expect) return getTrylockCallExpr(CallExp->getArg(0), C, Negate); return CallExp; - } - else if (const auto *PE = dyn_cast(Cond)) + } else if (const auto *PE = dyn_cast(Cond)) return getTrylockCallExpr(PE->getSubExpr(), C, Negate); else if (const auto *CE = dyn_cast(Cond)) return getTrylockCallExpr(CE->getSubExpr(), C, Negate); @@ -1418,27 +1409,27 @@ const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond, else if (const auto *DRE = dyn_cast(Cond)) { const Expr *E = LocalVarMap.lookupExpr(DRE->getDecl(), C); return getTrylockCallExpr(E, C, Negate); - } - else if (const auto *UOP = dyn_cast(Cond)) { + } else if (const auto *UOP = dyn_cast(Cond)) { if (UOP->getOpcode() == UO_LNot) { Negate = !Negate; return getTrylockCallExpr(UOP->getSubExpr(), C, Negate); } return nullptr; - } - else if (const auto *BOP = dyn_cast(Cond)) { + } else if (const auto *BOP = dyn_cast(Cond)) { if (BOP->getOpcode() == BO_EQ || BOP->getOpcode() == BO_NE) { if (BOP->getOpcode() == BO_NE) Negate = !Negate; bool TCond = false; if (getStaticBooleanValue(BOP->getRHS(), TCond)) { - if (!TCond) Negate = !Negate; + if (!TCond) + Negate = !Negate; return getTrylockCallExpr(BOP->getLHS(), C, Negate); } TCond = false; if (getStaticBooleanValue(BOP->getLHS(), TCond)) { - if (!TCond) Negate = !Negate; + if (!TCond) + Negate = !Negate; return getTrylockCallExpr(BOP->getRHS(), C, Negate); } return nullptr; @@ -1468,7 +1459,7 @@ const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond, /// Find the lockset that holds on the edge between PredBlock /// and CurrBlock. The edge set is the exit set of PredBlock (passed /// as the ExitSet parameter) plus any trylocks, which are conditionally held. -void ThreadSafetyAnalyzer::getEdgeLockset(FactSet& Result, +void ThreadSafetyAnalyzer::getEdgeLockset(FactSet &Result, const FactSet &ExitSet, const CFGBlock *PredBlock, const CFGBlock *CurrBlock) { @@ -1488,7 +1479,7 @@ void ThreadSafetyAnalyzer::getEdgeLockset(FactSet& Result, return; auto *FunDecl = dyn_cast_or_null(Exp->getCalleeDecl()); - if(!FunDecl || !FunDecl->hasAttrs()) + if (!FunDecl || !FunDecl->hasAttrs()) return; CapExprSet ExclusiveLocksToAdd; @@ -1497,27 +1488,27 @@ void ThreadSafetyAnalyzer::getEdgeLockset(FactSet& Result, // If the condition is a call to a Trylock function, then grab the attributes for (const auto *Attr : FunDecl->attrs()) { switch (Attr->getKind()) { - case attr::TryAcquireCapability: { - auto *A = cast(Attr); - getMutexIDs(A->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, A, - Exp, FunDecl, PredBlock, CurrBlock, A->getSuccessValue(), - Negate); - break; - }; - case attr::ExclusiveTrylockFunction: { - const auto *A = cast(Attr); - getMutexIDs(ExclusiveLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock, - A->getSuccessValue(), Negate); - break; - } - case attr::SharedTrylockFunction: { - const auto *A = cast(Attr); - getMutexIDs(SharedLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock, - A->getSuccessValue(), Negate); - break; - } - default: - break; + case attr::TryAcquireCapability: { + auto *A = cast(Attr); + getMutexIDs(A->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, A, + Exp, FunDecl, PredBlock, CurrBlock, A->getSuccessValue(), + Negate); + break; + }; + case attr::ExclusiveTrylockFunction: { + const auto *A = cast(Attr); + getMutexIDs(ExclusiveLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock, + A->getSuccessValue(), Negate); + break; + } + case attr::SharedTrylockFunction: { + const auto *A = cast(Attr); + getMutexIDs(SharedLocksToAdd, A, Exp, FunDecl, PredBlock, CurrBlock, + A->getSuccessValue(), Negate); + break; + } + default: + break; } } @@ -1631,7 +1622,7 @@ void ThreadSafetyAnalyzer::warnIfMutexNotHeld( if (LDat) { // Warn that there's no precise match. std::string PartMatchStr = LDat->toString(); - StringRef PartMatchName(PartMatchStr); + StringRef PartMatchName(PartMatchStr); Handler.handleMutexNotHeld(Cp.getKind(), D, POK, Cp.toString(), LK, Loc, &PartMatchName); } else { @@ -1762,7 +1753,8 @@ void ThreadSafetyAnalyzer::checkPtAccess(const FactSet &FSet, const Expr *Exp, // Pass by reference warnings are under a different flag. ProtectedOperationKind PtPOK = POK_VarDereference; - if (POK == POK_PassByRef) PtPOK = POK_PtPassByRef; + if (POK == POK_PassByRef) + PtPOK = POK_PtPassByRef; if (POK == POK_ReturnByRef) PtPOK = POK_PtReturnByRef; @@ -1820,96 +1812,96 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D, Loc = Exp->getExprLoc(); } - for(const Attr *At : D->attrs()) { + for (const Attr *At : D->attrs()) { switch (At->getKind()) { - // When we encounter a lock function, we need to add the lock to our - // lockset. - case attr::AcquireCapability: { - const auto *A = cast(At); - Analyzer->getMutexIDs(A->isShared() ? SharedLocksToAdd - : ExclusiveLocksToAdd, - A, Exp, D, Self); - break; - } + // When we encounter a lock function, we need to add the lock to our + // lockset. + case attr::AcquireCapability: { + const auto *A = cast(At); + Analyzer->getMutexIDs(A->isShared() ? SharedLocksToAdd + : ExclusiveLocksToAdd, + A, Exp, D, Self); + break; + } - // An assert will add a lock to the lockset, but will not generate - // a warning if it is already there, and will not generate a warning - // if it is not removed. - case attr::AssertExclusiveLock: { - const auto *A = cast(At); - - CapExprSet AssertLocks; - Analyzer->getMutexIDs(AssertLocks, A, Exp, D, Self); - for (const auto &AssertLock : AssertLocks) - Analyzer->addLock( - FSet, std::make_unique( - AssertLock, LK_Exclusive, Loc, FactEntry::Asserted)); - break; - } - case attr::AssertSharedLock: { - const auto *A = cast(At); - - CapExprSet AssertLocks; - Analyzer->getMutexIDs(AssertLocks, A, Exp, D, Self); - for (const auto &AssertLock : AssertLocks) - Analyzer->addLock( - FSet, std::make_unique( - AssertLock, LK_Shared, Loc, FactEntry::Asserted)); - break; - } + // An assert will add a lock to the lockset, but will not generate + // a warning if it is already there, and will not generate a warning + // if it is not removed. + case attr::AssertExclusiveLock: { + const auto *A = cast(At); + + CapExprSet AssertLocks; + Analyzer->getMutexIDs(AssertLocks, A, Exp, D, Self); + for (const auto &AssertLock : AssertLocks) + Analyzer->addLock( + FSet, std::make_unique( + AssertLock, LK_Exclusive, Loc, FactEntry::Asserted)); + break; + } + case attr::AssertSharedLock: { + const auto *A = cast(At); + + CapExprSet AssertLocks; + Analyzer->getMutexIDs(AssertLocks, A, Exp, D, Self); + for (const auto &AssertLock : AssertLocks) + Analyzer->addLock(FSet, + std::make_unique( + AssertLock, LK_Shared, Loc, FactEntry::Asserted)); + break; + } - case attr::AssertCapability: { - const auto *A = cast(At); - CapExprSet AssertLocks; - Analyzer->getMutexIDs(AssertLocks, A, Exp, D, Self); - for (const auto &AssertLock : AssertLocks) - Analyzer->addLock(FSet, std::make_unique( - AssertLock, - A->isShared() ? LK_Shared : LK_Exclusive, - Loc, FactEntry::Asserted)); - break; - } + case attr::AssertCapability: { + const auto *A = cast(At); + CapExprSet AssertLocks; + Analyzer->getMutexIDs(AssertLocks, A, Exp, D, Self); + for (const auto &AssertLock : AssertLocks) + Analyzer->addLock(FSet, std::make_unique( + AssertLock, + A->isShared() ? LK_Shared : LK_Exclusive, + Loc, FactEntry::Asserted)); + break; + } - // When we encounter an unlock function, we need to remove unlocked - // mutexes from the lockset, and flag a warning if they are not there. - case attr::ReleaseCapability: { - const auto *A = cast(At); - if (A->isGeneric()) - Analyzer->getMutexIDs(GenericLocksToRemove, A, Exp, D, Self); - else if (A->isShared()) - Analyzer->getMutexIDs(SharedLocksToRemove, A, Exp, D, Self); - else - Analyzer->getMutexIDs(ExclusiveLocksToRemove, A, Exp, D, Self); - break; - } + // When we encounter an unlock function, we need to remove unlocked + // mutexes from the lockset, and flag a warning if they are not there. + case attr::ReleaseCapability: { + const auto *A = cast(At); + if (A->isGeneric()) + Analyzer->getMutexIDs(GenericLocksToRemove, A, Exp, D, Self); + else if (A->isShared()) + Analyzer->getMutexIDs(SharedLocksToRemove, A, Exp, D, Self); + else + Analyzer->getMutexIDs(ExclusiveLocksToRemove, A, Exp, D, Self); + break; + } - case attr::RequiresCapability: { - const auto *A = cast(At); - for (auto *Arg : A->args()) { - Analyzer->warnIfMutexNotHeld(FSet, D, Exp, - A->isShared() ? AK_Read : AK_Written, - Arg, POK_FunctionCall, Self, Loc); - // use for adopting a lock - if (!Scp.shouldIgnore()) - Analyzer->getMutexIDs(ScopedReqsAndExcludes, A, Exp, D, Self); - } - break; + case attr::RequiresCapability: { + const auto *A = cast(At); + for (auto *Arg : A->args()) { + Analyzer->warnIfMutexNotHeld(FSet, D, Exp, + A->isShared() ? AK_Read : AK_Written, Arg, + POK_FunctionCall, Self, Loc); + // use for adopting a lock + if (!Scp.shouldIgnore()) + Analyzer->getMutexIDs(ScopedReqsAndExcludes, A, Exp, D, Self); } + break; + } - case attr::LocksExcluded: { - const auto *A = cast(At); - for (auto *Arg : A->args()) { - Analyzer->warnIfMutexHeld(FSet, D, Exp, Arg, Self, Loc); - // use for deferring a lock - if (!Scp.shouldIgnore()) - Analyzer->getMutexIDs(ScopedReqsAndExcludes, A, Exp, D, Self); - } - break; + case attr::LocksExcluded: { + const auto *A = cast(At); + for (auto *Arg : A->args()) { + Analyzer->warnIfMutexHeld(FSet, D, Exp, Arg, Self, Loc); + // use for deferring a lock + if (!Scp.shouldIgnore()) + Analyzer->getMutexIDs(ScopedReqsAndExcludes, A, Exp, D, Self); } + break; + } - // Ignore attributes unrelated to thread-safety - default: - break; + // Ignore attributes unrelated to thread-safety + default: + break; } } @@ -1955,14 +1947,14 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D, /// VisitCastExpr. void BuildLockset::VisitUnaryOperator(const UnaryOperator *UO) { switch (UO->getOpcode()) { - case UO_PostDec: - case UO_PostInc: - case UO_PreDec: - case UO_PreInc: - checkAccess(UO->getSubExpr(), AK_Written); - break; - default: - break; + case UO_PostDec: + case UO_PostInc: + case UO_PreDec: + case UO_PreInc: + checkAccess(UO->getSubExpr(), AK_Written); + break; + default: + break; } } @@ -2038,51 +2030,51 @@ void BuildLockset::VisitCallExpr(const CallExpr *Exp) { } else if (const auto *OE = dyn_cast(Exp)) { OverloadedOperatorKind OEop = OE->getOperator(); switch (OEop) { - case OO_Equal: - case OO_PlusEqual: - case OO_MinusEqual: - case OO_StarEqual: - case OO_SlashEqual: - case OO_PercentEqual: - case OO_CaretEqual: - case OO_AmpEqual: - case OO_PipeEqual: - case OO_LessLessEqual: - case OO_GreaterGreaterEqual: - checkAccess(OE->getArg(1), AK_Read); - [[fallthrough]]; - case OO_PlusPlus: - case OO_MinusMinus: - checkAccess(OE->getArg(0), AK_Written); - break; - case OO_Star: - case OO_ArrowStar: - case OO_Arrow: - case OO_Subscript: - if (!(OEop == OO_Star && OE->getNumArgs() > 1)) { - // Grrr. operator* can be multiplication... - checkPtAccess(OE->getArg(0), AK_Read); - } - [[fallthrough]]; - default: { - // TODO: get rid of this, and rely on pass-by-ref instead. - const Expr *Obj = OE->getArg(0); - checkAccess(Obj, AK_Read); - // Check the remaining arguments. For method operators, the first - // argument is the implicit self argument, and doesn't appear in the - // FunctionDecl, but for non-methods it does. - const FunctionDecl *FD = OE->getDirectCallee(); - examineArguments(FD, std::next(OE->arg_begin()), OE->arg_end(), - /*SkipFirstParam*/ !isa(FD)); - break; + case OO_Equal: + case OO_PlusEqual: + case OO_MinusEqual: + case OO_StarEqual: + case OO_SlashEqual: + case OO_PercentEqual: + case OO_CaretEqual: + case OO_AmpEqual: + case OO_PipeEqual: + case OO_LessLessEqual: + case OO_GreaterGreaterEqual: + checkAccess(OE->getArg(1), AK_Read); + [[fallthrough]]; + case OO_PlusPlus: + case OO_MinusMinus: + checkAccess(OE->getArg(0), AK_Written); + break; + case OO_Star: + case OO_ArrowStar: + case OO_Arrow: + case OO_Subscript: + if (!(OEop == OO_Star && OE->getNumArgs() > 1)) { + // Grrr. operator* can be multiplication... + checkPtAccess(OE->getArg(0), AK_Read); } + [[fallthrough]]; + default: { + // TODO: get rid of this, and rely on pass-by-ref instead. + const Expr *Obj = OE->getArg(0); + checkAccess(Obj, AK_Read); + // Check the remaining arguments. For method operators, the first + // argument is the implicit self argument, and doesn't appear in the + // FunctionDecl, but for non-methods it does. + const FunctionDecl *FD = OE->getDirectCallee(); + examineArguments(FD, std::next(OE->arg_begin()), OE->arg_end(), + /*SkipFirstParam*/ !isa(FD)); + break; + } } } else { examineArguments(Exp->getDirectCallee(), Exp->arg_begin(), Exp->arg_end()); } auto *D = dyn_cast_or_null(Exp->getCalleeDecl()); - if(!D || !D->hasAttrs()) + if (!D || !D->hasAttrs()) return; handleCall(Exp, D); } @@ -2090,7 +2082,7 @@ void BuildLockset::VisitCallExpr(const CallExpr *Exp) { void BuildLockset::VisitCXXConstructExpr(const CXXConstructExpr *Exp) { const CXXConstructorDecl *D = Exp->getConstructor(); if (D && D->isCopyConstructor()) { - const Expr* Source = Exp->getArg(0); + const Expr *Source = Exp->getArg(0); checkAccess(Source, AK_Read); } else { examineArguments(D, Exp->arg_begin(), Exp->arg_end()); @@ -2287,14 +2279,14 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { // to 'this', so checks on member variable access is disabled, but we should // still enable checks on other objects. if (isa(D)) - return; // Don't check inside constructors. + return; // Don't check inside constructors. if (isa(D)) - return; // Don't check inside destructors. + return; // Don't check inside destructors. Handler.enterFunction(CurrentFunction); BlockInfo.resize(CFGraph->getNumBlockIDs(), - CFGBlockInfo::getEmptyBlockInfo(LocalVarMap)); + CFGBlockInfo::getEmptyBlockInfo(LocalVarMap)); // We need to explore the CFG via a "topological" ordering. // That way, we will be guaranteed to have information about required @@ -2303,7 +2295,7 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph); CFGBlockInfo &Initial = BlockInfo[CFGraph->getEntry().getBlockID()]; - CFGBlockInfo &Final = BlockInfo[CFGraph->getExit().getBlockID()]; + CFGBlockInfo &Final = BlockInfo[CFGraph->getExit().getBlockID()]; // Mark entry block as reachable Initial.Reachable = true; @@ -2414,7 +2406,8 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { // all code paths. bool LocksetInitialized = false; for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(), - PE = CurrBlock->pred_end(); PI != PE; ++PI) { + PE = CurrBlock->pred_end(); + PI != PE; ++PI) { // if *PI -> CurrBlock is a back edge if (*PI == nullptr || !VisitedBlocks.alreadySet(*PI)) continue; @@ -2456,51 +2449,51 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { // Visit all the statements in the basic block. for (const auto &BI : *CurrBlock) { switch (BI.getKind()) { - case CFGElement::Statement: { - CFGStmt CS = BI.castAs(); - LocksetBuilder.Visit(CS.getStmt()); - break; - } - // Ignore BaseDtor and MemberDtor for now. - case CFGElement::AutomaticObjectDtor: { - CFGAutomaticObjDtor AD = BI.castAs(); - const auto *DD = AD.getDestructorDecl(AC.getASTContext()); - if (!DD->hasAttrs()) - break; - - LocksetBuilder.handleCall(nullptr, DD, - SxBuilder.createVariable(AD.getVarDecl()), - AD.getTriggerStmt()->getEndLoc()); + case CFGElement::Statement: { + CFGStmt CS = BI.castAs(); + LocksetBuilder.Visit(CS.getStmt()); + break; + } + // Ignore BaseDtor and MemberDtor for now. + case CFGElement::AutomaticObjectDtor: { + CFGAutomaticObjDtor AD = BI.castAs(); + const auto *DD = AD.getDestructorDecl(AC.getASTContext()); + if (!DD->hasAttrs()) break; - } - case CFGElement::CleanupFunction: { - const CFGCleanupFunction &CF = BI.castAs(); - LocksetBuilder.handleCall(/*Exp=*/nullptr, CF.getFunctionDecl(), - SxBuilder.createVariable(CF.getVarDecl()), - CF.getVarDecl()->getLocation()); - break; - } + LocksetBuilder.handleCall(nullptr, DD, + SxBuilder.createVariable(AD.getVarDecl()), + AD.getTriggerStmt()->getEndLoc()); + break; + } - case CFGElement::TemporaryDtor: { - auto TD = BI.castAs(); - - // Clean up constructed object even if there are no attributes to - // keep the number of objects in limbo as small as possible. - if (auto Object = ConstructedObjects.find( - TD.getBindTemporaryExpr()->getSubExpr()); - Object != ConstructedObjects.end()) { - const auto *DD = TD.getDestructorDecl(AC.getASTContext()); - if (DD->hasAttrs()) - // TODO: the location here isn't quite correct. - LocksetBuilder.handleCall(nullptr, DD, Object->second, - TD.getBindTemporaryExpr()->getEndLoc()); - ConstructedObjects.erase(Object); - } - break; + case CFGElement::CleanupFunction: { + const CFGCleanupFunction &CF = BI.castAs(); + LocksetBuilder.handleCall(/*Exp=*/nullptr, CF.getFunctionDecl(), + SxBuilder.createVariable(CF.getVarDecl()), + CF.getVarDecl()->getLocation()); + break; + } + + case CFGElement::TemporaryDtor: { + auto TD = BI.castAs(); + + // Clean up constructed object even if there are no attributes to + // keep the number of objects in limbo as small as possible. + if (auto Object = ConstructedObjects.find( + TD.getBindTemporaryExpr()->getSubExpr()); + Object != ConstructedObjects.end()) { + const auto *DD = TD.getDestructorDecl(AC.getASTContext()); + if (DD->hasAttrs()) + // TODO: the location here isn't quite correct. + LocksetBuilder.handleCall(nullptr, DD, Object->second, + TD.getBindTemporaryExpr()->getEndLoc()); + ConstructedObjects.erase(Object); } - default: - break; + break; + } + default: + break; } } CurrBlockInfo->ExitSet = LocksetBuilder.FSet; @@ -2510,7 +2503,8 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { // the one held at the beginning of FirstLoopBlock. We can look up the // Lockset held at the beginning of FirstLoopBlock in the EntryLockSets map. for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(), - SE = CurrBlock->succ_end(); SI != SE; ++SI) { + SE = CurrBlock->succ_end(); + SI != SE; ++SI) { // if CurrBlock -> *SI is *not* a back edge if (*SI == nullptr || !VisitedBlocks.alreadySet(*SI)) continue; @@ -2554,10 +2548,10 @@ void threadSafety::threadSafetyCleanup(BeforeSet *Cache) { delete Cache; } /// of access. LockKind threadSafety::getLockKindFromAccessKind(AccessKind AK) { switch (AK) { - case AK_Read : - return LK_Shared; - case AK_Written : - return LK_Exclusive; + case AK_Read: + return LK_Shared; + case AK_Written: + return LK_Exclusive; } llvm_unreachable("Unknown AccessKind"); } diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index 2fe0f85897c3b..7062e1f074767 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -40,23 +40,23 @@ using namespace threadSafety; // From ThreadSafetyUtil.h std::string threadSafety::getSourceLiteralString(const Expr *CE) { switch (CE->getStmtClass()) { - case Stmt::IntegerLiteralClass: - return toString(cast(CE)->getValue(), 10, true); - case Stmt::StringLiteralClass: { - std::string ret("\""); - ret += cast(CE)->getString(); - ret += "\""; - return ret; - } - case Stmt::CharacterLiteralClass: - case Stmt::CXXNullPtrLiteralExprClass: - case Stmt::GNUNullExprClass: - case Stmt::CXXBoolLiteralExprClass: - case Stmt::FloatingLiteralClass: - case Stmt::ImaginaryLiteralClass: - case Stmt::ObjCStringLiteralClass: - default: - return "#lit"; + case Stmt::IntegerLiteralClass: + return toString(cast(CE)->getValue(), 10, true); + case Stmt::StringLiteralClass: { + std::string ret("\""); + ret += cast(CE)->getString(); + ret += "\""; + return ret; + } + case Stmt::CharacterLiteralClass: + case Stmt::CXXNullPtrLiteralExprClass: + case Stmt::GNUNullExprClass: + case Stmt::CXXBoolLiteralExprClass: + case Stmt::FloatingLiteralClass: + case Stmt::ImaginaryLiteralClass: + case Stmt::ObjCStringLiteralClass: + default: + return "#lit"; } } @@ -127,18 +127,18 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, if (!DeclExp) /* We'll use Self. */; else if (const auto *ME = dyn_cast(DeclExp)) { - Ctx.SelfArg = ME->getBase(); + Ctx.SelfArg = ME->getBase(); Ctx.SelfArrow = ME->isArrow(); } else if (const auto *CE = dyn_cast(DeclExp)) { - Ctx.SelfArg = CE->getImplicitObjectArgument(); + Ctx.SelfArg = CE->getImplicitObjectArgument(); Ctx.SelfArrow = isCalleeArrow(CE->getCallee()); - Ctx.NumArgs = CE->getNumArgs(); - Ctx.FunArgs = CE->getArgs(); + Ctx.NumArgs = CE->getNumArgs(); + Ctx.FunArgs = CE->getArgs(); } else if (const auto *CE = dyn_cast(DeclExp)) { Ctx.NumArgs = CE->getNumArgs(); Ctx.FunArgs = CE->getArgs(); } else if (const auto *CE = dyn_cast(DeclExp)) { - Ctx.SelfArg = nullptr; // Will be set below + Ctx.SelfArg = nullptr; // Will be set below Ctx.NumArgs = CE->getNumArgs(); Ctx.FunArgs = CE->getArgs(); } @@ -158,14 +158,14 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, ClassifyDiagnostic( cast(D)->getFunctionObjectParameterType()), false); - else // For most attributes. + else // For most attributes. return translateAttrExpr(AttrExp, &Ctx); } // If the attribute has no arguments, then assume the argument is "this". if (!AttrExp) return translateAttrExpr(cast(Ctx.SelfArg), nullptr); - else // For most attributes. + else // For most attributes. return translateAttrExpr(AttrExp, &Ctx); } @@ -176,7 +176,7 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, if (!AttrExp) return CapabilityExpr(); - if (const auto* SLit = dyn_cast(AttrExp)) { + if (const auto *SLit = dyn_cast(AttrExp)) { if (SLit->getString() == StringRef("*")) // The "*" expr is a universal lock, which essentially turns off // checks until it is removed from the lockset. @@ -193,8 +193,7 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, Neg = true; AttrExp = OE->getArg(0); } - } - else if (const auto *UO = dyn_cast(AttrExp)) { + } else if (const auto *UO = dyn_cast(AttrExp)) { if (UO->getOpcode() == UO_LNot) { Neg = true; AttrExp = UO->getSubExpr(); @@ -264,11 +263,11 @@ til::SExpr *SExprBuilder::translate(const Stmt *S, CallingContext *Ctx) { case Stmt::ArraySubscriptExprClass: return translateArraySubscriptExpr(cast(S), Ctx); case Stmt::ConditionalOperatorClass: - return translateAbstractConditionalOperator( - cast(S), Ctx); + return translateAbstractConditionalOperator(cast(S), + Ctx); case Stmt::BinaryConditionalOperatorClass: return translateAbstractConditionalOperator( - cast(S), Ctx); + cast(S), Ctx); // We treat these as no-ops case Stmt::ConstantExprClass: @@ -381,7 +380,7 @@ static const CXXMethodDecl *getFirstVirtualDecl(const CXXMethodDecl *D) { D = D->getCanonicalDecl(); auto OverriddenMethods = D->overridden_methods(); if (OverriddenMethods.begin() == OverriddenMethods.end()) - return D; // Method does not override anything + return D; // Method does not override anything // FIXME: this does not work with multiple inheritance. D = *OverriddenMethods.begin(); } @@ -391,7 +390,7 @@ static const CXXMethodDecl *getFirstVirtualDecl(const CXXMethodDecl *D) { til::SExpr *SExprBuilder::translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx) { til::SExpr *BE = translate(ME->getBase(), Ctx); - til::SExpr *E = new (Arena) til::SApply(BE); + til::SExpr *E = new (Arena) til::SApply(BE); const auto *D = cast(ME->getMemberDecl()->getCanonicalDecl()); if (const auto *VD = dyn_cast(D)) @@ -443,8 +442,9 @@ til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE, return new (Arena) til::Call(E, CE); } -til::SExpr *SExprBuilder::translateCXXMemberCallExpr( - const CXXMemberCallExpr *ME, CallingContext *Ctx) { +til::SExpr * +SExprBuilder::translateCXXMemberCallExpr(const CXXMemberCallExpr *ME, + CallingContext *Ctx) { if (CapabilityExprMode) { // Ignore calls to get() on smart pointers. if (ME->getMethodDecl()->getNameAsString() == "get" && @@ -458,8 +458,9 @@ til::SExpr *SExprBuilder::translateCXXMemberCallExpr( ME->getImplicitObjectArgument()); } -til::SExpr *SExprBuilder::translateCXXOperatorCallExpr( - const CXXOperatorCallExpr *OCE, CallingContext *Ctx) { +til::SExpr * +SExprBuilder::translateCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE, + CallingContext *Ctx) { if (CapabilityExprMode) { // Ignore operator * and operator -> on smart pointers. OverloadedOperatorKind k = OCE->getOperator(); @@ -503,13 +504,13 @@ til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO, case UO_Minus: return new (Arena) - til::UnaryOp(til::UOP_Minus, translate(UO->getSubExpr(), Ctx)); + til::UnaryOp(til::UOP_Minus, translate(UO->getSubExpr(), Ctx)); case UO_Not: return new (Arena) - til::UnaryOp(til::UOP_BitNot, translate(UO->getSubExpr(), Ctx)); + til::UnaryOp(til::UOP_BitNot, translate(UO->getSubExpr(), Ctx)); case UO_LNot: return new (Arena) - til::UnaryOp(til::UOP_LogicNot, translate(UO->getSubExpr(), Ctx)); + til::UnaryOp(til::UOP_LogicNot, translate(UO->getSubExpr(), Ctx)); // Currently unsupported case UO_Real: @@ -524,18 +525,17 @@ til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO, til::SExpr *SExprBuilder::translateBinOp(til::TIL_BinaryOpcode Op, const BinaryOperator *BO, CallingContext *Ctx, bool Reverse) { - til::SExpr *E0 = translate(BO->getLHS(), Ctx); - til::SExpr *E1 = translate(BO->getRHS(), Ctx); - if (Reverse) - return new (Arena) til::BinaryOp(Op, E1, E0); - else - return new (Arena) til::BinaryOp(Op, E0, E1); + til::SExpr *E0 = translate(BO->getLHS(), Ctx); + til::SExpr *E1 = translate(BO->getRHS(), Ctx); + if (Reverse) + return new (Arena) til::BinaryOp(Op, E1, E0); + else + return new (Arena) til::BinaryOp(Op, E0, E1); } til::SExpr *SExprBuilder::translateBinAssign(til::TIL_BinaryOpcode Op, const BinaryOperator *BO, - CallingContext *Ctx, - bool Assign) { + CallingContext *Ctx, bool Assign) { const Expr *LHS = BO->getLHS(); const Expr *RHS = BO->getRHS(); til::SExpr *E0 = translate(LHS, Ctx); @@ -565,37 +565,67 @@ til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO, case BO_PtrMemI: return new (Arena) til::Undefined(BO); - case BO_Mul: return translateBinOp(til::BOP_Mul, BO, Ctx); - case BO_Div: return translateBinOp(til::BOP_Div, BO, Ctx); - case BO_Rem: return translateBinOp(til::BOP_Rem, BO, Ctx); - case BO_Add: return translateBinOp(til::BOP_Add, BO, Ctx); - case BO_Sub: return translateBinOp(til::BOP_Sub, BO, Ctx); - case BO_Shl: return translateBinOp(til::BOP_Shl, BO, Ctx); - case BO_Shr: return translateBinOp(til::BOP_Shr, BO, Ctx); - case BO_LT: return translateBinOp(til::BOP_Lt, BO, Ctx); - case BO_GT: return translateBinOp(til::BOP_Lt, BO, Ctx, true); - case BO_LE: return translateBinOp(til::BOP_Leq, BO, Ctx); - case BO_GE: return translateBinOp(til::BOP_Leq, BO, Ctx, true); - case BO_EQ: return translateBinOp(til::BOP_Eq, BO, Ctx); - case BO_NE: return translateBinOp(til::BOP_Neq, BO, Ctx); - case BO_Cmp: return translateBinOp(til::BOP_Cmp, BO, Ctx); - case BO_And: return translateBinOp(til::BOP_BitAnd, BO, Ctx); - case BO_Xor: return translateBinOp(til::BOP_BitXor, BO, Ctx); - case BO_Or: return translateBinOp(til::BOP_BitOr, BO, Ctx); - case BO_LAnd: return translateBinOp(til::BOP_LogicAnd, BO, Ctx); - case BO_LOr: return translateBinOp(til::BOP_LogicOr, BO, Ctx); - - case BO_Assign: return translateBinAssign(til::BOP_Eq, BO, Ctx, true); - case BO_MulAssign: return translateBinAssign(til::BOP_Mul, BO, Ctx); - case BO_DivAssign: return translateBinAssign(til::BOP_Div, BO, Ctx); - case BO_RemAssign: return translateBinAssign(til::BOP_Rem, BO, Ctx); - case BO_AddAssign: return translateBinAssign(til::BOP_Add, BO, Ctx); - case BO_SubAssign: return translateBinAssign(til::BOP_Sub, BO, Ctx); - case BO_ShlAssign: return translateBinAssign(til::BOP_Shl, BO, Ctx); - case BO_ShrAssign: return translateBinAssign(til::BOP_Shr, BO, Ctx); - case BO_AndAssign: return translateBinAssign(til::BOP_BitAnd, BO, Ctx); - case BO_XorAssign: return translateBinAssign(til::BOP_BitXor, BO, Ctx); - case BO_OrAssign: return translateBinAssign(til::BOP_BitOr, BO, Ctx); + case BO_Mul: + return translateBinOp(til::BOP_Mul, BO, Ctx); + case BO_Div: + return translateBinOp(til::BOP_Div, BO, Ctx); + case BO_Rem: + return translateBinOp(til::BOP_Rem, BO, Ctx); + case BO_Add: + return translateBinOp(til::BOP_Add, BO, Ctx); + case BO_Sub: + return translateBinOp(til::BOP_Sub, BO, Ctx); + case BO_Shl: + return translateBinOp(til::BOP_Shl, BO, Ctx); + case BO_Shr: + return translateBinOp(til::BOP_Shr, BO, Ctx); + case BO_LT: + return translateBinOp(til::BOP_Lt, BO, Ctx); + case BO_GT: + return translateBinOp(til::BOP_Lt, BO, Ctx, true); + case BO_LE: + return translateBinOp(til::BOP_Leq, BO, Ctx); + case BO_GE: + return translateBinOp(til::BOP_Leq, BO, Ctx, true); + case BO_EQ: + return translateBinOp(til::BOP_Eq, BO, Ctx); + case BO_NE: + return translateBinOp(til::BOP_Neq, BO, Ctx); + case BO_Cmp: + return translateBinOp(til::BOP_Cmp, BO, Ctx); + case BO_And: + return translateBinOp(til::BOP_BitAnd, BO, Ctx); + case BO_Xor: + return translateBinOp(til::BOP_BitXor, BO, Ctx); + case BO_Or: + return translateBinOp(til::BOP_BitOr, BO, Ctx); + case BO_LAnd: + return translateBinOp(til::BOP_LogicAnd, BO, Ctx); + case BO_LOr: + return translateBinOp(til::BOP_LogicOr, BO, Ctx); + + case BO_Assign: + return translateBinAssign(til::BOP_Eq, BO, Ctx, true); + case BO_MulAssign: + return translateBinAssign(til::BOP_Mul, BO, Ctx); + case BO_DivAssign: + return translateBinAssign(til::BOP_Div, BO, Ctx); + case BO_RemAssign: + return translateBinAssign(til::BOP_Rem, BO, Ctx); + case BO_AddAssign: + return translateBinAssign(til::BOP_Add, BO, Ctx); + case BO_SubAssign: + return translateBinAssign(til::BOP_Sub, BO, Ctx); + case BO_ShlAssign: + return translateBinAssign(til::BOP_Shl, BO, Ctx); + case BO_ShrAssign: + return translateBinAssign(til::BOP_Shr, BO, Ctx); + case BO_AndAssign: + return translateBinAssign(til::BOP_BitAnd, BO, Ctx); + case BO_XorAssign: + return translateBinAssign(til::BOP_BitXor, BO, Ctx); + case BO_OrAssign: + return translateBinAssign(til::BOP_BitOr, BO, Ctx); case BO_Comma: // The clang CFG should have already processed both sides. @@ -645,8 +675,7 @@ SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E, return new (Arena) til::ArrayIndex(E0, E1); } -til::SExpr * -SExprBuilder::translateAbstractConditionalOperator( +til::SExpr *SExprBuilder::translateAbstractConditionalOperator( const AbstractConditionalOperator *CO, CallingContext *Ctx) { auto *C = translate(CO->getCond(), Ctx); auto *T = translate(CO->getTrueExpr(), Ctx); @@ -654,13 +683,13 @@ SExprBuilder::translateAbstractConditionalOperator( return new (Arena) til::IfThenElse(C, T, E); } -til::SExpr * -SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) { +til::SExpr *SExprBuilder::translateDeclStmt(const DeclStmt *S, + CallingContext *Ctx) { DeclGroupRef DGrp = S->getDeclGroup(); for (auto *I : DGrp) { if (auto *VD = dyn_cast_or_null(I)) { Expr *E = VD->getInit(); - til::SExpr* SE = translate(E, Ctx); + til::SExpr *SE = translate(E, Ctx); // Add local variables with trivial type to the variable map QualType T = VD->getType(); @@ -678,7 +707,7 @@ SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) { // update the statement map so that S refers to E. Returns a new variable // that refers to E. // If E is trivial returns E. -til::SExpr *SExprBuilder::addStatement(til::SExpr* E, const Stmt *S, +til::SExpr *SExprBuilder::addStatement(til::SExpr *E, const Stmt *S, const ValueDecl *VD) { if (!E || !CurrentBB || E->block() || til::ThreadSafetyTIL::isTrivial(E)) return E; @@ -725,7 +754,7 @@ til::SExpr *SExprBuilder::updateVarDecl(const ValueDecl *VD, til::SExpr *E) { auto It = LVarIdxMap.find(VD); if (It == LVarIdxMap.end()) { til::SExpr *Ptr = new (Arena) til::LiteralPtr(VD); - til::SExpr *St = new (Arena) til::Store(Ptr, E); + til::SExpr *St = new (Arena) til::Store(Ptr, E); return St; } CurrentLVarMap.makeWritable(); @@ -785,12 +814,12 @@ void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) { return; } if (CurrentLVarMap.sameAs(Map)) - return; // Easy merge: maps from different predecessors are unchanged. + return; // Easy merge: maps from different predecessors are unchanged. unsigned NPreds = CurrentBB->numPredecessors(); unsigned ESz = CurrentLVarMap.size(); unsigned MSz = Map.size(); - unsigned Sz = std::min(ESz, MSz); + unsigned Sz = std::min(ESz, MSz); for (unsigned i = 0; i < Sz; ++i) { if (CurrentLVarMap[i].first != Map[i].first) { @@ -880,7 +909,7 @@ void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D, // FIXME: right now we emulate params with loads; that should be fixed. til::SExpr *Lp = new (Arena) til::LiteralPtr(Pm); til::SExpr *Ld = new (Arena) til::Load(Lp); - til::SExpr *V = addStatement(Ld, nullptr, Pm); + til::SExpr *V = addStatement(Ld, nullptr, Pm); addVarDecl(Pm, V); } } @@ -920,8 +949,8 @@ void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) { void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) { // The merge*() methods have created arguments. // Push those arguments onto the basic block. - CurrentBB->arguments().reserve( - static_cast(CurrentArguments.size()), Arena); + CurrentBB->arguments().reserve(static_cast(CurrentArguments.size()), + Arena); for (auto *A : CurrentArguments) CurrentBB->addArgument(A); } @@ -942,7 +971,7 @@ void SExprBuilder::handleDestructorCall(const VarDecl *VD, void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) { CurrentBB->instructions().reserve( - static_cast(CurrentInstructions.size()), Arena); + static_cast(CurrentInstructions.size()), Arena); for (auto *V : CurrentInstructions) CurrentBB->addInstruction(V); @@ -955,8 +984,7 @@ void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) { unsigned Idx = BB ? BB->findPredecessorIndex(CurrentBB) : 0; auto *Tm = new (Arena) til::Goto(BB, Idx); CurrentBB->setTerminator(Tm); - } - else if (N == 2) { + } else if (N == 2) { til::SExpr *C = translate(B->getTerminatorCondition(true), nullptr); til::BasicBlock *BB1 = *It ? lookupBlock(*It) : nullptr; ++It; diff --git a/clang/lib/Analysis/ThreadSafetyLogical.cpp b/clang/lib/Analysis/ThreadSafetyLogical.cpp index ac730770093e4..c1e1d23f5ab55 100644 --- a/clang/lib/Analysis/ThreadSafetyLogical.cpp +++ b/clang/lib/Analysis/ThreadSafetyLogical.cpp @@ -106,6 +106,6 @@ bool implies(const LExpr *LHS, const LExpr *RHS) { // Start out by assuming that LHS and RHS are not negated. return ::implies(LHS, false, RHS, false); } -} -} -} +} // namespace lexpr +} // namespace threadSafety +} // namespace clang diff --git a/clang/lib/Analysis/ThreadSafetyTIL.cpp b/clang/lib/Analysis/ThreadSafetyTIL.cpp index 652f953d2a6db..b9642e904e6dc 100644 --- a/clang/lib/Analysis/ThreadSafetyTIL.cpp +++ b/clang/lib/Analysis/ThreadSafetyTIL.cpp @@ -18,37 +18,57 @@ using namespace til; StringRef til::getUnaryOpcodeString(TIL_UnaryOpcode Op) { switch (Op) { - case UOP_Minus: return "-"; - case UOP_BitNot: return "~"; - case UOP_LogicNot: return "!"; + case UOP_Minus: + return "-"; + case UOP_BitNot: + return "~"; + case UOP_LogicNot: + return "!"; } return {}; } StringRef til::getBinaryOpcodeString(TIL_BinaryOpcode Op) { switch (Op) { - case BOP_Mul: return "*"; - case BOP_Div: return "/"; - case BOP_Rem: return "%"; - case BOP_Add: return "+"; - case BOP_Sub: return "-"; - case BOP_Shl: return "<<"; - case BOP_Shr: return ">>"; - case BOP_BitAnd: return "&"; - case BOP_BitXor: return "^"; - case BOP_BitOr: return "|"; - case BOP_Eq: return "=="; - case BOP_Neq: return "!="; - case BOP_Lt: return "<"; - case BOP_Leq: return "<="; - case BOP_Cmp: return "<=>"; - case BOP_LogicAnd: return "&&"; - case BOP_LogicOr: return "||"; + case BOP_Mul: + return "*"; + case BOP_Div: + return "/"; + case BOP_Rem: + return "%"; + case BOP_Add: + return "+"; + case BOP_Sub: + return "-"; + case BOP_Shl: + return "<<"; + case BOP_Shr: + return ">>"; + case BOP_BitAnd: + return "&"; + case BOP_BitXor: + return "^"; + case BOP_BitOr: + return "|"; + case BOP_Eq: + return "=="; + case BOP_Neq: + return "!="; + case BOP_Lt: + return "<"; + case BOP_Leq: + return "<="; + case BOP_Cmp: + return "<=>"; + case BOP_LogicAnd: + return "&&"; + case BOP_LogicOr: + return "||"; } return {}; } -SExpr* Future::force() { +SExpr *Future::force() { Status = FS_evaluating; Result = compute(); Status = FS_done; @@ -140,9 +160,9 @@ void til::simplifyIncompleteArg(til::Phi *Ph) { for (unsigned i = 1, n = Ph->values().size(); i < n; ++i) { SExpr *Ei = simplifyToCanonicalVal(Ph->values()[i]); if (Ei == Ph) - continue; // Recursive reference to itself. Don't count. + continue; // Recursive reference to itself. Don't count. if (Ei != E0) { - return; // Status is already set to MultiVal. + return; // Status is already set to MultiVal. } } Ph->setStatus(Phi::PH_SingleVal); @@ -164,7 +184,8 @@ unsigned BasicBlock::renumberInstrs(unsigned ID) { // block, and ID should be the total number of blocks. unsigned BasicBlock::topologicalSort(SimpleArray &Blocks, unsigned ID) { - if (Visited) return ID; + if (Visited) + return ID; Visited = true; for (auto *Block : successors()) ID = Block->topologicalSort(Blocks, ID); @@ -190,7 +211,8 @@ unsigned BasicBlock::topologicalFinalSort(SimpleArray &Blocks, unsigned ID) { // Visited is assumed to have been set by the topologicalSort. This pass // assumes !Visited means that we've visited this node before. - if (!Visited) return ID; + if (!Visited) + return ID; Visited = false; if (DominatorNode.Parent) ID = DominatorNode.Parent->topologicalFinalSort(Blocks, ID); @@ -210,7 +232,8 @@ void BasicBlock::computeDominator() { // Walk backwards from each predecessor to find the common dominator node. for (auto *Pred : Predecessors) { // Skip back-edges - if (Pred->BlockID >= BlockID) continue; + if (Pred->BlockID >= BlockID) + continue; // If we don't yet have a candidate for dominator yet, take this one. if (Candidate == nullptr) { Candidate = Pred; @@ -237,7 +260,8 @@ void BasicBlock::computePostDominator() { // Walk back from each predecessor to find the common post-dominator node. for (auto *Succ : successors()) { // Skip back-edges - if (Succ->BlockID <= BlockID) continue; + if (Succ->BlockID <= BlockID) + continue; // If we don't yet have a candidate for post-dominator yet, take this one. if (Candidate == nullptr) { Candidate = Succ; @@ -279,7 +303,7 @@ static inline void computeNodeID(BasicBlock *B, BasicBlock::TopologyNode *N = &(B->*TN); if (N->Parent) { BasicBlock::TopologyNode *P = &(N->Parent->*TN); - N->NodeID += P->NodeID; // Fix NodeIDs relative to starting node. + N->NodeID += P->NodeID; // Fix NodeIDs relative to starting node. } } @@ -308,7 +332,7 @@ void SCFG::computeNormalForm() { // Once dominators have been computed, the final sort may be performed. unsigned NumBlocks = Exit->topologicalFinalSort(Blocks, 0); assert(static_cast(NumBlocks) == Blocks.size()); - (void) NumBlocks; + (void)NumBlocks; // Renumber the instructions now that we have a final sort. renumberInstrs(); diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp index e9111ded64eb1..2788a48738276 100644 --- a/clang/lib/Analysis/UninitializedValues.cpp +++ b/clang/lib/Analysis/UninitializedValues.cpp @@ -64,7 +64,8 @@ static bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) { QualType ty = vd->getType(); if (const auto *RD = ty->getAsRecordDecl()) return recordIsNotEmpty(RD); - return ty->isScalarType() || ty->isVectorType() || ty->isRVVSizelessBuiltinType(); + return ty->isScalarType() || ty->isVectorType() || + ty->isRVVSizelessBuiltinType(); } return false; } @@ -96,8 +97,8 @@ class DeclToIndex { void DeclToIndex::computeMap(const DeclContext &dc) { unsigned count = 0; DeclContext::specific_decl_iterator I(dc.decls_begin()), - E(dc.decls_end()); - for ( ; I != E; ++I) { + E(dc.decls_end()); + for (; I != E; ++I) { const VarDecl *vd = *I; if (isTrackedVar(vd, &dc)) map[vd] = count++; @@ -117,18 +118,16 @@ std::optional DeclToIndex::getValueIndex(const VarDecl *d) const { // These values are defined in such a way that a merge can be done using // a bitwise OR. -enum Value { Unknown = 0x0, /* 00 */ - Initialized = 0x1, /* 01 */ - Uninitialized = 0x2, /* 10 */ - MayUninitialized = 0x3 /* 11 */ }; +enum Value { + Unknown = 0x0, /* 00 */ + Initialized = 0x1, /* 01 */ + Uninitialized = 0x2, /* 10 */ + MayUninitialized = 0x3 /* 11 */ +}; -static bool isUninitialized(const Value v) { - return v >= Uninitialized; -} +static bool isUninitialized(const Value v) { return v >= Uninitialized; } -static bool isAlwaysUninit(const Value v) { - return v == Uninitialized; -} +static bool isAlwaysUninit(const Value v) { return v == Uninitialized; } namespace { @@ -155,9 +154,7 @@ class CFGBlockValues { void mergeIntoScratch(ValueVector const &source, bool isFirst); bool updateValueVectorWithScratch(const CFGBlock *block); - bool hasNoDeclarations() const { - return declToIndex.size() == 0; - } + bool hasNoDeclarations() const { return declToIndex.size() == 0; } void resetScratch(); @@ -187,8 +184,7 @@ void CFGBlockValues::computeSetOfDeclarations(const DeclContext &dc) { } #if DEBUG_LOGGING -static void printVector(const CFGBlock *block, ValueVector &bv, - unsigned num) { +static void printVector(const CFGBlock *block, ValueVector &bv, unsigned num) { llvm::errs() << block->getBlockID() << " :"; for (const auto &i : bv) llvm::errs() << ' ' << i; @@ -201,8 +197,7 @@ void CFGBlockValues::setAllScratchValues(Value V) { scratch[I] = V; } -void CFGBlockValues::mergeIntoScratch(ValueVector const &source, - bool isFirst) { +void CFGBlockValues::mergeIntoScratch(ValueVector const &source, bool isFirst) { if (isFirst) scratch = source; else @@ -220,9 +215,7 @@ bool CFGBlockValues::updateValueVectorWithScratch(const CFGBlock *block) { return changed; } -void CFGBlockValues::resetScratch() { - scratch.reset(); -} +void CFGBlockValues::resetScratch() { scratch.reset(); } ValueVector::reference CFGBlockValues::operator[](const VarDecl *vd) { return scratch[*declToIndex.getValueIndex(vd)]; @@ -279,21 +272,13 @@ namespace { /// escaped the analysis and will be treated as an initialization. class ClassifyRefs : public StmtVisitor { public: - enum Class { - Init, - Use, - SelfInit, - ConstRefUse, - Ignore - }; + enum Class { Init, Use, SelfInit, ConstRefUse, Ignore }; private: const DeclContext *DC; llvm::DenseMap Classification; - bool isTrackedVar(const VarDecl *VD) const { - return ::isTrackedVar(VD, DC); - } + bool isTrackedVar(const VarDecl *VD) const { return ::isTrackedVar(VD, DC); } void classify(const Expr *E, Class C); @@ -310,8 +295,8 @@ class ClassifyRefs : public StmtVisitor { void operator()(Stmt *S) { Visit(S); } Class get(const DeclRefExpr *DRE) const { - llvm::DenseMap::const_iterator I - = Classification.find(DRE); + llvm::DenseMap::const_iterator I = + Classification.find(DRE); if (I != Classification.end()) return I->second; @@ -443,8 +428,8 @@ void ClassifyRefs::VisitCallExpr(CallExpr *CE) { // conservatively do not assume that it is used. // If a value is passed by const reference to a function, // it should already be initialized. - for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); - I != E; ++I) { + for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); I != E; + ++I) { if ((*I)->isGLValue()) { if ((*I)->getType().isConstQualified()) classify((*I), isTrivialBody ? Ignore : ConstRefUse); @@ -487,9 +472,8 @@ class TransferFunctions : public StmtVisitor { UninitVariablesHandler &handler; public: - TransferFunctions(CFGBlockValues &vals, const CFG &cfg, - const CFGBlock *block, AnalysisDeclContext &ac, - const ClassifyRefs &classification, + TransferFunctions(CFGBlockValues &vals, const CFG &cfg, const CFGBlock *block, + AnalysisDeclContext &ac, const ClassifyRefs &classification, UninitVariablesHandler &handler) : vals(vals), cfg(cfg), block(block), ac(ac), classification(classification), objCNoRet(ac.getASTContext()), @@ -569,7 +553,7 @@ class TransferFunctions : public StmtVisitor { // 'n' is definitely uninitialized for two edges into block 7 (from blocks 2 // and 4), so we report that any time either of those edges is taken (in // each case when 'b == false'), 'n' is used uninitialized. - SmallVector Queue; + SmallVector Queue; SmallVector SuccsVisited(cfg.getNumBlockIDs(), 0); Queue.push_back(block); // Specify that we've already visited all successors of the starting block. @@ -633,7 +617,8 @@ class TransferFunctions : public StmtVisitor { // to a post-dominator block, and the variable is uninitialized on that // edge, we have found a bug. for (CFGBlock::const_succ_iterator I = Block->succ_begin(), - E = Block->succ_end(); I != E; ++I) { + E = Block->succ_end(); + I != E; ++I) { const CFGBlock *Succ = *I; if (Succ && SuccsVisited[Succ->getBlockID()] >= Succ->succ_size() && vals.getValue(Block, Succ, vd) == Uninitialized) { @@ -721,8 +706,7 @@ void TransferFunctions::VisitCallExpr(CallExpr *ce) { // mark variables as initialized if they have an initializer which is // reachable from here. vals.setAllScratchValues(Initialized); - } - else if (Callee->hasAttr()) { + } else if (Callee->hasAttr()) { // Functions labeled like "analyzer_noreturn" are often used to denote // "panic" functions that in special debug situations can still return, // but for the most part should not be treated as returning. This is a @@ -843,7 +827,8 @@ static bool runOnBlock(const CFGBlock *block, const CFG &cfg, // Merge in values of predecessor blocks. bool isFirst = true; for (CFGBlock::const_pred_iterator I = block->pred_begin(), - E = block->pred_end(); I != E; ++I) { + E = block->pred_end(); + I != E; ++I) { const CFGBlock *pred = *I; if (!pred) continue; @@ -909,11 +894,8 @@ struct PruneBlocksHandler : public UninitVariablesHandler { } // namespace void clang::runUninitializedVariablesAnalysis( - const DeclContext &dc, - const CFG &cfg, - AnalysisDeclContext &ac, - UninitVariablesHandler &handler, - UninitVariablesAnalysisStats &stats) { + const DeclContext &dc, const CFG &cfg, AnalysisDeclContext &ac, + UninitVariablesHandler &handler, UninitVariablesAnalysisStats &stats) { CFGBlockValues vals(cfg); vals.computeSetOfDeclarations(dc); if (vals.hasNoDeclarations()) @@ -945,8 +927,8 @@ void clang::runUninitializedVariablesAnalysis( PBH.currentBlock = block->getBlockID(); // Did the block change? - bool changed = runOnBlock(block, cfg, ac, vals, - classification, wasAnalyzed, PBH); + bool changed = + runOnBlock(block, cfg, ac, vals, classification, wasAnalyzed, PBH); ++stats.NumBlockVisits; if (changed || !previouslyVisited[block->getBlockID()]) worklist.enqueueSuccessors(block); diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index 701f1ac852c25..e31dd0f0f511d 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -130,42 +130,42 @@ class MatchDescendantVisitor bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) { // These are unevaluated, except the result expression. - if(ignoreUnevaluatedContext) + if (ignoreUnevaluatedContext) return TraverseStmt(Node->getResultExpr()); return VisitorBase::TraverseGenericSelectionExpr(Node); } bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) { // Unevaluated context. - if(ignoreUnevaluatedContext) + if (ignoreUnevaluatedContext) return true; return VisitorBase::TraverseUnaryExprOrTypeTraitExpr(Node); } bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) { // Unevaluated context. - if(ignoreUnevaluatedContext) + if (ignoreUnevaluatedContext) return true; return VisitorBase::TraverseTypeOfExprTypeLoc(Node); } bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) { // Unevaluated context. - if(ignoreUnevaluatedContext) + if (ignoreUnevaluatedContext) return true; return VisitorBase::TraverseDecltypeTypeLoc(Node); } bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) { // Unevaluated context. - if(ignoreUnevaluatedContext) + if (ignoreUnevaluatedContext) return true; return VisitorBase::TraverseCXXNoexceptExpr(Node); } bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) { // Unevaluated context. - if(ignoreUnevaluatedContext) + if (ignoreUnevaluatedContext) return true; return VisitorBase::TraverseCXXTypeidExpr(Node); } @@ -213,24 +213,26 @@ class MatchDescendantVisitor // Because we're dealing with raw pointers, let's define what we mean by that. static auto hasPointerType() { - return hasType(hasCanonicalType(pointerType())); + return hasType(hasCanonicalType(pointerType())); } -static auto hasArrayType() { - return hasType(hasCanonicalType(arrayType())); -} +static auto hasArrayType() { return hasType(hasCanonicalType(arrayType())); } -AST_MATCHER_P(Stmt, forEachDescendantEvaluatedStmt, internal::Matcher, innerMatcher) { +AST_MATCHER_P(Stmt, forEachDescendantEvaluatedStmt, internal::Matcher, + innerMatcher) { const DynTypedMatcher &DTM = static_cast(innerMatcher); - MatchDescendantVisitor Visitor(&DTM, Finder, Builder, ASTMatchFinder::BK_All, true); + MatchDescendantVisitor Visitor(&DTM, Finder, Builder, ASTMatchFinder::BK_All, + true); return Visitor.findMatch(DynTypedNode::create(Node)); } -AST_MATCHER_P(Stmt, forEachDescendantStmt, internal::Matcher, innerMatcher) { +AST_MATCHER_P(Stmt, forEachDescendantStmt, internal::Matcher, + innerMatcher) { const DynTypedMatcher &DTM = static_cast(innerMatcher); - MatchDescendantVisitor Visitor(&DTM, Finder, Builder, ASTMatchFinder::BK_All, false); + MatchDescendantVisitor Visitor(&DTM, Finder, Builder, ASTMatchFinder::BK_All, + false); return Visitor.findMatch(DynTypedNode::create(Node)); } @@ -268,10 +270,9 @@ static auto isInUnspecifiedLvalueContext(internal::Matcher innerMatcher) { hasLHS(innerMatcher) ) )); -// clang-format on + // clang-format on } - // Returns a matcher that matches any expression `e` such that `InnerMatcher` // matches `e` and `e` is in an Unspecified Pointer Context (UPC). static internal::Matcher @@ -315,7 +316,7 @@ isInUnspecifiedPointerContext(internal::Matcher InnerMatcher) { // clang-format on return stmt(anyOf(CallArgMatcher, CastOperandMatcher, CompOperandMatcher, - PtrSubtractionMatcher)); + PtrSubtractionMatcher)); // FIXME: any more cases? (UPC excludes the RHS of an assignment. For now we // don't have to check that.) } @@ -481,7 +482,9 @@ class Gadget { #ifndef NDEBUG StringRef getDebugName() const { switch (K) { -#define GADGET(x) case Kind::x: return #x; +#define GADGET(x) \ + case Kind::x: \ + return #x; #include "clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def" } llvm_unreachable("Unhandled Gadget::Kind enum"); @@ -502,7 +505,6 @@ class Gadget { Kind K; }; - /// Warning gadgets correspond to unsafe code patterns that warrants /// an immediate warning. class WarningGadget : public Gadget { @@ -513,10 +515,10 @@ class WarningGadget : public Gadget { bool isWarningGadget() const final { return true; } }; -/// Fixable gadgets correspond to code patterns that aren't always unsafe but need to be -/// properly recognized in order to emit fixes. For example, if a raw pointer-type -/// variable is replaced by a safe C++ container, every use of such variable must be -/// carefully considered and possibly updated. +/// Fixable gadgets correspond to code patterns that aren't always unsafe but +/// need to be properly recognized in order to emit fixes. For example, if a raw +/// pointer-type variable is replaced by a safe C++ container, every use of such +/// variable must be carefully considered and possibly updated. class FixableGadget : public Gadget { public: FixableGadget(Kind K) : Gadget(K) {} @@ -531,20 +533,19 @@ class FixableGadget : public Gadget { return std::nullopt; } - /// Returns a list of two elements where the first element is the LHS of a pointer assignment - /// statement and the second element is the RHS. This two-element list represents the fact that - /// the LHS buffer gets its bounds information from the RHS buffer. This information will be used - /// later to group all those variables whose types must be modified together to prevent type - /// mismatches. + /// Returns a list of two elements where the first element is the LHS of a + /// pointer assignment statement and the second element is the RHS. This + /// two-element list represents the fact that the LHS buffer gets its bounds + /// information from the RHS buffer. This information will be used later to + /// group all those variables whose types must be modified together to prevent + /// type mismatches. virtual std::optional> getStrategyImplications() const { return std::nullopt; } }; -static auto toSupportedVariable() { - return to(varDecl()); -} +static auto toSupportedVariable() { return to(varDecl()); } using FixableGadgetList = std::vector>; using WarningGadgetList = std::vector>; @@ -565,10 +566,10 @@ class IncrementGadget : public WarningGadget { } static Matcher matcher() { - return stmt(unaryOperator( - hasOperatorName("++"), - hasUnaryOperand(ignoringParenImpCasts(hasPointerType())) - ).bind(OpTag)); + return stmt( + unaryOperator(hasOperatorName("++"), + hasUnaryOperand(ignoringParenImpCasts(hasPointerType()))) + .bind(OpTag)); } const UnaryOperator *getBaseStmt() const override { return Op; } @@ -600,10 +601,10 @@ class DecrementGadget : public WarningGadget { } static Matcher matcher() { - return stmt(unaryOperator( - hasOperatorName("--"), - hasUnaryOperand(ignoringParenImpCasts(hasPointerType())) - ).bind(OpTag)); + return stmt( + unaryOperator(hasOperatorName("--"), + hasUnaryOperand(ignoringParenImpCasts(hasPointerType()))) + .bind(OpTag)); } const UnaryOperator *getBaseStmt() const override { return Op; } @@ -754,26 +755,25 @@ class PointerInitGadget : public FixableGadget { private: static constexpr const char *const PointerInitLHSTag = "ptrInitLHS"; static constexpr const char *const PointerInitRHSTag = "ptrInitRHS"; - const VarDecl * PtrInitLHS; // the LHS pointer expression in `PI` - const DeclRefExpr * PtrInitRHS; // the RHS pointer expression in `PI` + const VarDecl *PtrInitLHS; // the LHS pointer expression in `PI` + const DeclRefExpr *PtrInitRHS; // the RHS pointer expression in `PI` public: PointerInitGadget(const MatchFinder::MatchResult &Result) : FixableGadget(Kind::PointerInit), - PtrInitLHS(Result.Nodes.getNodeAs(PointerInitLHSTag)), - PtrInitRHS(Result.Nodes.getNodeAs(PointerInitRHSTag)) {} + PtrInitLHS(Result.Nodes.getNodeAs(PointerInitLHSTag)), + PtrInitRHS(Result.Nodes.getNodeAs(PointerInitRHSTag)) {} static bool classof(const Gadget *G) { return G->getKind() == Kind::PointerInit; } static Matcher matcher() { - auto PtrInitStmt = declStmt(hasSingleDecl(varDecl( - hasInitializer(ignoringImpCasts(declRefExpr( - hasPointerType(), - toSupportedVariable()). - bind(PointerInitRHSTag)))). - bind(PointerInitLHSTag))); + auto PtrInitStmt = declStmt(hasSingleDecl( + varDecl(hasInitializer(ignoringImpCasts( + declRefExpr(hasPointerType(), toSupportedVariable()) + .bind(PointerInitRHSTag)))) + .bind(PointerInitLHSTag))); return stmt(PtrInitStmt); } @@ -793,8 +793,7 @@ class PointerInitGadget : public FixableGadget { virtual std::optional> getStrategyImplications() const override { - return std::make_pair(PtrInitLHS, - cast(PtrInitRHS->getDecl())); + return std::make_pair(PtrInitLHS, cast(PtrInitRHS->getDecl())); } }; @@ -807,8 +806,8 @@ class PtrToPtrAssignmentGadget : public FixableGadget { private: static constexpr const char *const PointerAssignLHSTag = "ptrLHS"; static constexpr const char *const PointerAssignRHSTag = "ptrRHS"; - const DeclRefExpr * PtrLHS; // the LHS pointer expression in `PA` - const DeclRefExpr * PtrRHS; // the RHS pointer expression in `PA` + const DeclRefExpr *PtrLHS; // the LHS pointer expression in `PA` + const DeclRefExpr *PtrRHS; // the RHS pointer expression in `PA` public: PtrToPtrAssignmentGadget(const MatchFinder::MatchResult &Result) @@ -821,13 +820,13 @@ class PtrToPtrAssignmentGadget : public FixableGadget { } static Matcher matcher() { - auto PtrAssignExpr = binaryOperator(allOf(hasOperatorName("="), - hasRHS(ignoringParenImpCasts(declRefExpr(hasPointerType(), - toSupportedVariable()). - bind(PointerAssignRHSTag))), - hasLHS(declRefExpr(hasPointerType(), - toSupportedVariable()). - bind(PointerAssignLHSTag)))); + auto PtrAssignExpr = binaryOperator( + allOf(hasOperatorName("="), + hasRHS(ignoringParenImpCasts( + declRefExpr(hasPointerType(), toSupportedVariable()) + .bind(PointerAssignRHSTag))), + hasLHS(declRefExpr(hasPointerType(), toSupportedVariable()) + .bind(PointerAssignLHSTag)))); return stmt(isInUnspecifiedUntypedContext(PtrAssignExpr)); } @@ -981,9 +980,8 @@ class ULCArraySubscriptGadget : public FixableGadget { static Matcher matcher() { auto ArrayOrPtr = anyOf(hasPointerType(), hasArrayType()); - auto BaseIsArrayOrPtrDRE = - hasBase(ignoringParenImpCasts(declRefExpr(ArrayOrPtr, - toSupportedVariable()))); + auto BaseIsArrayOrPtrDRE = hasBase( + ignoringParenImpCasts(declRefExpr(ArrayOrPtr, toSupportedVariable()))); auto Target = arraySubscriptExpr(BaseIsArrayOrPtrDRE).bind(ULCArraySubscriptTag); @@ -1025,9 +1023,9 @@ class UPCStandalonePointerGadget : public FixableGadget { static Matcher matcher() { auto ArrayOrPtr = anyOf(hasPointerType(), hasArrayType()); - auto target = expr( - ignoringParenImpCasts(declRefExpr(allOf(ArrayOrPtr, - toSupportedVariable())).bind(DeclRefExprTag))); + auto target = expr(ignoringParenImpCasts( + declRefExpr(allOf(ArrayOrPtr, toSupportedVariable())) + .bind(DeclRefExprTag))); return stmt(isInUnspecifiedPointerContext(target)); } @@ -1036,9 +1034,7 @@ class UPCStandalonePointerGadget : public FixableGadget { virtual const Stmt *getBaseStmt() const override { return Node; } - virtual DeclUseList getClaimedVarUseSites() const override { - return {Node}; - } + virtual DeclUseList getClaimedVarUseSites() const override { return {Node}; } }; class PointerDereferenceGadget : public FixableGadget { @@ -1103,10 +1099,10 @@ class UPCAddressofArraySubscriptGadget : public FixableGadget { static Matcher matcher() { return expr(isInUnspecifiedPointerContext(expr(ignoringImpCasts( - unaryOperator(hasOperatorName("&"), - hasUnaryOperand(arraySubscriptExpr( - hasBase(ignoringParenImpCasts(declRefExpr( - toSupportedVariable())))))) + unaryOperator( + hasOperatorName("&"), + hasUnaryOperand(arraySubscriptExpr(hasBase( + ignoringParenImpCasts(declRefExpr(toSupportedVariable())))))) .bind(UPCAddressofArraySubscriptTag))))); } @@ -1195,13 +1191,13 @@ class DeclUseTracker { class UPCPreIncrementGadget : public FixableGadget { private: static constexpr const char *const UPCPreIncrementTag = - "PointerPreIncrementUnderUPC"; + "PointerPreIncrementUnderUPC"; const UnaryOperator *Node; // the `++Ptr` node public: UPCPreIncrementGadget(const MatchFinder::MatchResult &Result) - : FixableGadget(Kind::UPCPreIncrement), - Node(Result.Nodes.getNodeAs(UPCPreIncrementTag)) { + : FixableGadget(Kind::UPCPreIncrement), + Node(Result.Nodes.getNodeAs(UPCPreIncrementTag)) { assert(Node != nullptr && "Expecting a non-null matching result"); } @@ -1215,10 +1211,9 @@ class UPCPreIncrementGadget : public FixableGadget { // can have the matcher be general, so long as `getClaimedVarUseSites` does // things right. return stmt(isInUnspecifiedPointerContext(expr(ignoringImpCasts( - unaryOperator(isPreInc(), - hasUnaryOperand(declRefExpr( - toSupportedVariable())) - ).bind(UPCPreIncrementTag))))); + unaryOperator(isPreInc(), + hasUnaryOperand(declRefExpr(toSupportedVariable()))) + .bind(UPCPreIncrementTag))))); } virtual std::optional @@ -1782,9 +1777,9 @@ static SourceRange getSourceRangeToTokenEnd(const Decl *D, const LangOptions &LangOpts) { SourceLocation Begin = D->getBeginLoc(); SourceLocation - End = // `D->getEndLoc` should always return the starting location of the - // last token, so we should get the end of the token - Lexer::getLocForEndOfToken(D->getEndLoc(), 0, SM, LangOpts); + End = // `D->getEndLoc` should always return the starting location of the + // last token, so we should get the end of the token + Lexer::getLocForEndOfToken(D->getEndLoc(), 0, SM, LangOpts); return SourceRange(Begin, End); } @@ -1976,7 +1971,7 @@ PointerDereferenceGadget::getFixits(const FixitStrategy &S) const { if (auto LocPastOperand = getPastLoc(BaseDeclRefExpr, SM, Ctx.getLangOpts())) { return FixItList{{FixItHint::CreateRemoval(derefRange), - FixItHint::CreateInsertion(*LocPastOperand, "[0]")}}; + FixItHint::CreateInsertion(*LocPastOperand, "[0]")}}; } break; } @@ -2057,8 +2052,8 @@ fixUPCAddressofArraySubscriptWithSpan(const UnaryOperator *Node) { if (!IndexString) return std::nullopt; - SS << "&" << (*DreString).str() << ".data()" - << "[" << (*IndexString).str() << "]"; + SS << "&" << (*DreString).str() << ".data()" << "[" << (*IndexString).str() + << "]"; } return FixItList{ FixItHint::CreateReplacement(Node->getSourceRange(), SS.str())}; @@ -2162,7 +2157,8 @@ FixVarInitializerWithSpan(const Expr *Init, ASTContext &Ctx, // NULL pointer, we use the default constructor to initialize the span // object, i.e., a `std:span` variable declaration with no initializer. // So the fix-it is just to remove the initializer. - if (Init->isNullPointerConstant(Ctx, + if (Init->isNullPointerConstant( + Ctx, // FIXME: Why does this function not ask for `const ASTContext // &`? It should. Maybe worth an NFC patch later. Expr::NullPointerConstantValueDependence:: @@ -2230,8 +2226,10 @@ FixVarInitializerWithSpan(const Expr *Init, ASTContext &Ctx, } #ifndef NDEBUG -#define DEBUG_NOTE_DECL_FAIL(D, Msg) \ -Handler.addDebugNoteForVar((D), (D)->getBeginLoc(), "failed to produce fixit for declaration '" + (D)->getNameAsString() + "'" + (Msg)) +#define DEBUG_NOTE_DECL_FAIL(D, Msg) \ + Handler.addDebugNoteForVar((D), (D)->getBeginLoc(), \ + "failed to produce fixit for declaration '" + \ + (D)->getNameAsString() + "'" + (Msg)) #else #define DEBUG_NOTE_DECL_FAIL(D, Msg) #endif @@ -2239,8 +2237,8 @@ Handler.addDebugNoteForVar((D), (D)->getBeginLoc(), "failed to produce fixit for // For the given variable declaration with a pointer-to-T type, returns the text // `std::span`. If it is unable to generate the text, returns // `std::nullopt`. -static std::optional createSpanTypeForVarDecl(const VarDecl *VD, - const ASTContext &Ctx) { +static std::optional +createSpanTypeForVarDecl(const VarDecl *VD, const ASTContext &Ctx) { assert(VD->getType()->isPointerType()); std::optional PteTyQualifiers = std::nullopt; @@ -2277,8 +2275,8 @@ static std::optional createSpanTypeForVarDecl(const VarDecl *VD, // the non-empty fix-it list, if fix-its are successfuly generated; empty // list otherwise. static FixItList fixLocalVarDeclWithSpan(const VarDecl *D, ASTContext &Ctx, - const StringRef UserFillPlaceHolder, - UnsafeBufferUsageHandler &Handler) { + const StringRef UserFillPlaceHolder, + UnsafeBufferUsageHandler &Handler) { if (hasUnsupportedSpecifiers(D, Ctx.getSourceManager())) return {}; @@ -2431,9 +2429,9 @@ createOverloadsForFixedParams(const FixitStrategy &S, const FunctionDecl *FD, // print parameter name if provided: if (IdentifierInfo *II = Parm->getIdentifier()) SS << ' ' << II->getName().str(); - } else if (auto ParmTypeText = getRangeText( - getSourceRangeToTokenEnd(Parm, SM, LangOpts), - SM, LangOpts)) { + } else if (auto ParmTypeText = + getRangeText(getSourceRangeToTokenEnd(Parm, SM, LangOpts), + SM, LangOpts)) { // print the whole `Parm` without modification: SS << ParmTypeText->str(); } else @@ -2577,7 +2575,8 @@ static FixItList fixVariableWithSpan(const VarDecl *VD, UnsafeBufferUsageHandler &Handler) { const DeclStmt *DS = Tracker.lookupDecl(VD); if (!DS) { - DEBUG_NOTE_DECL_FAIL(VD, " : variables declared this way not implemented yet"); + DEBUG_NOTE_DECL_FAIL(VD, + " : variables declared this way not implemented yet"); return {}; } if (!DS->isSingleDecl()) { @@ -2979,8 +2978,8 @@ void clang::checkUnsafeBufferUsage(const Decl *D, #endif assert(D && D->getBody()); - // We do not want to visit a Lambda expression defined inside a method independently. - // Instead, it should be visited along with the outer method. + // We do not want to visit a Lambda expression defined inside a method + // independently. Instead, it should be visited along with the outer method. // FIXME: do we want to do the same thing for `BlockDecl`s? if (const auto *fd = dyn_cast(D)) { if (fd->getParent()->isLambda() && fd->getParent()->isLocalClass()) @@ -2990,7 +2989,7 @@ void clang::checkUnsafeBufferUsage(const Decl *D, // Do not emit fixit suggestions for functions declared in an // extern "C" block. if (const auto *FD = dyn_cast(D)) { - for (FunctionDecl *FReDecl : FD->redecls()) { + for (FunctionDecl *FReDecl : FD->redecls()) { if (FReDecl->isExternC()) { EmitSuggestions = false; break; @@ -3002,7 +3001,7 @@ void clang::checkUnsafeBufferUsage(const Decl *D, FixableGadgetSets FixablesForAllVars; auto [FixableGadgets, WarningGadgets, Tracker] = - findGadgets(D, Handler, EmitSuggestions); + findGadgets(D, Handler, EmitSuggestions); if (!EmitSuggestions) { // Our job is very easy without suggestions. Just warn about @@ -3055,36 +3054,36 @@ void clang::checkUnsafeBufferUsage(const Decl *D, // Filter out non-local vars and vars with unclaimed DeclRefExpr-s. for (auto it = FixablesForAllVars.byVar.cbegin(); it != FixablesForAllVars.byVar.cend();) { - // FIXME: need to deal with global variables later - if ((!it->first->isLocalVarDecl() && !isa(it->first))) { + // FIXME: need to deal with global variables later + if ((!it->first->isLocalVarDecl() && !isa(it->first))) { #ifndef NDEBUG - Handler.addDebugNoteForVar( - it->first, it->first->getBeginLoc(), - ("failed to produce fixit for '" + it->first->getNameAsString() + - "' : neither local nor a parameter")); + Handler.addDebugNoteForVar(it->first, it->first->getBeginLoc(), + ("failed to produce fixit for '" + + it->first->getNameAsString() + + "' : neither local nor a parameter")); #endif - it = FixablesForAllVars.byVar.erase(it); - } else if (it->first->getType().getCanonicalType()->isReferenceType()) { + it = FixablesForAllVars.byVar.erase(it); + } else if (it->first->getType().getCanonicalType()->isReferenceType()) { #ifndef NDEBUG - Handler.addDebugNoteForVar(it->first, it->first->getBeginLoc(), - ("failed to produce fixit for '" + - it->first->getNameAsString() + - "' : has a reference type")); + Handler.addDebugNoteForVar(it->first, it->first->getBeginLoc(), + ("failed to produce fixit for '" + + it->first->getNameAsString() + + "' : has a reference type")); #endif - it = FixablesForAllVars.byVar.erase(it); - } else if (Tracker.hasUnclaimedUses(it->first)) { - it = FixablesForAllVars.byVar.erase(it); - } else if (it->first->isInitCapture()) { + it = FixablesForAllVars.byVar.erase(it); + } else if (Tracker.hasUnclaimedUses(it->first)) { + it = FixablesForAllVars.byVar.erase(it); + } else if (it->first->isInitCapture()) { #ifndef NDEBUG - Handler.addDebugNoteForVar( - it->first, it->first->getBeginLoc(), - ("failed to produce fixit for '" + it->first->getNameAsString() + - "' : init capture")); + Handler.addDebugNoteForVar(it->first, it->first->getBeginLoc(), + ("failed to produce fixit for '" + + it->first->getNameAsString() + + "' : init capture")); #endif - it = FixablesForAllVars.byVar.erase(it); - } else { - ++it; - } + it = FixablesForAllVars.byVar.erase(it); + } else { + ++it; + } } #ifndef NDEBUG @@ -3115,7 +3114,7 @@ void clang::checkUnsafeBufferUsage(const Decl *D, for (auto it : FixablesForAllVars.byVar) { for (const FixableGadget *fixable : it.second) { std::optional> ImplPair = - fixable->getStrategyImplications(); + fixable->getStrategyImplications(); if (ImplPair) { std::pair Impl = std::move(*ImplPair); PtrAssignmentGraph[Impl.first].insert(Impl.second); @@ -3144,10 +3143,10 @@ void clang::checkUnsafeBufferUsage(const Decl *D, for (const auto &[Var, ignore] : UnsafeOps.byVar) { if (VisitedVarsDirected.find(Var) == VisitedVarsDirected.end()) { - std::queue QueueDirected{}; + std::queue QueueDirected{}; QueueDirected.push(Var); - while(!QueueDirected.empty()) { - const VarDecl* CurrentVar = QueueDirected.front(); + while (!QueueDirected.empty()) { + const VarDecl *CurrentVar = QueueDirected.front(); QueueDirected.pop(); VisitedVarsDirected.insert(CurrentVar); auto AdjacentNodes = PtrAssignmentGraph[CurrentVar]; @@ -3178,11 +3177,11 @@ void clang::checkUnsafeBufferUsage(const Decl *D, for (const auto &[Var, ignore] : UnsafeOps.byVar) { if (VisitedVars.find(Var) == VisitedVars.end()) { VarGrpTy &VarGroup = Groups.emplace_back(); - std::queue Queue{}; + std::queue Queue{}; Queue.push(Var); - while(!Queue.empty()) { - const VarDecl* CurrentVar = Queue.front(); + while (!Queue.empty()) { + const VarDecl *CurrentVar = Queue.front(); Queue.pop(); VisitedVars.insert(CurrentVar); VarGroup.push_back(CurrentVar); diff --git a/clang/lib/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp b/clang/lib/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp index 32fba9c93752c..6ecfe110066b0 100644 --- a/clang/lib/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp +++ b/clang/lib/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp @@ -30,7 +30,7 @@ extern "C" void clang_registerCheckers(CheckerRegistry ®istry) { registry.addChecker(registerMyChecker, shouldRegisterMyChecker, "example.MyChecker", "Example Description", "example.mychecker.documentation.nonexistent.html", - /*isHidden*/false); + /*isHidden*/ false); registry.addCheckerOption(/*OptionType*/ "bool", /*CheckerFullName*/ "example.MyChecker", diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index 0e8cbc60689a7..09542bdbb57ac 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -52,8 +52,10 @@ class AnalysisOrderChecker } bool isCallbackEnabled(ProgramStateRef State, StringRef CallbackName) const { - AnalyzerOptions &Opts = State->getStateManager().getOwningEngine() - .getAnalysisManager().getAnalyzerOptions(); + AnalyzerOptions &Opts = State->getStateManager() + .getOwningEngine() + .getAnalysisManager() + .getAnalyzerOptions(); return isCallbackEnabled(Opts, CallbackName); } diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp index a54f1b1e71d47..a7b9b8b51cf33 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp @@ -27,24 +27,23 @@ using namespace ento; #define DEBUG_TYPE "StatsChecker" -STATISTIC(NumBlocks, - "The # of blocks in top level functions"); +STATISTIC(NumBlocks, "The # of blocks in top level functions"); STATISTIC(NumBlocksUnreachable, "The # of unreachable blocks in analyzing top level functions"); namespace { class AnalyzerStatsChecker : public Checker { public: - void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const; + void checkEndAnalysis(ExplodedGraph &G, BugReporter &B, + ExprEngine &Eng) const; }; -} +} // namespace -void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G, - BugReporter &B, +void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G, BugReporter &B, ExprEngine &Eng) const { const CFG *C = nullptr; const SourceManager &SM = B.getSourceManager(); - llvm::SmallPtrSet reachable; + llvm::SmallPtrSet reachable; // Root node should have the location context of the top most function. const ExplodedNode *GraphRoot = *G.roots_begin(); @@ -105,11 +104,10 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G, NumBlocks += total; std::string NameOfRootFunction = std::string(output.str()); - output << " -> Total CFGBlocks: " << total << " | Unreachable CFGBlocks: " - << unreachable << " | Exhausted Block: " - << (Eng.wasBlocksExhausted() ? "yes" : "no") - << " | Empty WorkList: " - << (Eng.hasEmptyWorkList() ? "yes" : "no"); + output << " -> Total CFGBlocks: " << total + << " | Unreachable CFGBlocks: " << unreachable + << " | Exhausted Block: " << (Eng.wasBlocksExhausted() ? "yes" : "no") + << " | Empty WorkList: " << (Eng.hasEmptyWorkList() ? "yes" : "no"); B.EmitBasicReport(D, this, "Analyzer Statistics", "Internal Statistics", output.str(), PathDiagnosticLocation(D, SM)); @@ -124,8 +122,8 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G, if (std::optional CS = CE.getAs()) { SmallString<128> bufI; llvm::raw_svector_ostream outputI(bufI); - outputI << "(" << NameOfRootFunction << ")" << - ": The analyzer generated a sink at this point"; + outputI << "(" << NameOfRootFunction << ")" + << ": The analyzer generated a sink at this point"; B.EmitBasicReport( D, this, "Sink Point", "Internal Statistics", outputI.str(), PathDiagnosticLocation::createBegin(CS->getStmt(), SM, LC)); diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp index c990ad138f890..92d8d6dbd5186 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp @@ -23,17 +23,16 @@ using namespace clang; using namespace ento; namespace { -class ArrayBoundChecker : - public Checker { +class ArrayBoundChecker : public Checker { const BugType BT{this, "Out-of-bound array access"}; public: - void checkLocation(SVal l, bool isLoad, const Stmt* S, + void checkLocation(SVal l, bool isLoad, const Stmt *S, CheckerContext &C) const; }; -} +} // namespace -void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS, +void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt *LoadS, CheckerContext &C) const { // Check for out of bound array element access. const MemRegion *R = l.getAsRegion(); diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp index 05fc00a990d52..3de7f711c122e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp @@ -279,11 +279,13 @@ static std::pair compareValueToThreshold(ProgramStateRef State, NonLoc Value, NonLoc Threshold, SValBuilder &SVB, bool CheckEquality = false) { if (auto ConcreteThreshold = Threshold.getAs()) { - std::tie(Value, Threshold) = getSimplifiedOffsets(Value, *ConcreteThreshold, SVB); + std::tie(Value, Threshold) = + getSimplifiedOffsets(Value, *ConcreteThreshold, SVB); } if (auto ConcreteThreshold = Threshold.getAs()) { QualType T = Value.getType(SVB.getContext()); - if (T->isUnsignedIntegerType() && ConcreteThreshold->getValue().isNegative()) { + if (T->isUnsignedIntegerType() && + ConcreteThreshold->getValue().isNegative()) { // In this case we reduced the bound check to a comparison of the form // (symbol or value with unsigned type) < (negative number) // which is always false. We are handling these cases separately because diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp index c72a97cc01e91..2693e5b219781 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp @@ -129,8 +129,7 @@ class NilArgChecker : public Checker(); if (!Location) @@ -157,15 +156,13 @@ void NilArgChecker::warnIfNilExpr(const Expr *E, } } -void NilArgChecker::warnIfNilArg(CheckerContext &C, - const ObjCMethodCall &msg, - unsigned int Arg, - FoundationClass Class, +void NilArgChecker::warnIfNilArg(CheckerContext &C, const ObjCMethodCall &msg, + unsigned int Arg, FoundationClass Class, bool CanBeSubscript) const { // Check if the argument is nil. ProgramStateRef State = C.getState(); if (!State->isNull(msg.getArgSVal(Arg)).isConstrainedTrue()) - return; + return; // NOTE: We cannot throw non-fatal errors from warnIfNilExpr, // because it's called multiple times from some callers, so it'd cause @@ -186,7 +183,7 @@ void NilArgChecker::warnIfNilArg(CheckerContext &C, os << GetReceiverInterfaceName(msg) << "' cannot be nil"; } else { assert(Arg == 1); - os << "'"<< GetReceiverInterfaceName(msg) << "' key cannot be nil"; + os << "'" << GetReceiverInterfaceName(msg) << "' key cannot be nil"; } } else llvm_unreachable("Missing foundation class for the subscript expr"); @@ -214,10 +211,8 @@ void NilArgChecker::warnIfNilArg(CheckerContext &C, } } -void NilArgChecker::generateBugReport(ExplodedNode *N, - StringRef Msg, - SourceRange Range, - const Expr *E, +void NilArgChecker::generateBugReport(ExplodedNode *N, StringRef Msg, + SourceRange Range, const Expr *E, CheckerContext &C) const { if (!BT) BT.reset(new APIMisuse(this, "nil argument")); @@ -313,7 +308,7 @@ void NilArgChecker::checkPreObjCMessage(const ObjCMethodCall &msg, if (S == DictionaryWithObjectForKeySel || S == SetObjectForKeySel) { Arg = 0; - warnIfNilArg(C, msg, /* Arg */1, Class); + warnIfNilArg(C, msg, /* Arg */ 1, Class); } else if (S == SetObjectForKeyedSubscriptSel) { CanBeSubscript = true; Arg = 1; @@ -350,9 +345,10 @@ void NilArgChecker::checkPostStmt(const ObjCDictionaryLiteral *DL, //===----------------------------------------------------------------------===// namespace { -class CFNumberChecker : public Checker< check::PreStmt > { +class CFNumberChecker : public Checker> { mutable std::unique_ptr BT; mutable IdentifierInfo *ICreate = nullptr, *IGetValue = nullptr; + public: CFNumberChecker() = default; @@ -380,27 +376,41 @@ enum CFNumberType { }; static std::optional GetCFNumberSize(ASTContext &Ctx, uint64_t i) { - static const unsigned char FixedSize[] = { 8, 16, 32, 64, 32, 64 }; + static const unsigned char FixedSize[] = {8, 16, 32, 64, 32, 64}; if (i < kCFNumberCharType) - return FixedSize[i-1]; + return FixedSize[i - 1]; QualType T; switch (i) { - case kCFNumberCharType: T = Ctx.CharTy; break; - case kCFNumberShortType: T = Ctx.ShortTy; break; - case kCFNumberIntType: T = Ctx.IntTy; break; - case kCFNumberLongType: T = Ctx.LongTy; break; - case kCFNumberLongLongType: T = Ctx.LongLongTy; break; - case kCFNumberFloatType: T = Ctx.FloatTy; break; - case kCFNumberDoubleType: T = Ctx.DoubleTy; break; - case kCFNumberCFIndexType: - case kCFNumberNSIntegerType: - case kCFNumberCGFloatType: - // FIXME: We need a way to map from names to Type*. - default: - return std::nullopt; + case kCFNumberCharType: + T = Ctx.CharTy; + break; + case kCFNumberShortType: + T = Ctx.ShortTy; + break; + case kCFNumberIntType: + T = Ctx.IntTy; + break; + case kCFNumberLongType: + T = Ctx.LongTy; + break; + case kCFNumberLongLongType: + T = Ctx.LongLongTy; + break; + case kCFNumberFloatType: + T = Ctx.FloatTy; + break; + case kCFNumberDoubleType: + T = Ctx.DoubleTy; + break; + case kCFNumberCFIndexType: + case kCFNumberNSIntegerType: + case kCFNumberCGFloatType: + // FIXME: We need a way to map from names to Type*. + default: + return std::nullopt; } return Ctx.getTypeSize(T); @@ -432,7 +442,7 @@ static const char* GetCFNumberTypeStr(uint64_t i) { #endif void CFNumberChecker::checkPreStmt(const CallExpr *CE, - CheckerContext &C) const { + CheckerContext &C) const { ProgramStateRef state = C.getState(); const FunctionDecl *FD = C.getCalleeDecl(CE); if (!FD) @@ -477,7 +487,7 @@ void CFNumberChecker::checkPreStmt(const CallExpr *CE, if (!LV) return; - const TypedValueRegion* R = dyn_cast(LV->stripCasts()); + const TypedValueRegion *R = dyn_cast(LV->stripCasts()); if (!R) return; @@ -503,27 +513,27 @@ void CFNumberChecker::checkPreStmt(const CallExpr *CE, bool isCreate = (FD->getIdentifier() == ICreate); if (isCreate) { - os << (PrimitiveTypeSize == 8 ? "An " : "A ") - << PrimitiveTypeSize << "-bit integer is used to initialize a " + os << (PrimitiveTypeSize == 8 ? "An " : "A ") << PrimitiveTypeSize + << "-bit integer is used to initialize a " << "CFNumber object that represents " - << (CFNumberSize == 8 ? "an " : "a ") - << CFNumberSize << "-bit integer; "; + << (CFNumberSize == 8 ? "an " : "a ") << CFNumberSize + << "-bit integer; "; } else { os << "A CFNumber object that represents " - << (CFNumberSize == 8 ? "an " : "a ") - << CFNumberSize << "-bit integer is used to initialize " - << (PrimitiveTypeSize == 8 ? "an " : "a ") - << PrimitiveTypeSize << "-bit integer; "; + << (CFNumberSize == 8 ? "an " : "a ") << CFNumberSize + << "-bit integer is used to initialize " + << (PrimitiveTypeSize == 8 ? "an " : "a ") << PrimitiveTypeSize + << "-bit integer; "; } if (PrimitiveTypeSize < CFNumberSize) os << (CFNumberSize - PrimitiveTypeSize) - << " bits of the CFNumber value will " - << (isCreate ? "be garbage." : "overwrite adjacent storage."); + << " bits of the CFNumber value will " + << (isCreate ? "be garbage." : "overwrite adjacent storage."); else os << (PrimitiveTypeSize - CFNumberSize) - << " bits of the integer value will be " - << (isCreate ? "lost." : "garbage."); + << " bits of the integer value will be " + << (isCreate ? "lost." : "garbage."); if (!BT) BT.reset(new APIMisuse(this, "Bad use of CFNumber APIs")); @@ -535,7 +545,8 @@ void CFNumberChecker::checkPreStmt(const CallExpr *CE, } //===----------------------------------------------------------------------===// -// CFRetain/CFRelease/CFMakeCollectable/CFAutorelease checking for null arguments. +// CFRetain/CFRelease/CFMakeCollectable/CFAutorelease checking for null +// arguments. //===----------------------------------------------------------------------===// namespace { @@ -641,8 +652,8 @@ void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg, os << "The '"; S.print(os); os << "' message should be sent to instances " - "of class '" << Class->getName() - << "' and not the class directly"; + "of class '" + << Class->getName() << "' and not the class directly"; auto report = std::make_unique(*BT, os.str(), N); report->addRange(msg.getSourceRange()); @@ -674,8 +685,8 @@ class VariadicMethodTypeChecker : public Checker { /// isVariadicMessage - Returns whether the given message is a variadic message, /// where all arguments must be Objective-C types. -bool -VariadicMethodTypeChecker::isVariadicMessage(const ObjCMethodCall &msg) const { +bool VariadicMethodTypeChecker::isVariadicMessage( + const ObjCMethodCall &msg) const { const ObjCMethodDecl *MD = msg.getDecl(); if (!MD || !MD->isVariadic() || isa(MD->getDeclContext())) @@ -706,16 +717,16 @@ VariadicMethodTypeChecker::isVariadicMessage(const ObjCMethodCall &msg) const { const ObjCInterfaceDecl *Class = msg.getReceiverInterface(); switch (findKnownClass(Class)) { - case FC_NSArray: - return S == arrayWithObjectsS; - case FC_NSOrderedSet: - return S == orderedSetWithObjectsS; - case FC_NSSet: - return S == setWithObjectsS; - case FC_NSDictionary: - return S == dictionaryWithObjectsAndKeysS; - default: - return false; + case FC_NSArray: + return S == arrayWithObjectsS; + case FC_NSOrderedSet: + return S == orderedSetWithObjectsS; + case FC_NSSet: + return S == setWithObjectsS; + case FC_NSDictionary: + return S == dictionaryWithObjectsAndKeysS; + default: + return false; } } } @@ -730,7 +741,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg, ASTContext &Ctx = C.getASTContext(); arrayWithObjectsS = GetUnarySelector("arrayWithObjects", Ctx); dictionaryWithObjectsAndKeysS = - GetUnarySelector("dictionaryWithObjectsAndKeys", Ctx); + GetUnarySelector("dictionaryWithObjectsAndKeys", Ctx); setWithObjectsS = GetUnarySelector("setWithObjects", Ctx); orderedSetWithObjectsS = GetUnarySelector("orderedSetWithObjects", Ctx); @@ -739,7 +750,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg, } if (!isVariadicMessage(msg)) - return; + return; // We are not interested in the selector arguments since they have // well-defined types, so the compiler will issue a warning for them. @@ -815,10 +826,9 @@ REGISTER_MAP_WITH_PROGRAMSTATE(ContainerNonEmptyMap, SymbolRef, bool) namespace { class ObjCLoopChecker - : public Checker, - check::PostObjCMessage, - check::DeadSymbols, - check::PointerEscape > { + : public Checker, + check::PostObjCMessage, check::DeadSymbols, + check::PointerEscape> { mutable IdentifierInfo *CountSelectorII = nullptr; bool isCollectionCountMethod(const ObjCMethodCall &M, @@ -920,9 +930,10 @@ static ProgramStateRef checkElementNonNil(CheckerContext &C, /// Returns NULL state if the collection is known to contain elements /// (or is known not to contain elements if the Assumption parameter is false.) -static ProgramStateRef -assumeCollectionNonEmpty(CheckerContext &C, ProgramStateRef State, - SymbolRef CollectionS, bool Assumption) { +static ProgramStateRef assumeCollectionNonEmpty(CheckerContext &C, + ProgramStateRef State, + SymbolRef CollectionS, + bool Assumption) { if (!State || !CollectionS) return State; @@ -936,10 +947,9 @@ assumeCollectionNonEmpty(CheckerContext &C, ProgramStateRef State, SValBuilder &SvalBuilder = C.getSValBuilder(); SVal CountGreaterThanZeroVal = - SvalBuilder.evalBinOp(State, BO_GT, - nonloc::SymbolVal(*CountS), - SvalBuilder.makeIntVal(0, (*CountS)->getType()), - SvalBuilder.getConditionType()); + SvalBuilder.evalBinOp(State, BO_GT, nonloc::SymbolVal(*CountS), + SvalBuilder.makeIntVal(0, (*CountS)->getType()), + SvalBuilder.getConditionType()); std::optional CountGreaterThanZero = CountGreaterThanZeroVal.getAs(); if (!CountGreaterThanZero) { @@ -953,8 +963,7 @@ assumeCollectionNonEmpty(CheckerContext &C, ProgramStateRef State, static ProgramStateRef assumeCollectionNonEmpty(CheckerContext &C, ProgramStateRef State, - const ObjCForCollectionStmt *FCS, - bool Assumption) { + const ObjCForCollectionStmt *FCS, bool Assumption) { if (!State) return nullptr; @@ -963,8 +972,9 @@ assumeCollectionNonEmpty(CheckerContext &C, ProgramStateRef State, } /// If the fist block edge is a back edge, we are reentering the loop. -static bool alreadyExecutedAtLeastOneLoopIteration(const ExplodedNode *N, - const ObjCForCollectionStmt *FCS) { +static bool +alreadyExecutedAtLeastOneLoopIteration(const ExplodedNode *N, + const ObjCForCollectionStmt *FCS) { if (!N) return false; @@ -989,13 +999,13 @@ void ObjCLoopChecker::checkPostStmt(const ObjCForCollectionStmt *FCS, // Check if this is the branch for the end of the loop. if (!ExprEngine::hasMoreIteration(State, FCS, C.getLocationContext())) { if (!alreadyExecutedAtLeastOneLoopIteration(C.getPredecessor(), FCS)) - State = assumeCollectionNonEmpty(C, State, FCS, /*Assumption*/false); + State = assumeCollectionNonEmpty(C, State, FCS, /*Assumption*/ false); - // Otherwise, this is a branch that goes through the loop body. + // Otherwise, this is a branch that goes through the loop body. } else { State = checkCollectionNonNil(C, State, FCS); State = checkElementNonNil(C, State, FCS); - State = assumeCollectionNonEmpty(C, State, FCS, /*Assumption*/true); + State = assumeCollectionNonEmpty(C, State, FCS, /*Assumption*/ true); } if (!State) @@ -1026,9 +1036,7 @@ void ObjCLoopChecker::checkPostObjCMessage(const ObjCMethodCall &M, return; FoundationClass Class = findKnownClass(ClassID); - if (Class != FC_NSDictionary && - Class != FC_NSArray && - Class != FC_NSSet && + if (Class != FC_NSDictionary && Class != FC_NSArray && Class != FC_NSSet && Class != FC_NSOrderedSet) return; @@ -1096,11 +1104,9 @@ static SymbolRef getMethodReceiverIfKnownImmutable(const CallEvent *Call) { return Message->getReceiverSVal().getAsSymbol(); } -ProgramStateRef -ObjCLoopChecker::checkPointerEscape(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind) const { +ProgramStateRef ObjCLoopChecker::checkPointerEscape( + ProgramStateRef State, const InvalidatedSymbols &Escaped, + const CallEvent *Call, PointerEscapeKind Kind) const { SymbolRef ImmutableReceiver = getMethodReceiverIfKnownImmutable(Call); // Remove the invalidated symbols from the collection count map. @@ -1141,14 +1147,13 @@ namespace { /// The checker restricts the return values of APIs known to /// never (or almost never) return 'nil'. class ObjCNonNilReturnValueChecker - : public Checker, - check::PostStmt, - check::PostStmt > { - mutable bool Initialized = false; - mutable Selector ObjectAtIndex; - mutable Selector ObjectAtIndexedSubscript; - mutable Selector NullSelector; + : public Checker, + check::PostStmt, + check::PostStmt> { + mutable bool Initialized = false; + mutable Selector ObjectAtIndex; + mutable Selector ObjectAtIndexedSubscript; + mutable Selector NullSelector; public: ObjCNonNilReturnValueChecker() = default; @@ -1174,10 +1179,8 @@ class ObjCNonNilReturnValueChecker }; } // end anonymous namespace -ProgramStateRef -ObjCNonNilReturnValueChecker::assumeExprIsNonNull(const Expr *NonNullExpr, - ProgramStateRef State, - CheckerContext &C) const { +ProgramStateRef ObjCNonNilReturnValueChecker::assumeExprIsNonNull( + const Expr *NonNullExpr, ProgramStateRef State, CheckerContext &C) const { SVal Val = C.getSVal(NonNullExpr); if (std::optional DV = Val.getAs()) @@ -1185,15 +1188,15 @@ ObjCNonNilReturnValueChecker::assumeExprIsNonNull(const Expr *NonNullExpr, return State; } -void ObjCNonNilReturnValueChecker::checkPostObjCMessage(const ObjCMethodCall &M, - CheckerContext &C) - const { +void ObjCNonNilReturnValueChecker::checkPostObjCMessage( + const ObjCMethodCall &M, CheckerContext &C) const { ProgramStateRef State = C.getState(); if (!Initialized) { ASTContext &Ctx = C.getASTContext(); ObjectAtIndex = GetUnarySelector("objectAtIndex", Ctx); - ObjectAtIndexedSubscript = GetUnarySelector("objectAtIndexedSubscript", Ctx); + ObjectAtIndexedSubscript = + GetUnarySelector("objectAtIndexedSubscript", Ctx); NullSelector = GetNullarySelector("null", Ctx); } @@ -1294,6 +1297,7 @@ void ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterObjCNonNilReturnValueChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterObjCNonNilReturnValueChecker( + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp index 339927c165fe0..6825740da5dc2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp @@ -41,11 +41,12 @@ struct NoteTagTemplate { }; constexpr NoteTagTemplate NoteTagTemplates[] = { - {"", "right operand of bit shift is less than "}, - {"left operand of bit shift is non-negative", " and right operand is less than "}, - {"right operand of bit shift is non-negative", " but less than "}, - {"both operands of bit shift are non-negative", " and right operand is less than "} -}; + {"", "right operand of bit shift is less than "}, + {"left operand of bit shift is non-negative", + " and right operand is less than "}, + {"right operand of bit shift is non-negative", " but less than "}, + {"both operands of bit shift are non-negative", + " and right operand is less than "}}; /// An implementation detail class which is introduced to split the checker /// logic into several methods while maintaining a consistently updated state @@ -80,9 +81,11 @@ class BitwiseShiftValidator { return PedanticFlag && !Ctx.getASTContext().getLangOpts().CPlusPlus20; } - bool assumeRequirement(OperandSide Side, BinaryOperator::Opcode Cmp, unsigned Limit); + bool assumeRequirement(OperandSide Side, BinaryOperator::Opcode Cmp, + unsigned Limit); - void recordAssumption(OperandSide Side, BinaryOperator::Opcode Cmp, unsigned Limit); + void recordAssumption(OperandSide Side, BinaryOperator::Opcode Cmp, + unsigned Limit); const NoteTag *createNoteTag() const; BugReportPtr createBugReport(StringRef ShortMsg, StringRef Msg) const; @@ -182,10 +185,10 @@ BugReportPtr BitwiseShiftValidator::checkOvershift() { } } - std::string ShortMsg = formatv( - "{0} shift{1}{2} overflows the capacity of '{3}'", - isLeftShift() ? "Left" : "Right", RightOpStr.empty() ? "" : " by", - RightOpStr, LHSTy.getAsString()); + std::string ShortMsg = + formatv("{0} shift{1}{2} overflows the capacity of '{3}'", + isLeftShift() ? "Left" : "Right", RightOpStr.empty() ? "" : " by", + RightOpStr, LHSTy.getAsString()); std::string Msg = formatv( "The result of {0} shift is undefined because the right " "operand{1} is{2} not smaller than {3}, the capacity of '{4}'", @@ -212,15 +215,15 @@ BugReportPtr BitwiseShiftValidator::checkOperandNegative(OperandSide Side) { if (assumeRequirement(Side, BO_GE, 0)) return nullptr; - std::string ShortMsg = formatv("{0} operand is negative in {1} shift", - Side == OperandSide::Left ? "Left" : "Right", - shiftDir()) - .str(); - std::string Msg = formatv("The result of {0} shift is undefined " - "because the {1} operand is negative", - shiftDir(), - Side == OperandSide::Left ? "left" : "right") - .str(); + std::string ShortMsg = + formatv("{0} operand is negative in {1} shift", + Side == OperandSide::Left ? "Left" : "Right", shiftDir()) + .str(); + std::string Msg = + formatv("The result of {0} shift is undefined " + "because the {1} operand is negative", + shiftDir(), Side == OperandSide::Left ? "left" : "right") + .str(); return createBugReport(ShortMsg, Msg); } @@ -265,8 +268,8 @@ BugReportPtr BitwiseShiftValidator::checkLeftShiftOverflow() { const std::string CapacityMsg = formatv("because '{0}' can hold only {1} bits ({2} the sign bit)", - LHSTy.getAsString(), LeftAvailableBitWidth, - ShouldPreserveSignBit ? "excluding" : "including"); + LHSTy.getAsString(), LeftAvailableBitWidth, + ShouldPreserveSignBit ? "excluding" : "including"); const SVal Right = Ctx.getSVal(Op->getRHS()); @@ -277,9 +280,9 @@ BugReportPtr BitwiseShiftValidator::checkLeftShiftOverflow() { const unsigned RHS = ConcreteRight->getValue().getExtValue(); assert(RHS > MaximalAllowedShift); const unsigned OverflownBits = RHS - MaximalAllowedShift; - ShortMsg = formatv( - "The shift '{0} << {1}' overflows the capacity of '{2}'", - Left->getValue(), ConcreteRight->getValue(), LHSTy.getAsString()); + ShortMsg = formatv("The shift '{0} << {1}' overflows the capacity of '{2}'", + Left->getValue(), ConcreteRight->getValue(), + LHSTy.getAsString()); Msg = formatv( "The shift '{0} << {1}' is undefined {2}, so {3} bit{4} overflow{5}", Left->getValue(), ConcreteRight->getValue(), CapacityMsg, OverflownBits, @@ -287,9 +290,8 @@ BugReportPtr BitwiseShiftValidator::checkLeftShiftOverflow() { } else { ShortMsg = formatv("Left shift of '{0}' overflows the capacity of '{1}'", Left->getValue(), LHSTy.getAsString()); - Msg = formatv( - "Left shift of '{0}' is undefined {1}, so some bits overflow", - Left->getValue(), CapacityMsg); + Msg = formatv("Left shift of '{0}' is undefined {1}, so some bits overflow", + Left->getValue(), CapacityMsg); } return createBugReport(ShortMsg, Msg); @@ -298,18 +300,18 @@ BugReportPtr BitwiseShiftValidator::checkLeftShiftOverflow() { void BitwiseShiftValidator::recordAssumption(OperandSide Side, BinaryOperator::Opcode Comparison, unsigned Limit) { - switch (Comparison) { - case BO_GE: - assert(Limit == 0); - NonNegOperands |= (Side == OperandSide::Left ? NonNegLeft : NonNegRight); - break; - case BO_LT: - assert(Side == OperandSide::Right); - if (!UpperBoundBitCount || Limit < UpperBoundBitCount.value()) - UpperBoundBitCount = Limit; - break; - default: - llvm_unreachable("this checker does not use other comparison operators"); + switch (Comparison) { + case BO_GE: + assert(Limit == 0); + NonNegOperands |= (Side == OperandSide::Left ? NonNegLeft : NonNegRight); + break; + case BO_LT: + assert(Side == OperandSide::Right); + if (!UpperBoundBitCount || Limit < UpperBoundBitCount.value()) + UpperBoundBitCount = Limit; + break; + default: + llvm_unreachable("this checker does not use other comparison operators"); } } @@ -330,7 +332,8 @@ const NoteTag *BitwiseShiftValidator::createNoteTag() const { } std::unique_ptr -BitwiseShiftValidator::createBugReport(StringRef ShortMsg, StringRef Msg) const { +BitwiseShiftValidator::createBugReport(StringRef ShortMsg, + StringRef Msg) const { ProgramStateRef State = Ctx.getState(); if (ExplodedNode *ErrNode = Ctx.generateErrorNode(State)) { auto BR = diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index 66e080adb1382..2bad370957229 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -53,8 +53,7 @@ class BlockInCriticalSectionChecker : public Checker { void initIdentifierInfo(ASTContext &Ctx) const; - void reportBlockInCritSection(SymbolRef FileDescSym, - const CallEvent &call, + void reportBlockInCritSection(SymbolRef FileDescSym, const CallEvent &call, CheckerContext &C) const; public: @@ -79,17 +78,19 @@ void BlockInCriticalSectionChecker::initIdentifierInfo(ASTContext &Ctx) const { * function is called instead of early returning it. To avoid this, a bool * variable (IdentifierInfoInitialized) is used and the function will be run * only once. */ - IILockGuard = &Ctx.Idents.get(ClassLockGuard); + IILockGuard = &Ctx.Idents.get(ClassLockGuard); IIUniqueLock = &Ctx.Idents.get(ClassUniqueLock); IdentifierInfoInitialized = true; } } -bool BlockInCriticalSectionChecker::isBlockingFunction(const CallEvent &Call) const { +bool BlockInCriticalSectionChecker::isBlockingFunction( + const CallEvent &Call) const { return matchesAny(Call, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn); } -bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) const { +bool BlockInCriticalSectionChecker::isLockFunction( + const CallEvent &Call) const { if (const auto *Ctor = dyn_cast(&Call)) { auto IdentifierInfo = Ctor->getDecl()->getParent()->getIdentifier(); if (IdentifierInfo == IILockGuard || IdentifierInfo == IIUniqueLock) @@ -100,7 +101,8 @@ bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) const MtxTimedLock, MtxTryLock); } -bool BlockInCriticalSectionChecker::isUnlockFunction(const CallEvent &Call) const { +bool BlockInCriticalSectionChecker::isUnlockFunction( + const CallEvent &Call) const { if (const auto *Dtor = dyn_cast(&Call)) { const auto *DRecordDecl = cast(Dtor->getDecl()->getParent()); auto IdentifierInfo = DRecordDecl->getIdentifier(); @@ -115,9 +117,8 @@ void BlockInCriticalSectionChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { initIdentifierInfo(C.getASTContext()); - if (!isBlockingFunction(Call) - && !isLockFunction(Call) - && !isUnlockFunction(Call)) + if (!isBlockingFunction(Call) && !isLockFunction(Call) && + !isUnlockFunction(Call)) return; ProgramStateRef State = C.getState(); @@ -155,6 +156,7 @@ void ento::registerBlockInCriticalSectionChecker(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterBlockInCriticalSectionChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterBlockInCriticalSectionChecker( + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp index 01e46fa8591c0..4c81aaeef2f5d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -28,7 +28,7 @@ class BuiltinFunctionChecker : public Checker { bool evalCall(const CallEvent &Call, CheckerContext &C) const; }; -} +} // namespace bool BuiltinFunctionChecker::evalCall(const CallEvent &Call, CheckerContext &C) const { @@ -46,7 +46,7 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call, case Builtin::BI__builtin_assume: case Builtin::BI__assume: { - assert (Call.getNumArgs() > 0); + assert(Call.getNumArgs() > 0); SVal Arg = Call.getArgSVal(0); if (Arg.isUndef()) return true; // Return true to model purity. @@ -74,7 +74,7 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call, // just return the value of the subexpression. // __builtin_addressof is going from a reference to a pointer, but those // are represented the same way in the analyzer. - assert (Call.getNumArgs() > 0); + assert(Call.getNumArgs() > 0); SVal Arg = Call.getArgSVal(0); C.addTransition(state->BindExpr(CE, LCtx, Arg)); return true; @@ -107,7 +107,8 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call, SValBuilder &SVB = C.getSValBuilder(); SVal V = UnknownVal(); Expr::EvalResult EVResult; - if (CE->EvaluateAsInt(EVResult, C.getASTContext(), Expr::SE_NoSideEffects)) { + if (CE->EvaluateAsInt(EVResult, C.getASTContext(), + Expr::SE_NoSideEffects)) { // Make sure the result has the correct type. llvm::APSInt Result = EVResult.Val.getInt(); BasicValueFactory &BVF = SVB.getBasicValueFactory(); diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index b7b64c3da4f6c..d9f84b141fa43 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -75,12 +75,9 @@ static QualType getCharPtrType(ASTContext &Ctx, CharKind CK) { : Ctx.WideCharTy); } -class CStringChecker : public Checker< eval::Call, - check::PreStmt, - check::LiveSymbols, - check::DeadSymbols, - check::RegionChanges - > { +class CStringChecker + : public Checker, check::LiveSymbols, + check::DeadSymbols, check::RegionChanges> { mutable std::unique_ptr BT_Null, BT_Bounds, BT_Overlap, BT_NotCString, BT_AdditionOverflow, BT_UninitRead; @@ -105,7 +102,10 @@ class CStringChecker : public Checker< eval::Call, CStringChecksFilter Filter; - static void *getTag() { static int tag; return &tag; } + static void *getTag() { + static int tag; + return &tag; + } bool evalCall(const CallEvent &Call, CheckerContext &C) const; void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const; @@ -113,12 +113,10 @@ class CStringChecker : public Checker< eval::Call, void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const; ProgramStateRef - checkRegionChanges(ProgramStateRef state, - const InvalidatedSymbols *, - ArrayRef ExplicitRegions, - ArrayRef Regions, - const LocationContext *LCtx, - const CallEvent *Call) const; + checkRegionChanges(ProgramStateRef state, const InvalidatedSymbols *, + ArrayRef ExplicitRegions, + ArrayRef Regions, + const LocationContext *LCtx, const CallEvent *Call) const; using FnCheck = std::function; @@ -222,28 +220,21 @@ class CStringChecker : public Checker< eval::Call, bool IsBounded, bool IsBuiltin) const; // Utility methods - std::pair - static assumeZero(CheckerContext &C, - ProgramStateRef state, SVal V, QualType Ty); + std::pair static assumeZero( + CheckerContext &C, ProgramStateRef state, SVal V, QualType Ty); static ProgramStateRef setCStringLength(ProgramStateRef state, - const MemRegion *MR, - SVal strLength); + const MemRegion *MR, SVal strLength); static SVal getCStringLengthForRegion(CheckerContext &C, - ProgramStateRef &state, - const Expr *Ex, - const MemRegion *MR, - bool hypothetical); - SVal getCStringLength(CheckerContext &C, - ProgramStateRef &state, - const Expr *Ex, - SVal Buf, + ProgramStateRef &state, const Expr *Ex, + const MemRegion *MR, bool hypothetical); + SVal getCStringLength(CheckerContext &C, ProgramStateRef &state, + const Expr *Ex, SVal Buf, bool hypothetical = false) const; const StringLiteral *getCStringLiteral(CheckerContext &C, ProgramStateRef &state, - const Expr *expr, - SVal val) const; + const Expr *expr, SVal val) const; /// Invalidate the destination buffer determined by characters copied. static ProgramStateRef @@ -277,9 +268,8 @@ class CStringChecker : public Checker< eval::Call, static bool SummarizeRegion(raw_ostream &os, ASTContext &Ctx, const MemRegion *MR); - static bool memsetAux(const Expr *DstBuffer, SVal CharE, - const Expr *Size, CheckerContext &C, - ProgramStateRef &State); + static bool memsetAux(const Expr *DstBuffer, SVal CharE, const Expr *Size, + CheckerContext &C, ProgramStateRef &State); // Re-usable checks ProgramStateRef checkNonNull(CheckerContext &C, ProgramStateRef State, @@ -296,10 +286,8 @@ class CStringChecker : public Checker< eval::Call, SizeArgExpr Size, AnyArgExpr First, AnyArgExpr Second, CharKind CK = CharKind::Regular) const; - void emitOverlapBug(CheckerContext &C, - ProgramStateRef state, - const Stmt *First, - const Stmt *Second) const; + void emitOverlapBug(CheckerContext &C, ProgramStateRef state, + const Stmt *First, const Stmt *Second) const; void emitNullArgBug(CheckerContext &C, ProgramStateRef State, const Stmt *S, StringRef WarningMsg) const; @@ -309,11 +297,10 @@ class CStringChecker : public Checker< eval::Call, const Stmt *S, StringRef WarningMsg) const; void emitAdditionOverflowBug(CheckerContext &C, ProgramStateRef State) const; void emitUninitializedReadBug(CheckerContext &C, ProgramStateRef State, - const Expr *E) const; + const Expr *E) const; ProgramStateRef checkAdditionOverflow(CheckerContext &C, - ProgramStateRef state, - NonLoc left, - NonLoc right) const; + ProgramStateRef state, NonLoc left, + NonLoc right) const; // Return true if the destination buffer of the copy function may be in bound. // Expects SVal of Size to be positive and unsigned. @@ -323,7 +310,7 @@ class CStringChecker : public Checker< eval::Call, QualType LengthTy); }; -} //end anonymous namespace +} // end anonymous namespace REGISTER_MAP_WITH_PROGRAMSTATE(CStringLength, const MemRegion *, SVal) @@ -331,12 +318,12 @@ REGISTER_MAP_WITH_PROGRAMSTATE(CStringLength, const MemRegion *, SVal) // Individual checks and utility methods. //===----------------------------------------------------------------------===// -std::pair +std::pair CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V, QualType Ty) { std::optional val = V.getAs(); if (!val) - return std::pair(state, state); + return std::pair(state, state); SValBuilder &svalBuilder = C.getSValBuilder(); DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty); @@ -635,7 +622,8 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C, } void CStringChecker::emitOverlapBug(CheckerContext &C, ProgramStateRef state, - const Stmt *First, const Stmt *Second) const { + const Stmt *First, + const Stmt *Second) const { ExplodedNode *N = C.generateErrorNode(state); if (!N) return; @@ -754,9 +742,9 @@ void CStringChecker::emitAdditionOverflowBug(CheckerContext &C, } ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C, - ProgramStateRef state, - NonLoc left, - NonLoc right) const { + ProgramStateRef state, + NonLoc left, + NonLoc right) const { // If out-of-bounds checking is turned off, skip the rest. if (!Filter.CheckCStringOutOfBounds) return state; @@ -774,25 +762,25 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C, SVal maxMinusRight; if (isa(right)) { - maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, right, - sizeTy); + maxMinusRight = + svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, right, sizeTy); } else { // Try switching the operands. (The order of these two assignments is // important!) - maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, left, - sizeTy); + maxMinusRight = + svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, left, sizeTy); left = right; } if (std::optional maxMinusRightNL = maxMinusRight.getAs()) { QualType cmpTy = svalBuilder.getConditionType(); // If left > max - right, we have an overflow. - SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left, - *maxMinusRightNL, cmpTy); + SVal willOverflow = + svalBuilder.evalBinOpNN(state, BO_GT, left, *maxMinusRightNL, cmpTy); ProgramStateRef stateOverflow, stateOkay; std::tie(stateOverflow, stateOkay) = - state->assume(willOverflow.castAs()); + state->assume(willOverflow.castAs()); if (stateOverflow && !stateOkay) { // We have an overflow. Emit a bug report. @@ -809,8 +797,8 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C, } ProgramStateRef CStringChecker::setCStringLength(ProgramStateRef state, - const MemRegion *MR, - SVal strLength) { + const MemRegion *MR, + SVal strLength) { assert(!strLength.isUndef() && "Attempt to set an undefined string length"); MR = MR->StripCasts(); @@ -864,10 +852,9 @@ SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C, // Otherwise, get a new symbol and update the state. SValBuilder &svalBuilder = C.getSValBuilder(); QualType sizeTy = svalBuilder.getContext().getSizeType(); - SVal strLength = svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(), - MR, Ex, sizeTy, - C.getLocationContext(), - C.blockCount()); + SVal strLength = + svalBuilder.getMetadataSymbolVal(CStringChecker::getTag(), MR, Ex, sizeTy, + C.getLocationContext(), C.blockCount()); if (!hypothetical) { if (std::optional strLn = strLength.getAs()) { @@ -875,8 +862,8 @@ SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C, BasicValueFactory &BVF = svalBuilder.getBasicValueFactory(); const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy); llvm::APSInt fourInt = APSIntType(maxValInt).getValue(4); - const llvm::APSInt *maxLengthInt = BVF.evalAPSInt(BO_Div, maxValInt, - fourInt); + const llvm::APSInt *maxLengthInt = + BVF.evalAPSInt(BO_Div, maxValInt, fourInt); NonLoc maxLength = svalBuilder.makeIntVal(*maxLengthInt); SVal evalLength = svalBuilder.evalBinOpNN(state, BO_LE, *strLn, maxLength, svalBuilder.getConditionType()); @@ -978,7 +965,9 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state, } const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C, - ProgramStateRef &state, const Expr *expr, SVal val) const { + ProgramStateRef &state, + const Expr *expr, + SVal val) const { // Get the memory region pointed to by the val. const MemRegion *bufRegion = val.getAsRegion(); @@ -989,7 +978,7 @@ const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C, bufRegion = bufRegion->StripCasts(); // Cast the memory region to a string region. - const StringRegion *strRegion= dyn_cast(bufRegion); + const StringRegion *strRegion = dyn_cast(bufRegion); if (!strRegion) return nullptr; @@ -1543,7 +1532,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, ProgramStateRef stateZeroSize, stateNonZeroSize; std::tie(stateZeroSize, stateNonZeroSize) = - assumeZero(C, state, maxlenVal, maxlenExpr->getType()); + assumeZero(C, state, maxlenVal, maxlenExpr->getType()); // If the size can be zero, the result will be 0 in that case, and we don't // have to check the string itself. @@ -1619,15 +1608,19 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, NonLoc resultNL = result.castAs(); if (strLengthNL) { - state = state->assume(C.getSValBuilder().evalBinOpNN( - state, BO_LE, resultNL, *strLengthNL, cmpTy) - .castAs(), true); + state = state->assume( + C.getSValBuilder() + .evalBinOpNN(state, BO_LE, resultNL, *strLengthNL, cmpTy) + .castAs(), + true); } if (maxlenValNL) { - state = state->assume(C.getSValBuilder().evalBinOpNN( - state, BO_LE, resultNL, *maxlenValNL, cmpTy) - .castAs(), true); + state = state->assume( + C.getSValBuilder() + .evalBinOpNN(state, BO_LE, resultNL, *maxlenValNL, cmpTy) + .castAs(), + true); } } @@ -1903,8 +1896,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, LCtx, strLength); } else { // strlcat returns strlen(src) + strlen(dst) - SVal retSize = svalBuilder.evalBinOp( - state, BO_Add, strLength, dstStrLength, sizeTy); + SVal retSize = svalBuilder.evalBinOp(state, BO_Add, strLength, + dstStrLength, sizeTy); StateZeroSize = StateZeroSize->BindExpr(Call.getOriginExpr(), LCtx, retSize); } @@ -1995,10 +1988,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, if (dstStrLengthNL && appendK != ConcatFnKind::none) { // we extend the dst string with the src // finalStrLength >= dstStrLength - SVal destInResult = svalBuilder.evalBinOpNN(state, BO_GE, - *finalStrLengthNL, - *dstStrLengthNL, - cmpTy); + SVal destInResult = svalBuilder.evalBinOpNN( + state, BO_GE, *finalStrLengthNL, *dstStrLengthNL, cmpTy); state = state->assume(destInResult.castAs(), true); if (!state) @@ -2021,7 +2012,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, Result = (ReturnEnd ? UnknownVal() : DstVal); } else { if (appendK == ConcatFnKind::strlcat || appendK == ConcatFnKind::none) - //strlcpy, strlcat + // strlcpy, strlcat Result = strlRetVal; else Result = finalStrLength; @@ -2054,7 +2045,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, // Then, if the final length is known... if (std::optional knownStrLength = finalStrLength.getAs()) { SVal lastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal, - *knownStrLength, ptrTy); + *knownStrLength, ptrTy); // ...and we haven't checked the bound, we'll check the actual copy. if (!boundWarning) { @@ -2117,25 +2108,25 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call, void CStringChecker::evalStrcmp(CheckerContext &C, const CallEvent &Call) const { - //int strcmp(const char *s1, const char *s2); + // int strcmp(const char *s1, const char *s2); evalStrcmpCommon(C, Call, /* IsBounded = */ false, /* IgnoreCase = */ false); } void CStringChecker::evalStrncmp(CheckerContext &C, const CallEvent &Call) const { - //int strncmp(const char *s1, const char *s2, size_t n); + // int strncmp(const char *s1, const char *s2, size_t n); evalStrcmpCommon(C, Call, /* IsBounded = */ true, /* IgnoreCase = */ false); } void CStringChecker::evalStrcasecmp(CheckerContext &C, const CallEvent &Call) const { - //int strcasecmp(const char *s1, const char *s2); + // int strcasecmp(const char *s1, const char *s2); evalStrcmpCommon(C, Call, /* IsBounded = */ false, /* IgnoreCase = */ true); } void CStringChecker::evalStrncasecmp(CheckerContext &C, const CallEvent &Call) const { - //int strncasecmp(const char *s1, const char *s2, size_t n); + // int strncasecmp(const char *s1, const char *s2, size_t n); evalStrcmpCommon(C, Call, /* IsBounded = */ true, /* IgnoreCase = */ true); } @@ -2248,15 +2239,13 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallEvent &Call, // than zero, [c11, p7.24.4.2]. if (compareRes == 0) { resultVal = svalBuilder.makeIntVal(compareRes, Call.getResultType()); - } - else { + } else { DefinedSVal zeroVal = svalBuilder.makeIntVal(0, Call.getResultType()); // Constrain strcmp's result range based on the result of StringRef's // comparison methods. BinaryOperatorKind op = (compareRes > 0) ? BO_GT : BO_LT; - SVal compareWithZero = - svalBuilder.evalBinOp(state, op, resultVal, zeroVal, - svalBuilder.getConditionType()); + SVal compareWithZero = svalBuilder.evalBinOp( + state, op, resultVal, zeroVal, svalBuilder.getConditionType()); DefinedSVal compareWithZeroVal = compareWithZero.castAs(); state = state->assume(compareWithZeroVal, true); } @@ -2437,7 +2426,7 @@ void CStringChecker::evalBzero(CheckerContext &C, const CallEvent &Call) const { ProgramStateRef StateZeroSize, StateNonZeroSize; std::tie(StateZeroSize, StateNonZeroSize) = - assumeZero(C, State, SizeVal, SizeTy); + assumeZero(C, State, SizeVal, SizeTy); // If the size is zero, there won't be any actual memory access, // In this case we just return. @@ -2599,7 +2588,7 @@ void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const { SVal StrVal = C.getSVal(Init); assert(StrVal.isValid() && "Initializer string is unknown or undefined"); DefinedOrUnknownSVal strLength = - getCStringLength(C, state, Init, StrVal).castAs(); + getCStringLength(C, state, Init, StrVal).castAs(); state = state->set(MR, strLength); } @@ -2607,12 +2596,10 @@ void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const { C.addTransition(state); } -ProgramStateRef -CStringChecker::checkRegionChanges(ProgramStateRef state, - const InvalidatedSymbols *, +ProgramStateRef CStringChecker::checkRegionChanges( + ProgramStateRef state, const InvalidatedSymbols *, ArrayRef ExplicitRegions, - ArrayRef Regions, - const LocationContext *LCtx, + ArrayRef Regions, const LocationContext *LCtx, const CallEvent *Call) const { CStringLengthTy Entries = state->get(); if (Entries.isEmpty()) @@ -2657,7 +2644,7 @@ CStringChecker::checkRegionChanges(ProgramStateRef state, } void CStringChecker::checkLiveSymbols(ProgramStateRef state, - SymbolReaper &SR) const { + SymbolReaper &SR) const { // Mark all symbols in our string length map as valid. CStringLengthTy Entries = state->get(); @@ -2668,7 +2655,7 @@ void CStringChecker::checkLiveSymbols(ProgramStateRef state, } void CStringChecker::checkDeadSymbols(SymbolReaper &SR, - CheckerContext &C) const { + CheckerContext &C) const { ProgramStateRef state = C.getState(); CStringLengthTy Entries = state->get(); if (Entries.isEmpty()) diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp index 888724f7ea3b2..6b9ef889c76f7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp @@ -11,13 +11,13 @@ // of bytes to copy. // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Expr.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/StmtVisitor.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TypeTraits.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -29,10 +29,10 @@ using namespace clang; using namespace ento; namespace { -class WalkAST: public StmtVisitor { +class WalkAST : public StmtVisitor { const CheckerBase *Checker; BugReporter &BR; - AnalysisDeclContext* AC; + AnalysisDeclContext *AC; /// Check if two expressions refer to the same declaration. bool sameDecl(const Expr *A1, const Expr *A2) { @@ -106,9 +106,7 @@ class WalkAST: public StmtVisitor { // Statement visitor methods. void VisitChildren(Stmt *S); - void VisitStmt(Stmt *S) { - VisitChildren(S); - } + void VisitStmt(Stmt *S) { VisitChildren(S); } void VisitCallExpr(CallExpr *CE); }; } // end anonymous namespace @@ -178,7 +176,8 @@ bool WalkAST::containsBadStrlcpyStrlcatPattern(const CallExpr *CE) { // - integral value // We try to figure out if the last argument is possibly longer // than the destination can possibly handle if its size can be defined. - if (const auto *IL = dyn_cast(LenArg->IgnoreParenImpCasts())) { + if (const auto *IL = + dyn_cast(LenArg->IgnoreParenImpCasts())) { uint64_t ILRawVal = IL->getValue().getZExtValue(); // Case when there is pointer arithmetic on the destination buffer @@ -189,7 +188,8 @@ bool WalkAST::containsBadStrlcpyStrlcatPattern(const CallExpr *CE) { dyn_cast(DstArg->IgnoreParenImpCasts())) { DstArgDRE = dyn_cast(BE->getLHS()->IgnoreParenImpCasts()); if (BE->getOpcode() == BO_Add) { - if ((IL = dyn_cast(BE->getRHS()->IgnoreParenImpCasts()))) { + if ((IL = dyn_cast( + BE->getRHS()->IgnoreParenImpCasts()))) { DstOff = IL->getValue().getZExtValue(); } } @@ -219,8 +219,8 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { if (containsBadStrncatPattern(CE)) { const Expr *DstArg = CE->getArg(0); const Expr *LenArg = CE->getArg(2); - PathDiagnosticLocation Loc = - PathDiagnosticLocation::createBegin(LenArg, BR.getSourceManager(), AC); + PathDiagnosticLocation Loc = PathDiagnosticLocation::createBegin( + LenArg, BR.getSourceManager(), AC); StringRef DstName = getPrintableName(DstArg); @@ -228,8 +228,10 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { llvm::raw_svector_ostream os(S); os << "Potential buffer overflow. "; if (!DstName.empty()) { - os << "Replace with 'sizeof(" << DstName << ") " - "- strlen(" << DstName <<") - 1'"; + os << "Replace with 'sizeof(" << DstName + << ") " + "- strlen(" + << DstName << ") - 1'"; os << " or u"; } else os << "U"; @@ -244,24 +246,25 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { if (containsBadStrlcpyStrlcatPattern(CE)) { const Expr *DstArg = CE->getArg(0); const Expr *LenArg = CE->getArg(2); - PathDiagnosticLocation Loc = - PathDiagnosticLocation::createBegin(LenArg, BR.getSourceManager(), AC); + PathDiagnosticLocation Loc = PathDiagnosticLocation::createBegin( + LenArg, BR.getSourceManager(), AC); StringRef DstName = getPrintableName(DstArg); SmallString<256> S; llvm::raw_svector_ostream os(S); - os << "The third argument allows to potentially copy more bytes than it should. "; + os << "The third argument allows to potentially copy more bytes than it " + "should. "; os << "Replace with the value "; if (!DstName.empty()) - os << "sizeof(" << DstName << ")"; + os << "sizeof(" << DstName << ")"; else - os << "sizeof()"; + os << "sizeof()"; os << " or lower"; BR.EmitBasicReport(FD, Checker, "Anti-pattern in the argument", - "C String API", os.str(), Loc, - LenArg->getSourceRange()); + "C String API", os.str(), Loc, + LenArg->getSourceRange()); } } @@ -276,16 +279,15 @@ void WalkAST::VisitChildren(Stmt *S) { } namespace { -class CStringSyntaxChecker: public Checker { +class CStringSyntaxChecker : public Checker { public: - - void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr, - BugReporter &BR) const { + void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr, + BugReporter &BR) const { WalkAST walker(this, BR, Mgr.getAnalysisDeclContext(D)); walker.Visit(D->getBody()); } }; -} +} // namespace void ento::registerCStringSyntaxChecker(CheckerManager &mgr) { mgr.registerChecker(); diff --git a/clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp index 24776338ce10b..85f90b009a679 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp @@ -31,7 +31,7 @@ class CXXSelfAssignmentChecker : public Checker { CXXSelfAssignmentChecker(); void checkBeginFunction(CheckerContext &C) const; }; -} +} // namespace CXXSelfAssignmentChecker::CXXSelfAssignmentChecker() {} @@ -46,14 +46,13 @@ void CXXSelfAssignmentChecker::checkBeginFunction(CheckerContext &C) const { return; auto &State = C.getState(); auto &SVB = C.getSValBuilder(); - auto ThisVal = - State->getSVal(SVB.getCXXThis(MD, LCtx->getStackFrame())); + auto ThisVal = State->getSVal(SVB.getCXXThis(MD, LCtx->getStackFrame())); auto Param = SVB.makeLoc(State->getRegion(MD->getParamDecl(0), LCtx)); auto ParamVal = State->getSVal(Param); ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal, LCtx); const NoteTag *SelfAssignTag = - C.getNoteTag([MD](PathSensitiveBugReport &BR) -> std::string { + C.getNoteTag([MD](PathSensitiveBugReport &BR) -> std::string { SmallString<256> Msg; llvm::raw_svector_ostream Out(Msg); Out << "Assuming " << MD->getParamDecl(0)->getName() << " == *this"; @@ -63,7 +62,7 @@ void CXXSelfAssignmentChecker::checkBeginFunction(CheckerContext &C) const { ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal, LCtx); const NoteTag *NonSelfAssignTag = - C.getNoteTag([MD](PathSensitiveBugReport &BR) -> std::string { + C.getNoteTag([MD](PathSensitiveBugReport &BR) -> std::string { SmallString<256> Msg; llvm::raw_svector_ostream Out(Msg); Out << "Assuming " << MD->getParamDecl(0)->getName() << " != *this"; diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index f2e1f69c32cfd..2e09d5d287355 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -117,8 +117,7 @@ class CallAndMessageChecker void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg, ExplodedNode *N) const; - void HandleNilReceiver(CheckerContext &C, - ProgramStateRef state, + void HandleNilReceiver(CheckerContext &C, ProgramStateRef state, const ObjCMethodCall &msg) const; void LazyInit_BT(const char *desc, std::unique_ptr &BT) const { @@ -138,7 +137,8 @@ void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C, if (!N) return; - auto R = std::make_unique(*BT, BT->getDescription(), N); + auto R = + std::make_unique(*BT, BT->getDescription(), N); if (BadE) { R->addRange(BadE->getSourceRange()); if (BadE->isGLValue()) @@ -194,7 +194,7 @@ bool CallAndMessageChecker::uninitRefOrPointer( return false; // No parameter declaration available, i.e. variadic function argument. - if(!ParamDecl) + if (!ParamDecl) return false; // If parameter is declared as pointer to const in function declaration, @@ -212,7 +212,7 @@ bool CallAndMessageChecker::uninitRefOrPointer( } else return false; - if(!ParamDecl->getType()->getPointeeType().isConstQualified()) + if (!ParamDecl->getType()->getPointeeType().isConstQualified()) return false; if (const MemRegion *SValMemRegion = V.getAsRegion()) { @@ -275,16 +275,10 @@ class FindUninitializedField { }; } // namespace -bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C, - SVal V, - SourceRange ArgRange, - const Expr *ArgEx, - int ArgumentNumber, - bool CheckUninitFields, - const CallEvent &Call, - std::unique_ptr &BT, - const ParmVarDecl *ParamDecl - ) const { +bool CallAndMessageChecker::PreVisitProcessArg( + CheckerContext &C, SVal V, SourceRange ArgRange, const Expr *ArgEx, + int ArgumentNumber, bool CheckUninitFields, const CallEvent &Call, + std::unique_ptr &BT, const ParmVarDecl *ParamDecl) const { const char *BD = "Uninitialized argument value"; if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD, @@ -338,7 +332,9 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C, os << " (e.g., via the field chain: '"; bool first = true; for (SmallVectorImpl::iterator - DI = F.FieldChain.begin(), DE = F.FieldChain.end(); DI!=DE;++DI){ + DI = F.FieldChain.begin(), + DE = F.FieldChain.end(); + DI != DE; ++DI) { if (first) first = false; else @@ -606,7 +602,8 @@ void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg, } assert(BT && "Unknown message kind."); - auto R = std::make_unique(*BT, BT->getDescription(), N); + auto R = std::make_unique( + *BT, BT->getDescription(), N); const ObjCMessageExpr *ME = msg.getOriginExpr(); R->addRange(ME->getReceiverRange()); @@ -666,7 +663,7 @@ void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C, static bool supportsNilWithFloatRet(const llvm::Triple &triple) { return (triple.getVendor() == llvm::Triple::Apple && (triple.isiOS() || triple.isWatchOS() || - !triple.isMacOSXVersionLT(10,5))); + !triple.isMacOSXVersionLT(10, 5))); } void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C, @@ -689,19 +686,18 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C, } // Other cases: check if sizeof(return type) > sizeof(void*) - if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap() - .isConsumedExpr(Msg.getOriginExpr())) { + if (CanRetTy != Ctx.VoidTy && + C.getLocationContext()->getParentMap().isConsumedExpr( + Msg.getOriginExpr())) { // Compute: sizeof(void *) and sizeof(return type) const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy); const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy); - if (CanRetTy.getTypePtr()->isReferenceType()|| + if (CanRetTy.getTypePtr()->isReferenceType() || (voidPtrSize < returnTypeSize && !(supportsNilWithFloatRet(Ctx.getTargetInfo().getTriple()) && - (Ctx.FloatTy == CanRetTy || - Ctx.DoubleTy == CanRetTy || - Ctx.LongDoubleTy == CanRetTy || - Ctx.LongLongTy == CanRetTy || + (Ctx.FloatTy == CanRetTy || Ctx.DoubleTy == CanRetTy || + Ctx.LongDoubleTy == CanRetTy || Ctx.LongLongTy == CanRetTy || Ctx.UnsignedLongLongTy == CanRetTy)))) { if (ExplodedNode *N = C.generateErrorNode(state, &Tag)) emitNilReceiverBug(C, Msg, N); diff --git a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp index a50772f881f7d..c89d89e673678 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp @@ -23,13 +23,13 @@ using namespace clang; using namespace ento; namespace { -class CastSizeChecker : public Checker< check::PreStmt > { +class CastSizeChecker : public Checker> { const BugType BT{this, "Cast region with wrong size."}; public: void checkPreStmt(const CastExpr *CE, CheckerContext &C) const; }; -} +} // namespace /// Check if we are casting to a struct with a flexible array at the end. /// \code @@ -64,7 +64,7 @@ static bool evenFlexibleArraySize(ASTContext &Ctx, CharUnits RegionSize, const Type *ElemType = Last->getType()->getArrayElementTypeNoTypeQual(); CharUnits FlexSize; if (const ConstantArrayType *ArrayTy = - Ctx.getAsConstantArrayType(Last->getType())) { + Ctx.getAsConstantArrayType(Last->getType())) { FlexSize = Ctx.getTypeSizeInChars(ElemType); if (ArrayTy->getSize() == 1 && TypeSize > FlexSize) TypeSize -= FlexSize; @@ -86,7 +86,8 @@ static bool evenFlexibleArraySize(ASTContext &Ctx, CharUnits RegionSize, return Left % FlexSize == 0; } -void CastSizeChecker::checkPreStmt(const CastExpr *CE,CheckerContext &C) const { +void CastSizeChecker::checkPreStmt(const CastExpr *CE, + CheckerContext &C) const { const Expr *E = CE->getSubExpr(); ASTContext &Ctx = C.getASTContext(); QualType ToTy = Ctx.getCanonicalType(CE->getType()); diff --git a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp index e674ec43bcd9d..43922d3735e1a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -34,7 +34,7 @@ class CastToStructVisitor : public RecursiveASTVisitor { : BR(B), Checker(Checker), AC(A) {} bool VisitCastExpr(const CastExpr *CE); }; -} +} // namespace bool CastToStructVisitor::VisitCastExpr(const CastExpr *CE) { const Expr *E = CE->getSubExpr(); @@ -62,12 +62,13 @@ bool CastToStructVisitor::VisitCastExpr(const CastExpr *CE) { if (!OrigPointeeTy->isRecordType()) { SourceRange Sr[1] = {CE->getSourceRange()}; PathDiagnosticLocation Loc(CE, BR.getSourceManager(), AC); - BR.EmitBasicReport( - AC->getDecl(), Checker, "Cast from non-struct type to struct type", - categories::LogicError, "Casting a non-structure type to a structure " - "type and accessing a field can lead to memory " - "access errors or data corruption.", - Loc, Sr); + BR.EmitBasicReport(AC->getDecl(), Checker, + "Cast from non-struct type to struct type", + categories::LogicError, + "Casting a non-structure type to a structure " + "type and accessing a field can lead to memory " + "access errors or data corruption.", + Loc, Sr); } else { // Don't warn when size of data is unknown. const auto *U = dyn_cast(E); @@ -83,8 +84,7 @@ bool CastToStructVisitor::VisitCastExpr(const CastExpr *CE) { if (!VD || VD->getType()->isReferenceType()) return true; - if (ToPointeeTy->isIncompleteType() || - OrigPointeeTy->isIncompleteType()) + if (ToPointeeTy->isIncompleteType() || OrigPointeeTy->isIncompleteType()) return true; // Warn when there is widening cast. diff --git a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp index f02d20d45678b..5389766d7ab3a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp @@ -138,8 +138,7 @@ static const NoteTag *getNoteTag(CheckerContext &C, static const NoteTag *getNoteTag(CheckerContext &C, SmallVector CastToTyVec, - const Expr *Object, - bool IsKnownCast) { + const Expr *Object, bool IsKnownCast) { Object = Object->IgnoreParenImpCasts(); return C.getNoteTag( @@ -161,14 +160,15 @@ static const NoteTag *getNoteTag(CheckerContext &C, Out << " is"; bool First = true; - for (QualType CastToTy: CastToTyVec) { + for (QualType CastToTy : CastToTyVec) { std::string CastToName = CastToTy->getAsCXXRecordDecl() ? CastToTy->getAsCXXRecordDecl()->getNameAsString() : CastToTy.getAsString(); - Out << ' ' << ((CastToTyVec.size() == 1) ? "not" : - (First ? "neither" : "nor")) << " a '" << CastToName - << '\''; + Out << ' ' + << ((CastToTyVec.size() == 1) ? "not" + : (First ? "neither" : "nor")) + << " a '" << CastToName << '\''; First = false; } @@ -266,7 +266,7 @@ static void addInstanceOfTransition(const CallEvent &Call, for (unsigned idx = 0; idx < FD->getTemplateSpecializationArgs()->size() - 1; ++idx) { TemplateArgument CastToTempArg = - FD->getTemplateSpecializationArgs()->get(idx); + FD->getTemplateSpecializationArgs()->get(idx); switch (CastToTempArg.getKind()) { default: return; @@ -274,7 +274,7 @@ static void addInstanceOfTransition(const CallEvent &Call, CastToTyVec.push_back(CastToTempArg.getAsType()); break; case TemplateArgument::Pack: - for (TemplateArgument ArgInPack: CastToTempArg.pack_elements()) + for (TemplateArgument ArgInPack : CastToTempArg.pack_elements()) CastToTyVec.push_back(ArgInPack.getAsType()); break; } @@ -286,7 +286,7 @@ static void addInstanceOfTransition(const CallEvent &Call, bool Success = false; bool IsAnyKnown = false; - for (QualType CastToTy: CastToTyVec) { + for (QualType CastToTy : CastToTyVec) { if (CastFromTy->isPointerType()) CastToTy = C.getASTContext().getPointerType(CastToTy); else if (CastFromTy->isReferenceType()) @@ -295,7 +295,7 @@ static void addInstanceOfTransition(const CallEvent &Call, return; const DynamicCastInfo *CastInfo = - getDynamicCastInfo(State, MR, CastFromTy, CastToTy); + getDynamicCastInfo(State, MR, CastFromTy, CastToTy); bool CastSucceeds; if (CastInfo) @@ -313,11 +313,11 @@ static void addInstanceOfTransition(const CallEvent &Call, if (CastSucceeds) { Success = true; - C.addTransition( - NewState->BindExpr(Call.getOriginExpr(), C.getLocationContext(), - C.getSValBuilder().makeTruthVal(true)), - getNoteTag(C, CastInfo, CastToTy, Call.getArgExpr(0), true, - IsKnownCast)); + C.addTransition(NewState->BindExpr(Call.getOriginExpr(), + C.getLocationContext(), + C.getSValBuilder().makeTruthVal(true)), + getNoteTag(C, CastInfo, CastToTy, Call.getArgExpr(0), + true, IsKnownCast)); if (IsKnownCast) return; } else if (CastInfo && CastInfo->succeeds()) { @@ -327,10 +327,10 @@ static void addInstanceOfTransition(const CallEvent &Call, } if (!Success) { - C.addTransition( - State->BindExpr(Call.getOriginExpr(), C.getLocationContext(), - C.getSValBuilder().makeTruthVal(false)), - getNoteTag(C, CastToTyVec, Call.getArgExpr(0), IsAnyKnown)); + C.addTransition(State->BindExpr(Call.getOriginExpr(), + C.getLocationContext(), + C.getSValBuilder().makeTruthVal(false)), + getNoteTag(C, CastToTyVec, Call.getArgExpr(0), IsAnyKnown)); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp index 978bc0bb082f8..eb3552c2c7abb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -27,14 +27,14 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/Analysis/PathDiagnostic.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" +#include "clang/Analysis/PathDiagnostic.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -93,10 +93,8 @@ namespace { class ObjCDeallocChecker : public Checker, check::PreObjCMessage, check::PostObjCMessage, - check::PreCall, - check::BeginFunction, check::EndFunction, - eval::Assume, - check::PointerEscape, + check::PreCall, check::BeginFunction, check::EndFunction, + eval::Assume, check::PointerEscape, check::PreStmt> { mutable const IdentifierInfo *NSObjectII = nullptr; @@ -116,7 +114,7 @@ class ObjCDeallocChecker categories::MemoryRefCount}; public: - void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& Mgr, + void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager &Mgr, BugReporter &BR) const; void checkBeginFunction(CheckerContext &Ctx) const; void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const; @@ -149,7 +147,7 @@ class ObjCDeallocChecker const ObjCIvarRegion *getIvarRegionForIvarSymbol(SymbolRef IvarSym) const; SymbolRef getInstanceSymbolFromIvarSymbol(SymbolRef IvarSym) const; - const ObjCPropertyImplDecl* + const ObjCPropertyImplDecl * findPropertyOnDeallocatingInstance(SymbolRef IvarSym, CheckerContext &C) const; @@ -183,13 +181,11 @@ class ObjCDeallocChecker }; } // End anonymous namespace. - /// Maps from the symbol for a class instance to the set of /// symbols remaining that must be released in -dealloc. REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(SymbolSet, SymbolRef) REGISTER_MAP_WITH_PROGRAMSTATE(UnreleasedIvarMap, SymbolRef, SymbolSet) - /// An AST check that diagnose when the class requires a -dealloc method and /// is missing one. void ObjCDeallocChecker::checkASTDecl(const ObjCImplementationDecl *D, @@ -234,7 +230,7 @@ void ObjCDeallocChecker::checkASTDecl(const ObjCImplementationDecl *D, } if (!MD) { // No dealloc found. - const char* Name = "Missing -dealloc"; + const char *Name = "Missing -dealloc"; std::string Buf; llvm::raw_string_ostream OS(Buf); @@ -256,8 +252,7 @@ void ObjCDeallocChecker::checkASTDecl(const ObjCImplementationDecl *D, /// If this is the beginning of -dealloc, mark the values initially stored in /// instance variables that must be released by the end of -dealloc /// as unreleased in the state. -void ObjCDeallocChecker::checkBeginFunction( - CheckerContext &C) const { +void ObjCDeallocChecker::checkBeginFunction(CheckerContext &C) const { initIdentifierInfoAndSelectors(C.getASTContext()); // Only do this if the current method is -dealloc. @@ -333,8 +328,8 @@ ObjCDeallocChecker::getInstanceSymbolFromIvarSymbol(SymbolRef IvarSym) const { /// If we are in -dealloc or -dealloc is on the stack, handle the call if it is /// a release or a nilling-out property setter. -void ObjCDeallocChecker::checkPreObjCMessage( - const ObjCMethodCall &M, CheckerContext &C) const { +void ObjCDeallocChecker::checkPreObjCMessage(const ObjCMethodCall &M, + CheckerContext &C) const { // Only run if -dealloc is on the stack. SVal DeallocedInstance; if (!instanceDeallocIsOnStack(C, DeallocedInstance)) @@ -352,7 +347,7 @@ void ObjCDeallocChecker::checkPreObjCMessage( if (ReleasedValue) { // An instance variable symbol was released with -release: // [_property release]; - if (diagnoseExtraRelease(ReleasedValue,M, C)) + if (diagnoseExtraRelease(ReleasedValue, M, C)) return; } else { // An instance variable symbol was released nilling out its property: @@ -385,8 +380,8 @@ void ObjCDeallocChecker::checkPreCall(const CallEvent &Call, } /// If the message was a call to '[super dealloc]', diagnose any missing /// releases. -void ObjCDeallocChecker::checkPostObjCMessage( - const ObjCMethodCall &M, CheckerContext &C) const { +void ObjCDeallocChecker::checkPostObjCMessage(const ObjCMethodCall &M, + CheckerContext &C) const { // We perform this check post-message so that if the super -dealloc // calls a helper method and that this class overrides, any ivars released in // the helper method will be recorded before checking. @@ -396,14 +391,14 @@ void ObjCDeallocChecker::checkPostObjCMessage( /// Check for missing releases even when -dealloc does not call /// '[super dealloc]'. -void ObjCDeallocChecker::checkEndFunction( - const ReturnStmt *RS, CheckerContext &C) const { +void ObjCDeallocChecker::checkEndFunction(const ReturnStmt *RS, + CheckerContext &C) const { diagnoseMissingReleases(C); } /// Check for missing releases on early return. -void ObjCDeallocChecker::checkPreStmt( - const ReturnStmt *RS, CheckerContext &C) const { +void ObjCDeallocChecker::checkPreStmt(const ReturnStmt *RS, + CheckerContext &C) const { diagnoseMissingReleases(C); } @@ -479,7 +474,6 @@ ProgramStateRef ObjCDeallocChecker::checkPointerEscape( State = State->remove(Sym); } - SymbolRef InstanceSymbol = getInstanceSymbolFromIvarSymbol(Sym); if (!InstanceSymbol) continue; @@ -573,8 +567,7 @@ void ObjCDeallocChecker::diagnoseMissingReleases(CheckerContext &C) const { assert(PropDecl->getSetterKind() == ObjCPropertyDecl::Copy || PropDecl->getSetterKind() == ObjCPropertyDecl::Retain); - OS << "The '" << *IvarDecl << "' ivar in '" << *ImplDecl - << "' was "; + OS << "The '" << *IvarDecl << "' ivar in '" << *ImplDecl << "' was "; if (PropDecl->getSetterKind() == ObjCPropertyDecl::Retain) OS << "retained"; @@ -685,13 +678,11 @@ bool ObjCDeallocChecker::diagnoseExtraRelease(SymbolRef ReleasedValue, assert(PropDecl->getSetterKind() == ObjCPropertyDecl::Weak || (PropDecl->getSetterKind() == ObjCPropertyDecl::Assign && !PropDecl->isReadOnly()) || - isReleasedByCIFilterDealloc(PropImpl) - ); + isReleasedByCIFilterDealloc(PropImpl)); const ObjCImplDecl *Container = getContainingObjCImpl(C.getLocationContext()); - OS << "The '" << *PropImpl->getPropertyIvarDecl() - << "' ivar in '" << *Container; - + OS << "The '" << *PropImpl->getPropertyIvarDecl() << "' ivar in '" + << *Container; if (isReleasedByCIFilterDealloc(PropImpl)) { OS << "' will be released by '-[CIFilter dealloc]' but also released here"; @@ -703,7 +694,7 @@ bool ObjCDeallocChecker::diagnoseExtraRelease(SymbolRef ReleasedValue, else OS << "an assign, readwrite"; - OS << " property but was released in 'dealloc'"; + OS << " property but was released in 'dealloc'"; } auto BR = std::make_unique(ExtraReleaseBugType, @@ -757,8 +748,7 @@ bool ObjCDeallocChecker::diagnoseMistakenDealloc(SymbolRef DeallocedValue, return true; } -void ObjCDeallocChecker::initIdentifierInfoAndSelectors( - ASTContext &Ctx) const { +void ObjCDeallocChecker::initIdentifierInfoAndSelectors(ASTContext &Ctx) const { if (NSObjectII) return; @@ -775,8 +765,7 @@ void ObjCDeallocChecker::initIdentifierInfoAndSelectors( } /// Returns true if M is a call to '[super dealloc]'. -bool ObjCDeallocChecker::isSuperDeallocMessage( - const ObjCMethodCall &M) const { +bool ObjCDeallocChecker::isSuperDeallocMessage(const ObjCMethodCall &M) const { if (M.getOriginExpr()->getReceiverKind() != ObjCMessageExpr::SuperInstance) return false; @@ -1001,7 +990,7 @@ bool ObjCDeallocChecker::instanceDeallocIsOnStack(const CheckerContext &C, bool ObjCDeallocChecker::classHasSeparateTeardown( const ObjCInterfaceDecl *ID) const { // Suppress if the class is not a subclass of NSObject. - for ( ; ID ; ID = ID->getSuperClass()) { + for (; ID; ID = ID->getSuperClass()) { IdentifierInfo *II = ID->getIdentifier(); if (II == NSObjectII) @@ -1040,7 +1029,7 @@ bool ObjCDeallocChecker::isReleasedByCIFilterDealloc( const ObjCInterfaceDecl *ID = PropImpl->getPropertyIvarDecl()->getContainingInterface(); - for ( ; ID ; ID = ID->getSuperClass()) { + for (; ID; ID = ID->getSuperClass()) { IdentifierInfo *II = ID->getIdentifier(); if (II == CIFilterII) return true; diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp index c8fe5c2ccf384..1bba08626525c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp @@ -12,11 +12,11 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/Analysis/PathDiagnostic.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Type.h" +#include "clang/Analysis/PathDiagnostic.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "llvm/ADT/DenseMap.h" @@ -30,7 +30,7 @@ static bool AreTypesCompatible(QualType Derived, QualType Ancestor, // Right now don't compare the compatibility of pointers. That involves // looking at subtyping relationships. FIXME: Future patch. - if (Derived->isAnyPointerType() && Ancestor->isAnyPointerType()) + if (Derived->isAnyPointerType() && Ancestor->isAnyPointerType()) return true; return C.typesAreCompatible(Derived, Ancestor); @@ -49,8 +49,7 @@ static void CompareReturnTypes(const ObjCMethodDecl *MethDerived, std::string sbuf; llvm::raw_string_ostream os(sbuf); - os << "The Objective-C class '" - << *MethDerived->getClassInterface() + os << "The Objective-C class '" << *MethDerived->getClassInterface() << "', which is derived from class '" << *MethAncestor->getClassInterface() << "', defines the instance method '"; @@ -64,8 +63,7 @@ static void CompareReturnTypes(const ObjCMethodDecl *MethDerived, "behavior for clients of these classes."; PathDiagnosticLocation MethDLoc = - PathDiagnosticLocation::createBegin(MethDerived, - BR.getSourceManager()); + PathDiagnosticLocation::createBegin(MethDerived, BR.getSourceManager()); BR.EmitBasicReport( MethDerived, Checker, "Incompatible instance method return type", @@ -86,7 +84,7 @@ static void CheckObjCInstMethSignature(const ObjCImplementationDecl *ID, ASTContext &Ctx = BR.getContext(); // Build a DenseMap of the methods for quick querying. - typedef llvm::DenseMap MapTy; + typedef llvm::DenseMap MapTy; MapTy IMeths; unsigned NumMethods = 0; @@ -122,15 +120,15 @@ static void CheckObjCInstMethSignature(const ObjCImplementationDecl *ID, //===----------------------------------------------------------------------===// namespace { -class ObjCMethSigsChecker : public Checker< - check::ASTDecl > { +class ObjCMethSigsChecker + : public Checker> { public: - void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& mgr, + void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager &mgr, BugReporter &BR) const { CheckObjCInstMethSignature(D, BR, this); } }; -} +} // namespace void ento::registerObjCMethSigsChecker(CheckerManager &mgr) { mgr.registerChecker(); diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp index 17af1aebd6d2a..d0651ce2d48e7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/StmtVisitor.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Basic/TargetInfo.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -26,11 +26,8 @@ using namespace ento; static bool isArc4RandomAvailable(const ASTContext &Ctx) { const llvm::Triple &T = Ctx.getTargetInfo().getTriple(); - return T.getVendor() == llvm::Triple::Apple || - T.isOSFreeBSD() || - T.isOSNetBSD() || - T.isOSOpenBSD() || - T.isOSDragonFly(); + return T.getVendor() == llvm::Triple::Apple || T.isOSFreeBSD() || + T.isOSNetBSD() || T.isOSOpenBSD() || T.isOSDragonFly(); } namespace { @@ -68,7 +65,7 @@ struct ChecksFilter { class WalkAST : public StmtVisitor { BugReporter &BR; - AnalysisDeclContext* AC; + AnalysisDeclContext *AC; enum { num_setids = 6 }; IdentifierInfo *II_setid[num_setids]; @@ -76,17 +73,15 @@ class WalkAST : public StmtVisitor { const ChecksFilter &filter; public: - WalkAST(BugReporter &br, AnalysisDeclContext* ac, - const ChecksFilter &f) - : BR(br), AC(ac), II_setid(), - CheckRand(isArc4RandomAvailable(BR.getContext())), - filter(f) {} + WalkAST(BugReporter &br, AnalysisDeclContext *ac, const ChecksFilter &f) + : BR(br), AC(ac), II_setid(), + CheckRand(isArc4RandomAvailable(BR.getContext())), filter(f) {} // Statement visitor methods. void VisitCallExpr(CallExpr *CE); void VisitObjCMessageExpr(ObjCMessageExpr *CE); void VisitForStmt(ForStmt *S); - void VisitCompoundStmt (CompoundStmt *S); + void VisitCompoundStmt(CompoundStmt *S); void VisitStmt(Stmt *S) { VisitChildren(S); } void VisitChildren(Stmt *S); @@ -137,7 +132,7 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { // Get the name of the callee. If it's a builtin, strip off the prefix. IdentifierInfo *II = FD->getIdentifier(); - if (!II) // if no identifier, not a simple C function + if (!II) // if no identifier, not a simple C function return; StringRef Name = II->getName(); Name.consume_front("__builtin_"); @@ -223,8 +218,8 @@ void WalkAST::VisitForStmt(ForStmt *FS) { // Returns either 'x' or 'y', depending on which one of them is incremented // in 'expr', or nullptr if none of them is incremented. -static const DeclRefExpr* -getIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y) { +static const DeclRefExpr *getIncrementedVar(const Expr *expr, const VarDecl *x, + const VarDecl *y) { expr = expr->IgnoreParenCasts(); if (const BinaryOperator *B = dyn_cast(expr)) { @@ -248,7 +243,8 @@ getIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y) { if (const UnaryOperator *U = dyn_cast(expr)) return U->isIncrementDecrementOp() - ? getIncrementedVar(U->getSubExpr(), x, y) : nullptr; + ? getIncrementedVar(U->getSubExpr(), x, y) + : nullptr; return nullptr; } @@ -289,9 +285,9 @@ void WalkAST::checkLoopConditionForFloat(const ForStmt *FS) { // Are we comparing variables? const DeclRefExpr *drLHS = - dyn_cast(B->getLHS()->IgnoreParenLValueCasts()); + dyn_cast(B->getLHS()->IgnoreParenLValueCasts()); const DeclRefExpr *drRHS = - dyn_cast(B->getRHS()->IgnoreParenLValueCasts()); + dyn_cast(B->getRHS()->IgnoreParenLValueCasts()); // Does at least one of the variables have a floating point type? drLHS = drLHS && drLHS->getType()->isRealFloatingType() ? drLHS : nullptr; @@ -332,10 +328,9 @@ void WalkAST::checkLoopConditionForFloat(const ForStmt *FS) { const char *bugType = "Floating point variable used as loop counter"; PathDiagnosticLocation FSLoc = - PathDiagnosticLocation::createBegin(FS, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), filter.checkName_FloatLoopCounter, - bugType, "Security", os.str(), - FSLoc, ranges); + PathDiagnosticLocation::createBegin(FS, BR.getSourceManager(), AC); + BR.EmitBasicReport(AC->getDecl(), filter.checkName_FloatLoopCounter, bugType, + "Security", os.str(), FSLoc, ranges); } //===----------------------------------------------------------------------===// @@ -372,12 +367,12 @@ void WalkAST::checkCall_bcmp(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_bcmp, "Use of deprecated function in call to 'bcmp()'", "Security", - "The bcmp() function is obsoleted by memcmp().", - CELoc, CE->getCallee()->getSourceRange()); + "The bcmp() function is obsoleted by memcmp().", CELoc, + CE->getCallee()->getSourceRange()); } //===----------------------------------------------------------------------===// @@ -414,7 +409,7 @@ void WalkAST::checkCall_bcopy(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_bcopy, "Use of deprecated function in call to 'bcopy()'", "Security", @@ -455,15 +450,14 @@ void WalkAST::checkCall_bzero(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_bzero, "Use of deprecated function in call to 'bzero()'", "Security", - "The bzero() function is obsoleted by memset().", - CELoc, CE->getCallee()->getSourceRange()); + "The bzero() function is obsoleted by memset().", CELoc, + CE->getCallee()->getSourceRange()); } - //===----------------------------------------------------------------------===// // Check: Any use of 'gets' is insecure. Most man pages literally says this. // @@ -493,10 +487,9 @@ void WalkAST::checkCall_gets(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_gets, - "Potential buffer overflow in call to 'gets'", - "Security", + "Potential buffer overflow in call to 'gets'", "Security", "Call to function 'gets' is extremely insecure as it can " "always result in a buffer overflow", CELoc, CE->getCallee()->getSourceRange()); @@ -533,10 +526,9 @@ void WalkAST::checkCall_getpw(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_getpw, - "Potential buffer overflow in call to 'getpw'", - "Security", + "Potential buffer overflow in call to 'getpw'", "Security", "The getpw() function is dangerous as it may overflow the " "provided buffer. It is obsoleted by getpwuid().", CELoc, CE->getCallee()->getSourceRange()); @@ -556,7 +548,7 @@ void WalkAST::checkCall_mktemp(const CallExpr *CE, const FunctionDecl *FD) { } const FunctionProtoType *FPT = FD->getType()->getAs(); - if(!FPT) + if (!FPT) return; // Verify that the function takes a single argument. @@ -574,7 +566,7 @@ void WalkAST::checkCall_mktemp(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_mktemp, "Potential insecure temporary file in call 'mktemp'", "Security", @@ -594,23 +586,22 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) { StringRef Name = FD->getIdentifier()->getName(); std::pair ArgSuffix = - llvm::StringSwitch >(Name) - .Case("mktemp", std::make_pair(0,-1)) - .Case("mkstemp", std::make_pair(0,-1)) - .Case("mkdtemp", std::make_pair(0,-1)) - .Case("mkstemps", std::make_pair(0,1)) - .Default(std::make_pair(-1, -1)); + llvm::StringSwitch>(Name) + .Case("mktemp", std::make_pair(0, -1)) + .Case("mkstemp", std::make_pair(0, -1)) + .Case("mkdtemp", std::make_pair(0, -1)) + .Case("mkstemps", std::make_pair(0, 1)) + .Default(std::make_pair(-1, -1)); assert(ArgSuffix.first >= 0 && "Unsupported function"); // Check if the number of arguments is consistent with out expectations. unsigned numArgs = CE->getNumArgs(); - if ((signed) numArgs <= ArgSuffix.first) + if ((signed)numArgs <= ArgSuffix.first) return; - const StringLiteral *strArg = - dyn_cast(CE->getArg((unsigned)ArgSuffix.first) - ->IgnoreParenImpCasts()); + const StringLiteral *strArg = dyn_cast( + CE->getArg((unsigned)ArgSuffix.first)->IgnoreParenImpCasts()); // Currently we only handle string literals. It is possible to do better, // either by looking at references to const variables, or by doing real @@ -634,23 +625,26 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) { // FIXME: Issue a warning. if (Result.isNegative()) return; - suffix = (unsigned) Result.getZExtValue(); + suffix = (unsigned)Result.getZExtValue(); n = (n > suffix) ? n - suffix : 0; } for (unsigned i = 0; i < n; ++i) - if (str[i] == 'X') ++numX; + if (str[i] == 'X') + ++numX; if (numX >= 6) return; // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); SmallString<512> buf; llvm::raw_svector_ostream out(buf); - out << "Call to '" << Name << "' should have at least 6 'X's in the" - " format string to be secure (" << numX << " 'X'"; + out << "Call to '" << Name + << "' should have at least 6 'X's in the" + " format string to be secure (" + << numX << " 'X'"; if (numX != 1) out << 's'; out << " seen"; @@ -662,8 +656,8 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) { } out << ')'; BR.EmitBasicReport(AC->getDecl(), filter.checkName_mkstemp, - "Insecure temporary file creation", "Security", - out.str(), CELoc, strArg->getSourceRange()); + "Insecure temporary file creation", "Security", out.str(), + CELoc, strArg->getSourceRange()); } //===----------------------------------------------------------------------===// @@ -693,7 +687,7 @@ void WalkAST::checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy, "Potential insecure memory buffer bounds restriction in " "call 'strcpy'", @@ -721,7 +715,7 @@ void WalkAST::checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy, "Potential insecure memory buffer bounds restriction in " "call 'strcat'", @@ -870,7 +864,7 @@ void WalkAST::checkCall_rand(const CallExpr *CE, const FunctionDecl *FD) { if (!PT) return; - if (! PT->getPointeeType()->isIntegralOrUnscopedEnumerationType()) + if (!PT->getPointeeType()->isIntegralOrUnscopedEnumerationType()) return; } else if (FTP->getNumParams() != 0) return; @@ -887,7 +881,7 @@ void WalkAST::checkCall_rand(const CallExpr *CE, const FunctionDecl *FD) { << " Use 'arc4random' instead"; PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand, os1.str(), "Security", os2.str(), CELoc, CE->getCallee()->getSourceRange()); @@ -908,13 +902,14 @@ void WalkAST::checkCall_random(const CallExpr *CE, const FunctionDecl *FD) { // Issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand, "'random' is not a secure random number generator", "Security", "The 'random' function produces a sequence of values that " "an adversary may be able to predict. Use 'arc4random' " - "instead", CELoc, CE->getCallee()->getSourceRange()); + "instead", + CELoc, CE->getCallee()->getSourceRange()); } //===----------------------------------------------------------------------===// @@ -928,7 +923,7 @@ void WalkAST::checkCall_vfork(const CallExpr *CE, const FunctionDecl *FD) { // All calls to vfork() are insecure, issue a warning. PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_vfork, "Potential insecure implementation-specific behavior in " "call 'vfork'", @@ -1014,10 +1009,8 @@ void WalkAST::checkUncheckedReturnValue(CallExpr *CE) { return; if (II_setid[0] == nullptr) { - static const char * const identifiers[num_setids] = { - "setuid", "setgid", "seteuid", "setegid", - "setreuid", "setregid" - }; + static const char *const identifiers[num_setids] = { + "setuid", "setgid", "seteuid", "setegid", "setreuid", "setregid"}; for (size_t i = 0; i < num_setids; i++) II_setid[i] = &BR.getContext().Idents.get(identifiers[i]); @@ -1059,7 +1052,7 @@ void WalkAST::checkUncheckedReturnValue(CallExpr *CE) { << "', the following code may execute with unexpected privileges"; PathDiagnosticLocation CELoc = - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), filter.checkName_UncheckedReturn, os1.str(), "Security", os2.str(), CELoc, CE->getCallee()->getSourceRange()); @@ -1074,13 +1067,13 @@ class SecuritySyntaxChecker : public Checker { public: ChecksFilter filter; - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { WalkAST walker(BR, mgr.getAnalysisDeclContext(D), filter); walker.Visit(D->getBody()); } }; -} +} // namespace void ento::registerSecuritySyntaxChecker(CheckerManager &mgr) { mgr.registerChecker(); diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp index 0d2551f11583e..c0b82cb015be4 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/StmtVisitor.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -24,7 +24,7 @@ namespace { class WalkAST : public StmtVisitor { BugReporter &BR; const CheckerBase *Checker; - AnalysisDeclContext* AC; + AnalysisDeclContext *AC; public: WalkAST(BugReporter &br, const CheckerBase *checker, AnalysisDeclContext *ac) @@ -33,7 +33,7 @@ class WalkAST : public StmtVisitor { void VisitStmt(Stmt *S) { VisitChildren(S); } void VisitChildren(Stmt *S); }; -} +} // namespace void WalkAST::VisitChildren(Stmt *S) { for (Stmt *Child : S->children()) @@ -46,8 +46,8 @@ void WalkAST::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { if (E->getKind() != UETT_SizeOf) return; - // If an explicit type is used in the code, usually the coder knows what they are - // doing. + // If an explicit type is used in the code, usually the coder knows what they + // are doing. if (E->isArgumentType()) return; @@ -62,7 +62,7 @@ void WalkAST::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { return; PathDiagnosticLocation ELoc = - PathDiagnosticLocation::createBegin(E, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(E, BR.getSourceManager(), AC); BR.EmitBasicReport(AC->getDecl(), Checker, "Potential unintended use of sizeof() on pointer type", categories::LogicError, @@ -79,13 +79,13 @@ void WalkAST::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { namespace { class SizeofPointerChecker : public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { WalkAST walker(BR, this, mgr.getAnalysisDeclContext(D)); walker.Visit(D->getBody()); } }; -} +} // namespace void ento::registerSizeofPointerChecker(CheckerManager &mgr) { mgr.registerChecker(); diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp index 3e5e2b9139149..690f8df8af99d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp @@ -33,30 +33,17 @@ namespace ento { /// checking. /// /// \sa CheckerContext -class CheckerDocumentation : public Checker< check::PreStmt, - check::PostStmt, - check::PreObjCMessage, - check::PostObjCMessage, - check::ObjCMessageNil, - check::PreCall, - check::PostCall, - check::BranchCondition, - check::NewAllocator, - check::Location, - check::Bind, - check::DeadSymbols, - check::BeginFunction, - check::EndFunction, - check::EndAnalysis, - check::EndOfTranslationUnit, - eval::Call, - eval::Assume, - check::LiveSymbols, - check::RegionChanges, - check::PointerEscape, - check::ConstPointerEscape, - check::Event, - check::ASTDecl > { +class CheckerDocumentation + : public Checker< + check::PreStmt, check::PostStmt, + check::PreObjCMessage, check::PostObjCMessage, check::ObjCMessageNil, + check::PreCall, check::PostCall, check::BranchCondition, + check::NewAllocator, check::Location, check::Bind, check::DeadSymbols, + check::BeginFunction, check::EndFunction, check::EndAnalysis, + check::EndOfTranslationUnit, eval::Call, eval::Assume, + check::LiveSymbols, check::RegionChanges, check::PointerEscape, + check::ConstPointerEscape, check::Event, + check::ASTDecl> { public: /// Pre-visit the Statement. /// @@ -179,7 +166,6 @@ class CheckerDocumentation : public Checker< check::PreStmt, /// check::DeadSymbols void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const {} - /// Called when the analyzer core starts analyzing a function, /// regardless of whether it is analyzed at the top level or is inlined. /// @@ -202,16 +188,14 @@ class CheckerDocumentation : public Checker< check::PreStmt, /// See IdempotentOperationChecker for a usage example. /// /// check::EndAnalysis - void checkEndAnalysis(ExplodedGraph &G, - BugReporter &BR, + void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng) const {} /// Called after analysis of a TranslationUnit is complete. /// /// check::EndOfTranslationUnit void checkEndOfTranslationUnit(const TranslationUnitDecl *TU, - AnalysisManager &Mgr, - BugReporter &BR) const {} + AnalysisManager &Mgr, BugReporter &BR) const {} /// Evaluates function call. /// @@ -236,9 +220,10 @@ class CheckerDocumentation : public Checker< check::PreStmt, /// performed on the symbols of interest and change the state accordingly. /// /// eval::Assume - ProgramStateRef evalAssume(ProgramStateRef State, - SVal Cond, - bool Assumption) const { return State; } + ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond, + bool Assumption) const { + return State; + } /// Allows modifying SymbolReaper object. For example, checkers can explicitly /// register symbols of interest as live. These symbols will not be marked @@ -270,12 +255,11 @@ class CheckerDocumentation : public Checker< check::PreStmt, /// /// check::RegionChanges ProgramStateRef - checkRegionChanges(ProgramStateRef State, - const InvalidatedSymbols *Invalidated, - ArrayRef ExplicitRegions, - ArrayRef Regions, - const LocationContext *LCtx, - const CallEvent *Call) const { + checkRegionChanges(ProgramStateRef State, + const InvalidatedSymbols *Invalidated, + ArrayRef ExplicitRegions, + ArrayRef Regions, + const LocationContext *LCtx, const CallEvent *Call) const { return State; } @@ -304,9 +288,9 @@ class CheckerDocumentation : public Checker< check::PreStmt, /// Note: in most cases checkPointerEscape callback is sufficient. /// \sa checkPointerEscape ProgramStateRef checkConstPointerEscape(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind) const { + const InvalidatedSymbols &Escaped, + const CallEvent *Call, + PointerEscapeKind Kind) const { return State; } @@ -321,14 +305,12 @@ class CheckerDocumentation : public Checker< check::PreStmt, /// FunctionDecl. /// /// check::ASTDecl - void checkASTDecl(const FunctionDecl *D, - AnalysisManager &Mgr, + void checkASTDecl(const FunctionDecl *D, AnalysisManager &Mgr, BugReporter &BR) const {} }; void CheckerDocumentation::checkPostStmt(const DeclStmt *DS, - CheckerContext &C) const { -} + CheckerContext &C) const {} } // end namespace ento } // end namespace clang diff --git a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp index be7be15022d36..fa26821ee7ab6 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp @@ -30,7 +30,7 @@ namespace { enum Kind { NO_CHROOT, ROOT_CHANGED, JAIL_ENTERED }; bool isRootChanged(intptr_t k) { return k == ROOT_CHANGED; } -//bool isJailEntered(intptr_t k) { return k == JAIL_ENTERED; } +// bool isJailEntered(intptr_t k) { return k == JAIL_ENTERED; } // This checker checks improper use of chroot. // The state transition: @@ -82,7 +82,7 @@ void ChrootChecker::evalChroot(const CallEvent &Call, CheckerContext &C) const { // Once encouter a chroot(), set the enum value ROOT_CHANGED directly in // the GDM. - state = Mgr.addGDM(state, ChrootChecker::getTag(), (void*) ROOT_CHANGED); + state = Mgr.addGDM(state, ChrootChecker::getTag(), (void *)ROOT_CHANGED); C.addTransition(state); } @@ -101,11 +101,11 @@ void ChrootChecker::evalChdir(const CallEvent &Call, CheckerContext &C) const { if (const MemRegion *R = ArgVal.getAsRegion()) { R = R->StripCasts(); - if (const StringRegion* StrRegion= dyn_cast(R)) { - const StringLiteral* Str = StrRegion->getStringLiteral(); + if (const StringRegion *StrRegion = dyn_cast(R)) { + const StringLiteral *Str = StrRegion->getStringLiteral(); if (Str->getString() == "/") - state = Mgr.addGDM(state, ChrootChecker::getTag(), - (void*) JAIL_ENTERED); + state = + Mgr.addGDM(state, ChrootChecker::getTag(), (void *)JAIL_ENTERED); } } @@ -120,9 +120,9 @@ void ChrootChecker::checkPreCall(const CallEvent &Call, return; // If jail state is ROOT_CHANGED, generate BugReport. - void *const* k = C.getState()->FindGDM(ChrootChecker::getTag()); + void *const *k = C.getState()->FindGDM(ChrootChecker::getTag()); if (k) - if (isRootChanged((intptr_t) *k)) + if (isRootChanged((intptr_t)*k)) if (ExplodedNode *N = C.generateNonFatalErrorNode()) { constexpr llvm::StringLiteral Msg = "No call of chdir(\"/\") immediately after chroot"; diff --git a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp index 6692a45a09f77..781445cf5580c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -12,9 +12,9 @@ /// //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Analysis/CloneDetection.h" #include "clang/Basic/Diagnostic.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -191,14 +191,16 @@ void ento::registerCloneChecker(CheckerManager &Mgr) { Checker, "MinimumCloneComplexity"); if (Checker->MinComplexity < 0) - Mgr.reportInvalidCheckerOptionValue( - Checker, "MinimumCloneComplexity", "a non-negative value"); + Mgr.reportInvalidCheckerOptionValue(Checker, "MinimumCloneComplexity", + "a non-negative value"); - Checker->ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption( - Checker, "ReportNormalClones"); + Checker->ReportNormalClones = + Mgr.getAnalyzerOptions().getCheckerBooleanOption(Checker, + "ReportNormalClones"); - Checker->IgnoredFilesPattern = Mgr.getAnalyzerOptions() - .getCheckerStringOption(Checker, "IgnoredFilesPattern"); + Checker->IgnoredFilesPattern = + Mgr.getAnalyzerOptions().getCheckerStringOption(Checker, + "IgnoredFilesPattern"); } bool ento::shouldRegisterCloneChecker(const CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp index 65a2ec4076fdf..cdba82cee3b45 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp @@ -31,7 +31,7 @@ using namespace iterator; namespace { class ContainerModeling - : public Checker { + : public Checker { void handleBegin(CheckerContext &C, const Expr *CE, SVal RetVal, SVal Cont) const; @@ -135,16 +135,16 @@ ProgramStateRef reassignAllIteratorPositionsUnless(ProgramStateRef State, SymbolRef Offset, BinaryOperator::Opcode Opc); ProgramStateRef rebaseSymbolInIteratorPositionsIf( - ProgramStateRef State, SValBuilder &SVB, SymbolRef OldSym, - SymbolRef NewSym, SymbolRef CondSym, BinaryOperator::Opcode Opc); + ProgramStateRef State, SValBuilder &SVB, SymbolRef OldSym, SymbolRef NewSym, + SymbolRef CondSym, BinaryOperator::Opcode Opc); SymbolRef rebaseSymbol(ProgramStateRef State, SValBuilder &SVB, SymbolRef Expr, - SymbolRef OldSym, SymbolRef NewSym); + SymbolRef OldSym, SymbolRef NewSym); bool hasLiveIterators(ProgramStateRef State, const MemRegion *Cont); } // namespace void ContainerModeling::checkPostCall(const CallEvent &Call, - CheckerContext &C) const { + CheckerContext &C) const { const auto *Func = dyn_cast_or_null(Call.getDecl()); if (!Func) return; @@ -156,7 +156,7 @@ void ContainerModeling::checkPostCall(const CallEvent &Call, const auto *InstCall = cast(&Call); if (cast(Func)->isMoveAssignmentOperator()) { handleAssignment(C, InstCall->getCXXThisVal(), Call.getOriginExpr(), - Call.getArgSVal(0)); + Call.getArgSVal(0)); return; } @@ -212,12 +212,12 @@ void ContainerModeling::checkLiveSymbols(ProgramStateRef State, const auto CData = Cont.second; if (CData.getBegin()) { SR.markLive(CData.getBegin()); - if(const auto *SIE = dyn_cast(CData.getBegin())) + if (const auto *SIE = dyn_cast(CData.getBegin())) SR.markLive(SIE->getLHS()); } if (CData.getEnd()) { SR.markLive(CData.getEnd()); - if(const auto *SIE = dyn_cast(CData.getEnd())) + if (const auto *SIE = dyn_cast(CData.getEnd())) SR.markLive(SIE->getLHS()); } } @@ -243,7 +243,7 @@ void ContainerModeling::checkDeadSymbols(SymbolReaper &SR, } void ContainerModeling::handleBegin(CheckerContext &C, const Expr *CE, - SVal RetVal, SVal Cont) const { + SVal RetVal, SVal Cont) const { const auto *ContReg = Cont.getAsRegion(); if (!ContReg) return; @@ -265,7 +265,7 @@ void ContainerModeling::handleBegin(CheckerContext &C, const Expr *CE, } void ContainerModeling::handleEnd(CheckerContext &C, const Expr *CE, - SVal RetVal, SVal Cont) const { + SVal RetVal, SVal Cont) const { const auto *ContReg = Cont.getAsRegion(); if (!ContReg) return; @@ -399,8 +399,7 @@ void ContainerModeling::handleClear(CheckerContext &C, SVal Cont, } } } - const NoteTag *ChangeTag = - getChangeTag(C, "became empty", ContReg, ContE); + const NoteTag *ChangeTag = getChangeTag(C, "became empty", ContReg, ContE); State = invalidateAllIteratorPositions(State, ContReg); C.addTransition(State, ChangeTag); } @@ -434,12 +433,12 @@ void ContainerModeling::handlePushBack(CheckerContext &C, SVal Cont, auto &BVF = SymMgr.getBasicVals(); auto &SVB = C.getSValBuilder(); const auto newEndSym = - SVB.evalBinOp(State, BO_Add, - nonloc::SymbolVal(EndSym), - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), - SymMgr.getType(EndSym)).getAsSymbol(); + SVB.evalBinOp(State, BO_Add, nonloc::SymbolVal(EndSym), + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), + SymMgr.getType(EndSym)) + .getAsSymbol(); const NoteTag *ChangeTag = - getChangeTag(C, "extended to the back by 1 position", ContReg, ContE); + getChangeTag(C, "extended to the back by 1 position", ContReg, ContE); State = setContainerData(State, ContReg, CData->newEnd(newEndSym)); C.addTransition(State, ChangeTag); } @@ -463,12 +462,12 @@ void ContainerModeling::handlePopBack(CheckerContext &C, SVal Cont, auto &BVF = SymMgr.getBasicVals(); auto &SVB = C.getSValBuilder(); const auto BackSym = - SVB.evalBinOp(State, BO_Sub, - nonloc::SymbolVal(EndSym), - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), - SymMgr.getType(EndSym)).getAsSymbol(); + SVB.evalBinOp(State, BO_Sub, nonloc::SymbolVal(EndSym), + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), + SymMgr.getType(EndSym)) + .getAsSymbol(); const NoteTag *ChangeTag = - getChangeTag(C, "shrank from the back by 1 position", ContReg, ContE); + getChangeTag(C, "shrank from the back by 1 position", ContReg, ContE); // For vector-like and deque-like containers invalidate the last and the // past-end iterator positions. For list-like containers only invalidate // the last position @@ -508,12 +507,12 @@ void ContainerModeling::handlePushFront(CheckerContext &C, SVal Cont, auto &BVF = SymMgr.getBasicVals(); auto &SVB = C.getSValBuilder(); const auto newBeginSym = - SVB.evalBinOp(State, BO_Sub, - nonloc::SymbolVal(BeginSym), - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), - SymMgr.getType(BeginSym)).getAsSymbol(); - const NoteTag *ChangeTag = - getChangeTag(C, "extended to the front by 1 position", ContReg, ContE); + SVB.evalBinOp(State, BO_Sub, nonloc::SymbolVal(BeginSym), + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), + SymMgr.getType(BeginSym)) + .getAsSymbol(); + const NoteTag *ChangeTag = getChangeTag( + C, "extended to the front by 1 position", ContReg, ContE); State = setContainerData(State, ContReg, CData->newBegin(newBeginSym)); C.addTransition(State, ChangeTag); } @@ -545,12 +544,12 @@ void ContainerModeling::handlePopFront(CheckerContext &C, SVal Cont, auto &BVF = SymMgr.getBasicVals(); auto &SVB = C.getSValBuilder(); const auto newBeginSym = - SVB.evalBinOp(State, BO_Add, - nonloc::SymbolVal(BeginSym), - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), - SymMgr.getType(BeginSym)).getAsSymbol(); + SVB.evalBinOp(State, BO_Add, nonloc::SymbolVal(BeginSym), + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), + SymMgr.getType(BeginSym)) + .getAsSymbol(); const NoteTag *ChangeTag = - getChangeTag(C, "shrank from the front by 1 position", ContReg, ContE); + getChangeTag(C, "shrank from the front by 1 position", ContReg, ContE); State = setContainerData(State, ContReg, CData->newBegin(newBeginSym)); C.addTransition(State, ChangeTag); } @@ -658,7 +657,7 @@ void ContainerModeling::handleErase(CheckerContext &C, SVal Cont, SVal Iter1, } void ContainerModeling::handleEraseAfter(CheckerContext &C, SVal Cont, - SVal Iter) const { + SVal Iter) const { auto State = C.getState(); const auto *Pos = getIteratorPosition(State, Iter); if (!Pos) @@ -670,10 +669,10 @@ void ContainerModeling::handleEraseAfter(CheckerContext &C, SVal Cont, auto &BVF = SymMgr.getBasicVals(); auto &SVB = C.getSValBuilder(); const auto NextSym = - SVB.evalBinOp(State, BO_Add, - nonloc::SymbolVal(Pos->getOffset()), - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), - SymMgr.getType(Pos->getOffset())).getAsSymbol(); + SVB.evalBinOp(State, BO_Add, nonloc::SymbolVal(Pos->getOffset()), + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))), + SymMgr.getType(Pos->getOffset())) + .getAsSymbol(); State = invalidateIteratorPositions(State, NextSym, BO_EQ); C.addTransition(State); } @@ -700,9 +699,9 @@ const NoteTag *ContainerModeling::getChangeTag(CheckerContext &C, // First try to get the name of the variable from the region if (const auto *DR = dyn_cast(ContReg)) { Name = DR->getDecl()->getName(); - // If the region is not a `DeclRegion` then use the expression instead + // If the region is not a `DeclRegion` then use the expression instead } else if (const auto *DRE = - dyn_cast(ContE->IgnoreParenCasts())) { + dyn_cast(ContE->IgnoreParenCasts())) { Name = DRE->getDecl()->getName(); } @@ -713,14 +712,14 @@ const NoteTag *ContainerModeling::getChangeTag(CheckerContext &C, SmallString<256> Msg; llvm::raw_svector_ostream Out(Msg); - Out << "Container " << (!Name.empty() ? ("'" + Name.str() + "' ") : "" ) + Out << "Container " << (!Name.empty() ? ("'" + Name.str() + "' ") : "") << Text; return std::string(Out.str()); }); } void ContainerModeling::printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep) const { + const char *NL, const char *Sep) const { auto ContMap = State->get(); if (!ContMap.isEmpty()) { @@ -845,8 +844,8 @@ ProgramStateRef createContainerBegin(ProgramStateRef State, return State; auto &SymMgr = State->getSymbolManager(); - const SymbolConjured *Sym = SymMgr.conjureSymbol(E, LCtx, T, BlockCount, - "begin"); + const SymbolConjured *Sym = + SymMgr.conjureSymbol(E, LCtx, T, BlockCount, "begin"); State = assumeNoOverflow(State, Sym, 4); if (CDataPtr) { @@ -868,8 +867,8 @@ ProgramStateRef createContainerEnd(ProgramStateRef State, const MemRegion *Cont, return State; auto &SymMgr = State->getSymbolManager(); - const SymbolConjured *Sym = SymMgr.conjureSymbol(E, LCtx, T, BlockCount, - "end"); + const SymbolConjured *Sym = + SymMgr.conjureSymbol(E, LCtx, T, BlockCount, "end"); State = assumeNoOverflow(State, Sym, 4); if (CDataPtr) { @@ -989,7 +988,7 @@ ProgramStateRef reassignAllIteratorPositionsUnless(ProgramStateRef State, BinaryOperator::Opcode Opc) { auto MatchContAndCompare = [&](const IteratorPosition &Pos) { return Pos.getContainer() == Cont && - !compare(State, Pos.getOffset(), Offset, Opc); + !compare(State, Pos.getOffset(), Offset, Opc); }; auto ReAssign = [&](const IteratorPosition &Pos) { return Pos.reAssign(NewCont); @@ -1001,14 +1000,13 @@ ProgramStateRef reassignAllIteratorPositionsUnless(ProgramStateRef State, // `OldSym - Int` to `NewSym - Int` and `OldSym` to `NewSym` in any iterator // position offsets where `CondSym` is true. ProgramStateRef rebaseSymbolInIteratorPositionsIf( - ProgramStateRef State, SValBuilder &SVB, SymbolRef OldSym, - SymbolRef NewSym, SymbolRef CondSym, BinaryOperator::Opcode Opc) { + ProgramStateRef State, SValBuilder &SVB, SymbolRef OldSym, SymbolRef NewSym, + SymbolRef CondSym, BinaryOperator::Opcode Opc) { auto LessThanEnd = [&](const IteratorPosition &Pos) { return compare(State, Pos.getOffset(), CondSym, Opc); }; auto RebaseSymbol = [&](const IteratorPosition &Pos) { - return Pos.setTo(rebaseSymbol(State, SVB, Pos.getOffset(), OldSym, - NewSym)); + return Pos.setTo(rebaseSymbol(State, SVB, Pos.getOffset(), OldSym, NewSym)); }; return processIteratorPositions(State, LessThanEnd, RebaseSymbol); } @@ -1020,16 +1018,18 @@ SymbolRef rebaseSymbol(ProgramStateRef State, SValBuilder &SVB, SymbolRef OrigExpr, SymbolRef OldExpr, SymbolRef NewSym) { auto &SymMgr = SVB.getSymbolManager(); - auto Diff = SVB.evalBinOpNN(State, BO_Sub, nonloc::SymbolVal(OrigExpr), - nonloc::SymbolVal(OldExpr), - SymMgr.getType(OrigExpr)); + auto Diff = + SVB.evalBinOpNN(State, BO_Sub, nonloc::SymbolVal(OrigExpr), + nonloc::SymbolVal(OldExpr), SymMgr.getType(OrigExpr)); const auto DiffInt = Diff.getAs(); if (!DiffInt) return OrigExpr; - return SVB.evalBinOpNN(State, BO_Add, *DiffInt, nonloc::SymbolVal(NewSym), - SymMgr.getType(OrigExpr)).getAsSymbol(); + return SVB + .evalBinOpNN(State, BO_Add, *DiffInt, nonloc::SymbolVal(NewSym), + SymMgr.getType(OrigExpr)) + .getAsSymbol(); } bool hasLiveIterators(ProgramStateRef State, const MemRegion *Cont) { @@ -1061,7 +1061,7 @@ bool ento::shouldRegisterContainerModeling(const CheckerManager &mgr) { if (!mgr.getAnalyzerOptions().ShouldAggressivelySimplifyBinaryOperation) { mgr.getASTContext().getDiagnostics().Report( diag::err_analyzer_checker_incompatible_analyzer_option) - << "aggressive-binary-operation-simplification" << "false"; + << "aggressive-binary-operation-simplification" << "false"; return false; } diff --git a/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp index eca8d3cc07229..bb95746f3c325 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp @@ -23,8 +23,8 @@ // is an alternative to those checks. // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -52,7 +52,7 @@ class ConversionChecker : public Checker> { void reportBug(ExplodedNode *N, const Expr *E, CheckerContext &C, const char Msg[]) const; }; -} +} // namespace void ConversionChecker::checkPreStmt(const ImplicitCastExpr *Cast, CheckerContext &C) const { diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp index 86f446fc411ca..f9358b0780de1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -59,8 +59,7 @@ class EHCodeVisitor : public RecursiveASTVisitor { return true; } - EHCodeVisitor(llvm::DenseSet &S) : - inEH(false), S(S) {} + EHCodeVisitor(llvm::DenseSet &S) : inEH(false), S(S) {} }; // FIXME: Eventually migrate into its own file, and have it managed by @@ -68,9 +67,10 @@ class EHCodeVisitor : public RecursiveASTVisitor { class ReachableCode { const CFG &cfg; llvm::BitVector reachable; + public: ReachableCode(const CFG &cfg) - : cfg(cfg), reachable(cfg.getNumBlockIDs(), false) {} + : cfg(cfg), reachable(cfg.getNumBlockIDs(), false) {} void computeReachableBlocks(); @@ -78,13 +78,13 @@ class ReachableCode { return reachable[block->getBlockID()]; } }; -} +} // namespace void ReachableCode::computeReachableBlocks() { if (!cfg.getNumBlockIDs()) return; - SmallVector worklist; + SmallVector worklist; worklist.push_back(&cfg.getEntry()); while (!worklist.empty()) { @@ -130,11 +130,11 @@ class DeadStoresChecker : public Checker { class DeadStoreObs : public LiveVariables::Observer { const CFG &cfg; ASTContext &Ctx; - BugReporter& BR; + BugReporter &BR; const DeadStoresChecker *Checker; - AnalysisDeclContext* AC; - ParentMap& Parents; - llvm::SmallPtrSet Escaped; + AnalysisDeclContext *AC; + ParentMap &Parents; + llvm::SmallPtrSet Escaped; std::unique_ptr reachableCode; const CFGBlock *currentBlock; std::unique_ptr> InEH; @@ -189,8 +189,8 @@ class DeadStoreObs : public LiveVariables::Observer { return false; } - void Report(const VarDecl *V, DeadStoreKind dsk, - PathDiagnosticLocation L, SourceRange R) { + void Report(const VarDecl *V, DeadStoreKind dsk, PathDiagnosticLocation L, + SourceRange R) { if (Escaped.count(V)) return; @@ -214,48 +214,49 @@ class DeadStoreObs : public LiveVariables::Observer { SmallVector Fixits; switch (dsk) { - case DeadInit: { - BugType = "Dead initialization"; - os << "Value stored to '" << *V - << "' during its initialization is never read"; - - ASTContext &ACtx = V->getASTContext(); - if (Checker->ShowFixIts) { - if (V->getInit()->HasSideEffects(ACtx, - /*IncludePossibleEffects=*/true)) { - break; - } - SourceManager &SM = ACtx.getSourceManager(); - const LangOptions &LO = ACtx.getLangOpts(); - SourceLocation L1 = - Lexer::findNextToken( - V->getTypeSourceInfo()->getTypeLoc().getEndLoc(), - SM, LO)->getEndLoc(); - SourceLocation L2 = - Lexer::getLocForEndOfToken(V->getInit()->getEndLoc(), 1, SM, LO); - Fixits.push_back(FixItHint::CreateRemoval({L1, L2})); + case DeadInit: { + BugType = "Dead initialization"; + os << "Value stored to '" << *V + << "' during its initialization is never read"; + + ASTContext &ACtx = V->getASTContext(); + if (Checker->ShowFixIts) { + if (V->getInit()->HasSideEffects(ACtx, + /*IncludePossibleEffects=*/true)) { + break; } - break; + SourceManager &SM = ACtx.getSourceManager(); + const LangOptions &LO = ACtx.getLangOpts(); + SourceLocation L1 = + Lexer::findNextToken( + V->getTypeSourceInfo()->getTypeLoc().getEndLoc(), SM, LO) + ->getEndLoc(); + SourceLocation L2 = + Lexer::getLocForEndOfToken(V->getInit()->getEndLoc(), 1, SM, LO); + Fixits.push_back(FixItHint::CreateRemoval({L1, L2})); } + break; + } + + case DeadIncrement: + BugType = "Dead increment"; + [[fallthrough]]; + case Standard: + if (!BugType) + BugType = "Dead assignment"; + os << "Value stored to '" << *V << "' is never read"; + break; - case DeadIncrement: - BugType = "Dead increment"; - [[fallthrough]]; - case Standard: - if (!BugType) BugType = "Dead assignment"; - os << "Value stored to '" << *V << "' is never read"; - break; - - // eg.: f((x = foo())) - case Enclosing: - if (!Checker->WarnForDeadNestedAssignments) - return; - BugType = "Dead nested assignment"; - os << "Although the value stored to '" << *V - << "' is used in the enclosing expression, the value is never " - "actually read from '" - << *V << "'"; - break; + // eg.: f((x = foo())) + case Enclosing: + if (!Checker->WarnForDeadNestedAssignments) + return; + BugType = "Dead nested assignment"; + os << "Although the value stored to '" << *V + << "' is used in the enclosing expression, the value is never " + "actually read from '" + << *V << "'"; + break; } BR.EmitBasicReport(AC->getDecl(), Checker, BugType, categories::UnusedCode, @@ -278,23 +279,23 @@ class DeadStoreObs : public LiveVariables::Observer { VD->hasAttr())) { PathDiagnosticLocation ExLoc = - PathDiagnosticLocation::createBegin(Ex, BR.getSourceManager(), AC); + PathDiagnosticLocation::createBegin(Ex, BR.getSourceManager(), AC); Report(VD, dsk, ExLoc, Val->getSourceRange()); } } void CheckDeclRef(const DeclRefExpr *DR, const Expr *Val, DeadStoreKind dsk, - const LiveVariables::LivenessValues& Live) { + const LiveVariables::LivenessValues &Live) { if (const VarDecl *VD = dyn_cast(DR->getDecl())) CheckVarDecl(VD, DR, Val, dsk, Live); } - bool isIncrement(VarDecl *VD, const BinaryOperator* B) { + bool isIncrement(VarDecl *VD, const BinaryOperator *B) { if (B->isCompoundAssignmentOp()) return true; const Expr *RHS = B->getRHS()->IgnoreParenCasts(); - const BinaryOperator* BRHS = dyn_cast(RHS); + const BinaryOperator *BRHS = dyn_cast(RHS); if (!BRHS) return false; @@ -323,8 +324,9 @@ class DeadStoreObs : public LiveVariables::Observer { // Only cover dead stores from regular assignments. ++/-- dead stores // have never flagged a real bug. - if (const BinaryOperator* B = dyn_cast(S)) { - if (!B->isAssignmentOp()) return; // Skip non-assignments. + if (const BinaryOperator *B = dyn_cast(S)) { + if (!B->isAssignmentOp()) + return; // Skip non-assignments. if (DeclRefExpr *DR = dyn_cast(B->getLHS())) if (VarDecl *VD = dyn_cast(DR->getDecl())) { @@ -348,14 +350,14 @@ class DeadStoreObs : public LiveVariables::Observer { return; // Otherwise, issue a warning. - DeadStoreKind dsk = Parents.isConsumedExpr(B) - ? Enclosing - : (isIncrement(VD,B) ? DeadIncrement : Standard); + DeadStoreKind dsk = + Parents.isConsumedExpr(B) + ? Enclosing + : (isIncrement(VD, B) ? DeadIncrement : Standard); CheckVarDecl(VD, DR, B->getRHS(), dsk, Live); } - } - else if (const UnaryOperator* U = dyn_cast(S)) { + } else if (const UnaryOperator *U = dyn_cast(S)) { if (!U->isIncrementOp() || U->isPrefix()) return; @@ -367,8 +369,7 @@ class DeadStoreObs : public LiveVariables::Observer { if (const DeclRefExpr *DR = dyn_cast(Ex)) CheckDeclRef(DR, U, DeadIncrement, Live); - } - else if (const DeclStmt *DS = dyn_cast(S)) + } else if (const DeclStmt *DS = dyn_cast(S)) // Iterate through the decls. Warn if any initializers are complex // expressions that are not live (never used). for (const auto *DI : DS->decls()) { @@ -399,8 +400,7 @@ class DeadStoreObs : public LiveVariables::Observer { // A dead initialization is a variable that is dead after it // is initialized. We don't flag warnings for those variables // marked 'unused' or 'objc_precise_lifetime'. - if (!isLive(Live, V) && - !V->hasAttr() && + if (!isLive(Live, V) && !V->hasAttr() && !V->hasAttr()) { // Special case: check for initializations with constants. // @@ -435,7 +435,7 @@ class DeadStoreObs : public LiveVariables::Observer { } PathDiagnosticLocation Loc = - PathDiagnosticLocation::create(V, BR.getSourceManager()); + PathDiagnosticLocation::create(V, BR.getSourceManager()); Report(V, DeadInit, Loc, V->getInit()->getSourceRange()); } } @@ -477,7 +477,7 @@ class DeadStoreObs : public LiveVariables::Observer { namespace { class FindEscaped { public: - llvm::SmallPtrSet Escaped; + llvm::SmallPtrSet Escaped; void operator()(const Stmt *S) { // Check for '&'. Any VarDecl whose address has been taken we treat as @@ -501,7 +501,7 @@ class FindEscaped { } // Treat local variables captured by reference in C++ lambdas as escaped. - void findLambdaReferenceCaptures(const LambdaExpr *LE) { + void findLambdaReferenceCaptures(const LambdaExpr *LE) { const CXXRecordDecl *LambdaClass = LE->getLambdaClass(); llvm::DenseMap CaptureFields; FieldDecl *ThisCaptureField; @@ -524,7 +524,6 @@ class FindEscaped { }; } // end anonymous namespace - //===----------------------------------------------------------------------===// // DeadStoresChecker //===----------------------------------------------------------------------===// @@ -558,8 +557,7 @@ void ento::registerDeadStoresChecker(CheckerManager &Mgr) { const AnalyzerOptions &AnOpts = Mgr.getAnalyzerOptions(); Chk->WarnForDeadNestedAssignments = AnOpts.getCheckerBooleanOption(Chk, "WarnForDeadNestedAssignments"); - Chk->ShowFixIts = - AnOpts.getCheckerBooleanOption(Chk, "ShowFixIts"); + Chk->ShowFixIts = AnOpts.getCheckerBooleanOption(Chk, "ShowFixIts"); } bool ento::shouldRegisterDeadStoresChecker(const CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp index 04bbe85473c0e..c087ca6a1a29f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp @@ -10,12 +10,12 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Analysis/Analyses/Dominators.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/CallGraph.h" -#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" @@ -32,7 +32,7 @@ using namespace ento; namespace { class DominatorsTreeDumper : public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) { CFGDomTree Dom; @@ -41,7 +41,7 @@ class DominatorsTreeDumper : public Checker { } } }; -} +} // namespace void ento::registerDominatorsTreeDumper(CheckerManager &mgr) { mgr.registerChecker(); @@ -58,7 +58,7 @@ bool ento::shouldRegisterDominatorsTreeDumper(const CheckerManager &mgr) { namespace { class PostDominatorsTreeDumper : public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) { CFGPostDomTree Dom; @@ -67,7 +67,7 @@ class PostDominatorsTreeDumper : public Checker { } } }; -} +} // namespace void ento::registerPostDominatorsTreeDumper(CheckerManager &mgr) { mgr.registerChecker(); @@ -84,7 +84,7 @@ bool ento::shouldRegisterPostDominatorsTreeDumper(const CheckerManager &mgr) { namespace { class ControlDependencyTreeDumper : public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) { ControlDependencyCalculator Dom(AC->getCFG()); @@ -92,13 +92,14 @@ class ControlDependencyTreeDumper : public Checker { } } }; -} +} // namespace void ento::registerControlDependencyTreeDumper(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterControlDependencyTreeDumper(const CheckerManager &mgr) { +bool ento::shouldRegisterControlDependencyTreeDumper( + const CheckerManager &mgr) { return true; } @@ -109,14 +110,14 @@ bool ento::shouldRegisterControlDependencyTreeDumper(const CheckerManager &mgr) namespace { class LiveVariablesDumper : public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { - if (LiveVariables* L = mgr.getAnalysis(D)) { + if (LiveVariables *L = mgr.getAnalysis(D)) { L->dumpBlockLiveness(mgr.getSourceManager()); } } }; -} +} // namespace void ento::registerLiveVariablesDumper(CheckerManager &mgr) { mgr.registerChecker(); @@ -133,13 +134,13 @@ bool ento::shouldRegisterLiveVariablesDumper(const CheckerManager &mgr) { namespace { class LiveExpressionsDumper : public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr, BugReporter &BR) const { if (LiveVariables *L = Mgr.getAnalysis(D)) L->dumpExprLiveness(Mgr.getSourceManager()); } }; -} +} // namespace void ento::registerLiveExpressionsDumper(CheckerManager &mgr) { mgr.registerChecker(); @@ -156,22 +157,20 @@ bool ento::shouldRegisterLiveExpressionsDumper(const CheckerManager &mgr) { namespace { class CFGViewer : public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { if (CFG *cfg = mgr.getCFG(D)) { cfg->viewCFG(mgr.getLangOpts()); } } }; -} +} // namespace void ento::registerCFGViewer(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterCFGViewer(const CheckerManager &mgr) { - return true; -} +bool ento::shouldRegisterCFGViewer(const CheckerManager &mgr) { return true; } //===----------------------------------------------------------------------===// // CFGDumper @@ -180,7 +179,7 @@ bool ento::shouldRegisterCFGViewer(const CheckerManager &mgr) { namespace { class CFGDumper : public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { PrintingPolicy Policy(mgr.getLangOpts()); Policy.TerseOutput = true; @@ -188,36 +187,33 @@ class CFGDumper : public Checker { D->print(llvm::errs(), Policy); if (CFG *cfg = mgr.getCFG(D)) { - cfg->dump(mgr.getLangOpts(), - llvm::sys::Process::StandardErrHasColors()); + cfg->dump(mgr.getLangOpts(), llvm::sys::Process::StandardErrHasColors()); } } }; -} +} // namespace void ento::registerCFGDumper(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterCFGDumper(const CheckerManager &mgr) { - return true; -} +bool ento::shouldRegisterCFGDumper(const CheckerManager &mgr) { return true; } //===----------------------------------------------------------------------===// // CallGraphViewer //===----------------------------------------------------------------------===// namespace { -class CallGraphViewer : public Checker< check::ASTDecl > { +class CallGraphViewer : public Checker> { public: - void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, + void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager &mgr, BugReporter &BR) const { CallGraph CG; - CG.addToCallGraph(const_cast(TU)); + CG.addToCallGraph(const_cast(TU)); CG.viewGraph(); } }; -} +} // namespace void ento::registerCallGraphViewer(CheckerManager &mgr) { mgr.registerChecker(); @@ -232,16 +228,16 @@ bool ento::shouldRegisterCallGraphViewer(const CheckerManager &mgr) { //===----------------------------------------------------------------------===// namespace { -class CallGraphDumper : public Checker< check::ASTDecl > { +class CallGraphDumper : public Checker> { public: - void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager& mgr, + void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager &mgr, BugReporter &BR) const { CallGraph CG; - CG.addToCallGraph(const_cast(TU)); + CG.addToCallGraph(const_cast(TU)); CG.dump(); } }; -} +} // namespace void ento::registerCallGraphDumper(CheckerManager &mgr) { mgr.registerChecker(); @@ -256,7 +252,7 @@ bool ento::shouldRegisterCallGraphDumper(const CheckerManager &mgr) { //===----------------------------------------------------------------------===// namespace { -class ConfigDumper : public Checker< check::EndOfTranslationUnit > { +class ConfigDumper : public Checker { typedef AnalyzerOptions::ConfigTable Table; static int compareEntry(const Table::MapEntryTy *const *LHS, @@ -266,8 +262,7 @@ class ConfigDumper : public Checker< check::EndOfTranslationUnit > { public: void checkEndOfTranslationUnit(const TranslationUnitDecl *TU, - AnalysisManager& mgr, - BugReporter &BR) const { + AnalysisManager &mgr, BugReporter &BR) const { const Table &Config = mgr.options.Config; SmallVector Keys; @@ -282,7 +277,7 @@ class ConfigDumper : public Checker< check::EndOfTranslationUnit > { << '\n'; } }; -} +} // namespace void ento::registerConfigDumper(CheckerManager &mgr) { mgr.registerChecker(); @@ -297,15 +292,16 @@ bool ento::shouldRegisterConfigDumper(const CheckerManager &mgr) { //===----------------------------------------------------------------------===// namespace { -class ExplodedGraphViewer : public Checker< check::EndAnalysis > { +class ExplodedGraphViewer : public Checker { public: ExplodedGraphViewer() {} - void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const { + void checkEndAnalysis(ExplodedGraph &G, BugReporter &B, + ExprEngine &Eng) const { Eng.ViewGraph(false); } }; -} +} // namespace void ento::registerExplodedGraphViewer(CheckerManager &mgr) { mgr.registerChecker(); @@ -343,6 +339,4 @@ void ento::registerReportStmts(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterReportStmts(const CheckerManager &mgr) { - return true; -} +bool ento::shouldRegisterReportStmts(const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp index 72186a99d9435..045c618936adc 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp @@ -25,8 +25,7 @@ using namespace iterator; namespace { -class DebugContainerModeling - : public Checker { +class DebugContainerModeling : public Checker { const BugType DebugMsgBugType{this, "Checking analyzer assumptions", "debug", /*SuppressOnSink=*/true}; @@ -39,7 +38,7 @@ class DebugContainerModeling ExplodedNode *reportDebugMsg(llvm::StringRef Msg, CheckerContext &C) const; typedef void (DebugContainerModeling::*FnCheck)(const CallExpr *, - CheckerContext &) const; + CheckerContext &) const; CallDescriptionMap Callbacks = { {{{"clang_analyzer_container_begin"}, 1}, @@ -90,14 +89,13 @@ void DebugContainerModeling::analyzerContainerDataField(const CallExpr *CE, // Progpagate interestingness from the container's data (marked // interesting by an `ExprInspection` debug call to the container // itself. - const NoteTag *InterestingTag = - C.getNoteTag( - [Cont, Field](PathSensitiveBugReport &BR) -> std::string { - if (BR.isInteresting(Field)) { - BR.markInteresting(Cont); - } - return ""; - }); + const NoteTag *InterestingTag = C.getNoteTag( + [Cont, Field](PathSensitiveBugReport &BR) -> std::string { + if (BR.isInteresting(Field)) { + BR.markInteresting(Cont); + } + return ""; + }); C.addTransition(State, InterestingTag); return; } @@ -105,22 +103,21 @@ void DebugContainerModeling::analyzerContainerDataField(const CallExpr *CE, } auto &BVF = C.getSValBuilder().getBasicValueFactory(); - State = State->BindExpr(CE, C.getLocationContext(), - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0)))); + State = + State->BindExpr(CE, C.getLocationContext(), + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0)))); } void DebugContainerModeling::analyzerContainerBegin(const CallExpr *CE, CheckerContext &C) const { - analyzerContainerDataField(CE, C, [](const ContainerData *D) { - return D->getBegin(); - }); + analyzerContainerDataField( + CE, C, [](const ContainerData *D) { return D->getBegin(); }); } void DebugContainerModeling::analyzerContainerEnd(const CallExpr *CE, CheckerContext &C) const { - analyzerContainerDataField(CE, C, [](const ContainerData *D) { - return D->getEnd(); - }); + analyzerContainerDataField( + CE, C, [](const ContainerData *D) { return D->getEnd(); }); } ExplodedNode *DebugContainerModeling::reportDebugMsg(llvm::StringRef Msg, diff --git a/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp index 79ab71d7829db..4bf48b80491be 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp @@ -25,8 +25,7 @@ using namespace iterator; namespace { -class DebugIteratorModeling - : public Checker { +class DebugIteratorModeling : public Checker { const BugType DebugMsgBugType{this, "Checking analyzer assumptions", "debug", /*SuppressOnSink=*/true}; @@ -95,26 +94,35 @@ void DebugIteratorModeling::analyzerIteratorDataField(const CallExpr *CE, void DebugIteratorModeling::analyzerIteratorPosition(const CallExpr *CE, CheckerContext &C) const { auto &BVF = C.getSValBuilder().getBasicValueFactory(); - analyzerIteratorDataField(CE, C, [](const IteratorPosition *P) { - return nonloc::SymbolVal(P->getOffset()); - }, nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0)))); + analyzerIteratorDataField( + CE, C, + [](const IteratorPosition *P) { + return nonloc::SymbolVal(P->getOffset()); + }, + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0)))); } void DebugIteratorModeling::analyzerIteratorContainer(const CallExpr *CE, CheckerContext &C) const { auto &BVF = C.getSValBuilder().getBasicValueFactory(); - analyzerIteratorDataField(CE, C, [](const IteratorPosition *P) { - return loc::MemRegionVal(P->getContainer()); - }, loc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0)))); + analyzerIteratorDataField( + CE, C, + [](const IteratorPosition *P) { + return loc::MemRegionVal(P->getContainer()); + }, + loc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0)))); } void DebugIteratorModeling::analyzerIteratorValidity(const CallExpr *CE, CheckerContext &C) const { auto &BVF = C.getSValBuilder().getBasicValueFactory(); - analyzerIteratorDataField(CE, C, [&BVF](const IteratorPosition *P) { - return - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get((P->isValid())))); - }, nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0)))); + analyzerIteratorDataField( + CE, C, + [&BVF](const IteratorPosition *P) { + return nonloc::ConcreteInt( + BVF.getValue(llvm::APSInt::get((P->isValid())))); + }, + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0)))); } ExplodedNode *DebugIteratorModeling::reportDebugMsg(llvm::StringRef Msg, diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index a678c3827e7f1..4667671cec89b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -28,9 +28,8 @@ using namespace ento; namespace { class DereferenceChecker - : public Checker< check::Location, - check::Bind, - EventDispatcher > { + : public Checker> { enum DerefKind { NullPointer, UndefinedPointerValue }; BugType BT_Null{this, "Dereference of null pointer", categories::LogicError}; @@ -43,7 +42,7 @@ class DereferenceChecker bool suppressReport(CheckerContext &C, const Expr *E) const; public: - void checkLocation(SVal location, bool isLoad, const Stmt* S, + void checkLocation(SVal location, bool isLoad, const Stmt *S, CheckerContext &C) const; void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const; @@ -57,46 +56,42 @@ class DereferenceChecker }; } // end anonymous namespace -void -DereferenceChecker::AddDerefSource(raw_ostream &os, - SmallVectorImpl &Ranges, - const Expr *Ex, - const ProgramState *state, - const LocationContext *LCtx, - bool loadedFrom) { +void DereferenceChecker::AddDerefSource( + raw_ostream &os, SmallVectorImpl &Ranges, const Expr *Ex, + const ProgramState *state, const LocationContext *LCtx, bool loadedFrom) { Ex = Ex->IgnoreParenLValueCasts(); switch (Ex->getStmtClass()) { - default: - break; - case Stmt::DeclRefExprClass: { - const DeclRefExpr *DR = cast(Ex); - if (const VarDecl *VD = dyn_cast(DR->getDecl())) { - os << " (" << (loadedFrom ? "loaded from" : "from") - << " variable '" << VD->getName() << "')"; - Ranges.push_back(DR->getSourceRange()); - } - break; - } - case Stmt::MemberExprClass: { - const MemberExpr *ME = cast(Ex); - os << " (" << (loadedFrom ? "loaded from" : "via") - << " field '" << ME->getMemberNameInfo() << "')"; - SourceLocation L = ME->getMemberLoc(); - Ranges.push_back(SourceRange(L, L)); - break; - } - case Stmt::ObjCIvarRefExprClass: { - const ObjCIvarRefExpr *IV = cast(Ex); - os << " (" << (loadedFrom ? "loaded from" : "via") - << " ivar '" << IV->getDecl()->getName() << "')"; - SourceLocation L = IV->getLocation(); - Ranges.push_back(SourceRange(L, L)); - break; + default: + break; + case Stmt::DeclRefExprClass: { + const DeclRefExpr *DR = cast(Ex); + if (const VarDecl *VD = dyn_cast(DR->getDecl())) { + os << " (" << (loadedFrom ? "loaded from" : "from") << " variable '" + << VD->getName() << "')"; + Ranges.push_back(DR->getSourceRange()); } + break; + } + case Stmt::MemberExprClass: { + const MemberExpr *ME = cast(Ex); + os << " (" << (loadedFrom ? "loaded from" : "via") << " field '" + << ME->getMemberNameInfo() << "')"; + SourceLocation L = ME->getMemberLoc(); + Ranges.push_back(SourceRange(L, L)); + break; + } + case Stmt::ObjCIvarRefExprClass: { + const ObjCIvarRefExpr *IV = cast(Ex); + os << " (" << (loadedFrom ? "loaded from" : "via") << " ivar '" + << IV->getDecl()->getName() << "')"; + SourceLocation L = IV->getLocation(); + Ranges.push_back(SourceRange(L, L)); + break; + } } } -static const Expr *getDereferenceExpr(const Stmt *S, bool IsBind=false){ +static const Expr *getDereferenceExpr(const Stmt *S, bool IsBind = false) { const Expr *E = nullptr; // Walk through lvalue casts to get the original expression @@ -183,40 +178,40 @@ void DereferenceChecker::reportBug(DerefKind K, ProgramStateRef State, case Stmt::ArraySubscriptExprClass: { os << "Array access"; const ArraySubscriptExpr *AE = cast(S); - AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(), - State.get(), N->getLocationContext()); + AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(), State.get(), + N->getLocationContext()); os << DerefStr1; break; } case Stmt::OMPArraySectionExprClass: { os << "Array access"; const OMPArraySectionExpr *AE = cast(S); - AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(), - State.get(), N->getLocationContext()); + AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(), State.get(), + N->getLocationContext()); os << DerefStr1; break; } case Stmt::UnaryOperatorClass: { os << BT->getDescription(); const UnaryOperator *U = cast(S); - AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(), - State.get(), N->getLocationContext(), true); + AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(), State.get(), + N->getLocationContext(), true); break; } case Stmt::MemberExprClass: { const MemberExpr *M = cast(S); if (M->isArrow() || isDeclRefExprToReference(M->getBase())) { os << "Access to field '" << M->getMemberNameInfo() << "'" << DerefStr2; - AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(), - State.get(), N->getLocationContext(), true); + AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(), State.get(), + N->getLocationContext(), true); } break; } case Stmt::ObjCIvarRefExprClass: { const ObjCIvarRefExpr *IV = cast(S); os << "Access to instance variable '" << *IV->getDecl() << "'" << DerefStr2; - AddDerefSource(os, Ranges, IV->getBase()->IgnoreParenCasts(), - State.get(), N->getLocationContext(), true); + AddDerefSource(os, Ranges, IV->getBase()->IgnoreParenCasts(), State.get(), + N->getLocationContext(), true); break; } default: @@ -228,14 +223,15 @@ void DereferenceChecker::reportBug(DerefKind K, ProgramStateRef State, bugreporter::trackExpressionValue(N, bugreporter::getDerefExpr(S), *report); - for (SmallVectorImpl::iterator - I = Ranges.begin(), E = Ranges.end(); I!=E; ++I) + for (SmallVectorImpl::iterator I = Ranges.begin(), + E = Ranges.end(); + I != E; ++I) report->addRange(*I); C.emitReport(std::move(report)); } -void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S, +void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt *S, CheckerContext &C) const { // Check for dereference of an undefined value. if (l.isUndef()) { diff --git a/clang/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp b/clang/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp index 49486ea796c26..b07958814fad2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp @@ -1,4 +1,5 @@ -//=- DirectIvarAssignment.cpp - Check rules on ObjC properties -*- C++ ----*-==// +//=- DirectIvarAssignment.cpp - Check rules on ObjC properties -*- C++ +//----*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,10 +21,10 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/StmtVisitor.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -48,11 +49,11 @@ static bool DefaultMethodFilter(const ObjCMethodDecl *M) { M->getSelector().getNameForSlot(0).contains("Init"); } -class DirectIvarAssignment : - public Checker > { +class DirectIvarAssignment + : public Checker> { - typedef llvm::DenseMap IvarToPropertyMapTy; + typedef llvm::DenseMap + IvarToPropertyMapTy; /// A helper class, which walks the AST and locates all assignments to ivars /// in the given function. @@ -87,19 +88,19 @@ class DirectIvarAssignment : DirectIvarAssignment() : ShouldSkipMethod(&DefaultMethodFilter) {} - void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& Mgr, + void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager &Mgr, BugReporter &BR) const; }; -static const ObjCIvarDecl *findPropertyBackingIvar(const ObjCPropertyDecl *PD, - const ObjCInterfaceDecl *InterD, - ASTContext &Ctx) { +static const ObjCIvarDecl * +findPropertyBackingIvar(const ObjCPropertyDecl *PD, + const ObjCInterfaceDecl *InterD, ASTContext &Ctx) { // Check for synthesized ivars. ObjCIvarDecl *ID = PD->getPropertyIvarDecl(); if (ID) return ID; - ObjCInterfaceDecl *NonConstInterD = const_cast(InterD); + ObjCInterfaceDecl *NonConstInterD = const_cast(InterD); // Check for existing "_PropName". ID = NonConstInterD->lookupInstanceVariable(PD->getDefaultSynthIvarName(Ctx)); @@ -114,18 +115,17 @@ static const ObjCIvarDecl *findPropertyBackingIvar(const ObjCPropertyDecl *PD, } void DirectIvarAssignment::checkASTDecl(const ObjCImplementationDecl *D, - AnalysisManager& Mgr, - BugReporter &BR) const { + AnalysisManager &Mgr, + BugReporter &BR) const { const ObjCInterfaceDecl *InterD = D->getClassInterface(); - IvarToPropertyMapTy IvarToPropMap; // Find all properties for this class. for (const auto *PD : InterD->instance_properties()) { // Find the corresponding IVar. - const ObjCIvarDecl *ID = findPropertyBackingIvar(PD, InterD, - Mgr.getASTContext()); + const ObjCIvarDecl *ID = + findPropertyBackingIvar(PD, InterD, Mgr.getASTContext()); if (!ID) continue; @@ -163,12 +163,12 @@ static bool isAnnotatedToAllowDirectAssignment(const Decl *D) { } void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator( - const BinaryOperator *BO) { + const BinaryOperator *BO) { if (!BO->isAssignmentOp()) return; const ObjCIvarRefExpr *IvarRef = - dyn_cast(BO->getLHS()->IgnoreParenCasts()); + dyn_cast(BO->getLHS()->IgnoreParenCasts()); if (!IvarRef) return; @@ -205,10 +205,11 @@ void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator( } } } -} +} // namespace // Register the checker that checks for direct accesses in functions annotated -// with __attribute__((annotate("objc_no_direct_instance_variable_assignment"))). +// with +// __attribute__((annotate("objc_no_direct_instance_variable_assignment"))). static bool AttrFilter(const ObjCMethodDecl *M) { for (const auto *Ann : M->specific_attrs()) if (Ann->getAnnotation() == "objc_no_direct_instance_variable_assignment") diff --git a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp index 5496f087447fb..a05e3c49c04b9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp @@ -25,7 +25,7 @@ using namespace ento; using namespace taint; namespace { -class DivZeroChecker : public Checker< check::PreStmt > { +class DivZeroChecker : public Checker> { const BugType BT{this, "Division by zero"}; const BugType TaintBT{this, "Division by zero", categories::TaintedData}; void reportBug(StringRef Msg, ProgramStateRef StateZero, @@ -70,10 +70,7 @@ void DivZeroChecker::reportTaintBug( void DivZeroChecker::checkPreStmt(const BinaryOperator *B, CheckerContext &C) const { BinaryOperator::Opcode Op = B->getOpcode(); - if (Op != BO_Div && - Op != BO_Rem && - Op != BO_DivAssign && - Op != BO_RemAssign) + if (Op != BO_Div && Op != BO_Rem && Op != BO_DivAssign && Op != BO_RemAssign) return; if (!B->getRHS()->getType()->isScalarType()) diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp index 0ad307d3ebd50..5da9f404e1ca3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp @@ -21,8 +21,8 @@ #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" using namespace clang; @@ -58,7 +58,7 @@ class DynamicTypeChecker : public Checker> { public: void checkPostStmt(const ImplicitCastExpr *CE, CheckerContext &C) const; }; -} +} // namespace void DynamicTypeChecker::reportTypeError(QualType DynamicType, QualType StaticType, diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp index 034774a252b11..d4549638c70ca 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -49,14 +49,10 @@ REGISTER_MAP_WITH_PROGRAMSTATE(MostSpecializedTypeArgsMap, SymbolRef, const ObjCObjectPointerType *) namespace { -class DynamicTypePropagation: - public Checker< check::PreCall, - check::PostCall, - check::DeadSymbols, - check::PostStmt, - check::PostStmt, - check::PreObjCMessage, - check::PostObjCMessage > { +class DynamicTypePropagation + : public Checker, check::PostStmt, + check::PreObjCMessage, check::PostObjCMessage> { /// Return a better dynamic type if one can be derived from the cast. const ObjCObjectPointerType *getBetterObjCType(const Expr *CastE, @@ -445,8 +441,7 @@ DynamicTypePropagation::getBetterObjCType(const Expr *CastE, if (OldDTy.isNull()) { return NewTy; } - const ObjCObjectPointerType *OldTy = - OldDTy->getAs(); + const ObjCObjectPointerType *OldTy = OldDTy->getAs(); if (!OldTy) return nullptr; @@ -769,9 +764,10 @@ findMethodDecl(const ObjCMessageExpr *MessageExpr, /// Get the returned ObjCObjectPointerType by a method based on the tracked type /// information, or null pointer when the returned type is not an /// ObjCObjectPointerType. -static QualType getReturnTypeForMethod( - const ObjCMethodDecl *Method, ArrayRef TypeArgs, - const ObjCObjectPointerType *SelfType, ASTContext &C) { +static QualType getReturnTypeForMethod(const ObjCMethodDecl *Method, + ArrayRef TypeArgs, + const ObjCObjectPointerType *SelfType, + ASTContext &C) { QualType StaticResultType = Method->getReturnType(); // Is the return type declared as instance type? diff --git a/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp index 7aefcdc6d358a..ce7e8c4def956 100644 --- a/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp @@ -22,14 +22,13 @@ using namespace clang; using namespace ento; namespace { -class FixedAddressChecker - : public Checker< check::PreStmt > { +class FixedAddressChecker : public Checker> { const BugType BT{this, "Use fixed address"}; public: void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; }; -} +} // namespace void FixedAddressChecker::checkPreStmt(const BinaryOperator *B, CheckerContext &C) const { diff --git a/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp index 5637941a58f02..e9f9af4ccb28a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp @@ -28,8 +28,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -47,8 +47,7 @@ const char *WarnAtNode = "waitcall"; class GCDAntipatternChecker : public Checker { public: - void checkASTCodeBody(const Decl *D, - AnalysisManager &AM, + void checkASTCodeBody(const Decl *D, AnalysisManager &AM, BugReporter &BR) const; }; @@ -62,8 +61,8 @@ decltype(auto) equalsBoundArgDecl(int ArgIdx, const char *DeclName) { } decltype(auto) bindAssignmentToDecl(const char *DeclName) { - return hasLHS(ignoringParenImpCasts( - declRefExpr(to(varDecl().bind(DeclName))))); + return hasLHS( + ignoringParenImpCasts(declRefExpr(to(varDecl().bind(DeclName))))); } /// The pattern is very common in tests, and it is OK to use it there. @@ -71,7 +70,7 @@ decltype(auto) bindAssignmentToDecl(const char *DeclName) { /// (used in XCTest), and a class name contains "mock" or "test" (used in /// helpers which are not tests themselves, but used exclusively in tests). static bool isTest(const Decl *D) { - if (const auto* ND = dyn_cast(D)) { + if (const auto *ND = dyn_cast(D)) { std::string DeclName = ND->getNameAsString(); if (StringRef(DeclName).starts_with("test")) return true; @@ -90,45 +89,36 @@ static bool isTest(const Decl *D) { static auto findGCDAntiPatternWithSemaphore() -> decltype(compoundStmt()) { const char *SemaphoreBinding = "semaphore_name"; - auto SemaphoreCreateM = callExpr(allOf( - callsName("dispatch_semaphore_create"), - hasArgument(0, ignoringParenCasts(integerLiteral(equals(0)))))); + auto SemaphoreCreateM = callExpr( + allOf(callsName("dispatch_semaphore_create"), + hasArgument(0, ignoringParenCasts(integerLiteral(equals(0)))))); auto SemaphoreBindingM = anyOf( forEachDescendant( varDecl(hasDescendant(SemaphoreCreateM)).bind(SemaphoreBinding)), forEachDescendant(binaryOperator(bindAssignmentToDecl(SemaphoreBinding), - hasRHS(SemaphoreCreateM)))); + hasRHS(SemaphoreCreateM)))); - auto HasBlockArgumentM = hasAnyArgument(hasType( - hasCanonicalType(blockPointerType()) - )); + auto HasBlockArgumentM = + hasAnyArgument(hasType(hasCanonicalType(blockPointerType()))); - auto ArgCallsSignalM = hasAnyArgument(stmt(hasDescendant(callExpr( - allOf( - callsName("dispatch_semaphore_signal"), - equalsBoundArgDecl(0, SemaphoreBinding) - ))))); + auto ArgCallsSignalM = hasAnyArgument(stmt( + hasDescendant(callExpr(allOf(callsName("dispatch_semaphore_signal"), + equalsBoundArgDecl(0, SemaphoreBinding)))))); auto HasBlockAndCallsSignalM = allOf(HasBlockArgumentM, ArgCallsSignalM); auto HasBlockCallingSignalM = - forEachDescendant( - stmt(anyOf( - callExpr(HasBlockAndCallsSignalM), - objcMessageExpr(HasBlockAndCallsSignalM) - ))); - - auto SemaphoreWaitM = forEachDescendant( - callExpr( - allOf( - callsName("dispatch_semaphore_wait"), - equalsBoundArgDecl(0, SemaphoreBinding) - ) - ).bind(WarnAtNode)); - - return compoundStmt( - SemaphoreBindingM, HasBlockCallingSignalM, SemaphoreWaitM); + forEachDescendant(stmt(anyOf(callExpr(HasBlockAndCallsSignalM), + objcMessageExpr(HasBlockAndCallsSignalM)))); + + auto SemaphoreWaitM = + forEachDescendant(callExpr(allOf(callsName("dispatch_semaphore_wait"), + equalsBoundArgDecl(0, SemaphoreBinding))) + .bind(WarnAtNode)); + + return compoundStmt(SemaphoreBindingM, HasBlockCallingSignalM, + SemaphoreWaitM); } static auto findGCDAntiPatternWithGroup() -> decltype(compoundStmt()) { @@ -140,46 +130,35 @@ static auto findGCDAntiPatternWithGroup() -> decltype(compoundStmt()) { forEachDescendant( varDecl(hasDescendant(DispatchGroupCreateM)).bind(GroupBinding)), forEachDescendant(binaryOperator(bindAssignmentToDecl(GroupBinding), - hasRHS(DispatchGroupCreateM)))); + hasRHS(DispatchGroupCreateM)))); auto GroupEnterM = forEachDescendant( stmt(callExpr(allOf(callsName("dispatch_group_enter"), equalsBoundArgDecl(0, GroupBinding))))); - auto HasBlockArgumentM = hasAnyArgument(hasType( - hasCanonicalType(blockPointerType()) - )); + auto HasBlockArgumentM = + hasAnyArgument(hasType(hasCanonicalType(blockPointerType()))); - auto ArgCallsSignalM = hasAnyArgument(stmt(hasDescendant(callExpr( - allOf( - callsName("dispatch_group_leave"), - equalsBoundArgDecl(0, GroupBinding) - ))))); + auto ArgCallsSignalM = hasAnyArgument(stmt( + hasDescendant(callExpr(allOf(callsName("dispatch_group_leave"), + equalsBoundArgDecl(0, GroupBinding)))))); auto HasBlockAndCallsLeaveM = allOf(HasBlockArgumentM, ArgCallsSignalM); auto AcceptsBlockM = - forEachDescendant( - stmt(anyOf( - callExpr(HasBlockAndCallsLeaveM), - objcMessageExpr(HasBlockAndCallsLeaveM) - ))); - - auto GroupWaitM = forEachDescendant( - callExpr( - allOf( - callsName("dispatch_group_wait"), - equalsBoundArgDecl(0, GroupBinding) - ) - ).bind(WarnAtNode)); + forEachDescendant(stmt(anyOf(callExpr(HasBlockAndCallsLeaveM), + objcMessageExpr(HasBlockAndCallsLeaveM)))); + + auto GroupWaitM = + forEachDescendant(callExpr(allOf(callsName("dispatch_group_wait"), + equalsBoundArgDecl(0, GroupBinding))) + .bind(WarnAtNode)); return compoundStmt(GroupBindingM, GroupEnterM, AcceptsBlockM, GroupWaitM); } -static void emitDiagnostics(const BoundNodes &Nodes, - const char* Type, - BugReporter &BR, - AnalysisDeclContext *ADC, +static void emitDiagnostics(const BoundNodes &Nodes, const char *Type, + BugReporter &BR, AnalysisDeclContext *ADC, const GCDAntipatternChecker *Checker) { const auto *SW = Nodes.getNodeAs(WarnAtNode); assert(SW); @@ -191,17 +170,14 @@ static void emitDiagnostics(const BoundNodes &Nodes, << "using a synchronous API or changing the caller to be asynchronous"; BR.EmitBasicReport( - ADC->getDecl(), - Checker, - /*Name=*/"GCD performance anti-pattern", - /*BugCategory=*/"Performance", - OS.str(), - PathDiagnosticLocation::createBegin(SW, BR.getSourceManager(), ADC), - SW->getSourceRange()); + ADC->getDecl(), Checker, + /*Name=*/"GCD performance anti-pattern", + /*BugCategory=*/"Performance", OS.str(), + PathDiagnosticLocation::createBegin(SW, BR.getSourceManager(), ADC), + SW->getSourceRange()); } -void GCDAntipatternChecker::checkASTCodeBody(const Decl *D, - AnalysisManager &AM, +void GCDAntipatternChecker::checkASTCodeBody(const Decl *D, AnalysisManager &AM, BugReporter &BR) const { if (isTest(D)) return; diff --git a/clang/lib/StaticAnalyzer/Checkers/GTestChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GTestChecker.cpp index 6c32a8dec844c..f40c52640cdb7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/GTestChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/GTestChecker.cpp @@ -12,9 +12,9 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Expr.h" #include "clang/Basic/LangOptions.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" @@ -224,7 +224,7 @@ void GTestChecker::checkPostCall(const CallEvent &Call, modelAssertionResultBoolConstructor(CtorCall, /*IsRef=*/false, C); return; } - if (ParamCount == 2){ + if (ParamCount == 2) { auto *RefTy = CtorDecl->getParamDecl(0)->getType()->getAs(); if (RefTy && RefTy->getPointeeType()->getCanonicalTypeUnqualified() == BoolTy) { diff --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp index 4ceaf933d0bfc..a5dc9480b6da3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -977,30 +977,29 @@ void GenericTaintRule::process(const GenericTaintChecker &Checker, /// Propagate taint where it is necessary. auto &F = State->getStateManager().get_context(); ImmutableSet Result = F.getEmptySet(); - ForEachCallArg( - [&](ArgIdxTy I, const Expr *E, SVal V) { - if (PropDstArgs.contains(I)) { - LLVM_DEBUG(llvm::dbgs() << "PreCall<"; Call.dump(llvm::dbgs()); - llvm::dbgs() - << "> prepares tainting arg index: " << I << '\n';); - Result = F.add(Result, I); - } + ForEachCallArg([&](ArgIdxTy I, const Expr *E, SVal V) { + if (PropDstArgs.contains(I)) { + LLVM_DEBUG(llvm::dbgs() << "PreCall<"; Call.dump(llvm::dbgs()); + llvm::dbgs() + << "> prepares tainting arg index: " << I << '\n';); + Result = F.add(Result, I); + } - // Taint property gets lost if the variable is passed as a - // non-const pointer or reference to a function which is - // not inlined. For matching rules we want to preserve the taintedness. - // TODO: We should traverse all reachable memory regions via the - // escaping parameter. Instead of doing that we simply mark only the - // referred memory region as tainted. - if (WouldEscape(V, E->getType()) && getTaintedPointeeOrPointer(State, V)) { - LLVM_DEBUG(if (!Result.contains(I)) { - llvm::dbgs() << "PreCall<"; - Call.dump(llvm::dbgs()); - llvm::dbgs() << "> prepares tainting arg index: " << I << '\n'; - }); - Result = F.add(Result, I); - } + // Taint property gets lost if the variable is passed as a + // non-const pointer or reference to a function which is + // not inlined. For matching rules we want to preserve the taintedness. + // TODO: We should traverse all reachable memory regions via the + // escaping parameter. Instead of doing that we simply mark only the + // referred memory region as tainted. + if (WouldEscape(V, E->getType()) && getTaintedPointeeOrPointer(State, V)) { + LLVM_DEBUG(if (!Result.contains(I)) { + llvm::dbgs() << "PreCall<"; + Call.dump(llvm::dbgs()); + llvm::dbgs() << "> prepares tainting arg index: " << I << '\n'; }); + Result = F.add(Result, I); + } + }); if (!Result.isEmpty()) State = State->set(C.getStackFrame(), Result); diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index 1cf81b54e77d3..5a2dbf42f4d96 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -15,8 +15,8 @@ /// //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -37,9 +37,9 @@ class FindIdenticalExprVisitor BugReporter &BR; const CheckerBase *Checker; AnalysisDeclContext *AC; + public: - explicit FindIdenticalExprVisitor(BugReporter &B, - const CheckerBase *Checker, + explicit FindIdenticalExprVisitor(BugReporter &B, const CheckerBase *Checker, AnalysisDeclContext *A) : BR(B), Checker(Checker), AC(A) {} // FindIdenticalExprVisitor only visits nodes @@ -68,10 +68,8 @@ void FindIdenticalExprVisitor::reportIdenticalExpr(const BinaryOperator *B, PathDiagnosticLocation ELoc = PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager()); - BR.EmitBasicReport(AC->getDecl(), Checker, - "Use of identical expressions", - categories::LogicError, - Message, ELoc, Sr); + BR.EmitBasicReport(AC->getDecl(), Checker, "Use of identical expressions", + categories::LogicError, Message, ELoc, Sr); } void FindIdenticalExprVisitor::checkBitwiseOrLogicalOp(const BinaryOperator *B, @@ -115,12 +113,15 @@ bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) { if (const CompoundStmt *CS = dyn_cast(Stmt1)) { if (!CS->body_empty()) { const IfStmt *InnerIf = dyn_cast(*CS->body_begin()); - if (InnerIf && isIdenticalStmt(AC->getASTContext(), I->getCond(), InnerIf->getCond(), /*IgnoreSideEffects=*/ false)) { - PathDiagnosticLocation ELoc(InnerIf->getCond(), BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), Checker, "Identical conditions", - categories::LogicError, - "conditions of the inner and outer statements are identical", - ELoc); + if (InnerIf && + isIdenticalStmt(AC->getASTContext(), I->getCond(), InnerIf->getCond(), + /*IgnoreSideEffects=*/false)) { + PathDiagnosticLocation ELoc(InnerIf->getCond(), BR.getSourceManager(), + AC); + BR.EmitBasicReport( + AC->getDecl(), Checker, "Identical conditions", + categories::LogicError, + "conditions of the inner and outer statements are identical", ELoc); } } } @@ -168,12 +169,11 @@ bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) { } if (isIdenticalStmt(AC->getASTContext(), Stmt1, Stmt2, true)) { - PathDiagnosticLocation ELoc = - PathDiagnosticLocation::createBegin(I, BR.getSourceManager(), AC); - BR.EmitBasicReport(AC->getDecl(), Checker, - "Identical branches", - categories::LogicError, - "true and false branches are identical", ELoc); + PathDiagnosticLocation ELoc = + PathDiagnosticLocation::createBegin(I, BR.getSourceManager(), AC); + BR.EmitBasicReport(AC->getDecl(), Checker, "Identical branches", + categories::LogicError, + "true and false branches are identical", ELoc); } return true; } @@ -273,8 +273,8 @@ bool FindIdenticalExprVisitor::VisitConditionalOperator( // Check if expressions in conditional expression are identical // from a symbolic point of view. - if (isIdenticalStmt(AC->getASTContext(), C->getTrueExpr(), - C->getFalseExpr(), true)) { + if (isIdenticalStmt(AC->getASTContext(), C->getTrueExpr(), C->getFalseExpr(), + true)) { PathDiagnosticLocation ELoc = PathDiagnosticLocation::createConditionalColonLoc( C, BR.getSourceManager()); @@ -360,8 +360,8 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, case Stmt::NullStmtClass: return true; case Stmt::CStyleCastExprClass: { - const CStyleCastExpr* CastExpr1 = cast(Stmt1); - const CStyleCastExpr* CastExpr2 = cast(Stmt2); + const CStyleCastExpr *CastExpr1 = cast(Stmt1); + const CStyleCastExpr *CastExpr2 = cast(Stmt2); return CastExpr1->getTypeAsWritten() == CastExpr2->getTypeAsWritten(); } @@ -471,7 +471,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, llvm::APInt I2 = IntLit2->getValue(); if (I1.getBitWidth() != I2.getBitWidth()) return false; - return I1 == I2; + return I1 == I2; } case Stmt::FloatingLiteralClass: { const FloatingLiteral *FloatLit1 = cast(Stmt1); diff --git a/clang/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp index b673b51c46232..2afafcbb59a0e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp @@ -29,7 +29,6 @@ using namespace ento; REGISTER_SET_FACTORY_WITH_PROGRAMSTATE(PtrSet, SymbolRef) REGISTER_MAP_WITH_PROGRAMSTATE(RawPtrMap, const MemRegion *, PtrSet) - namespace { class InnerPointerChecker @@ -101,8 +100,8 @@ class InnerPointerChecker const MemRegion *ObjRegion, CheckerContext &C) const; - /// Standard library functions that take a non-const `basic_string` argument by - /// reference may invalidate its inner pointers. Check for these cases and + /// Standard library functions that take a non-const `basic_string` argument + /// by reference may invalidate its inner pointers. Check for these cases and /// mark the pointers released. void checkFunctionArguments(const CallEvent &Call, ProgramStateRef State, CheckerContext &C) const; @@ -119,7 +118,7 @@ class InnerPointerChecker } // end anonymous namespace bool InnerPointerChecker::isInvalidatingMemberFunction( - const CallEvent &Call) const { + const CallEvent &Call) const { if (const auto *MemOpCall = dyn_cast(&Call)) { OverloadedOperatorKind Opc = MemOpCall->getOriginExpr()->getOperator(); if (Opc == OO_Equal || Opc == OO_PlusEqual) @@ -171,7 +170,7 @@ void InnerPointerChecker::checkFunctionArguments(const CallEvent &Call, // In case of member operator calls, `this` is counted as an // argument but not as a parameter. bool isaMemberOpCall = isa(FC); - unsigned ArgI = isaMemberOpCall ? I+1 : I; + unsigned ArgI = isaMemberOpCall ? I + 1 : I; SVal Arg = FC->getArgSVal(ArgI); const auto *ArgRegion = diff --git a/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp index 2e21f619a133e..093cfbc85b15e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp @@ -16,7 +16,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" - #include "Iterator.h" using namespace clang; @@ -26,10 +25,10 @@ using namespace iterator; namespace { class InvalidatedIteratorChecker - : public Checker, - check::PreStmt, - check::PreStmt, - check::PreStmt> { + : public Checker, + check::PreStmt, + check::PreStmt, + check::PreStmt> { const BugType InvalidatedBugType{this, "Iterator invalidated", "Misuse of STL APIs"}; @@ -44,7 +43,6 @@ class InvalidatedIteratorChecker void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; void checkPreStmt(const ArraySubscriptExpr *ASE, CheckerContext &C) const; void checkPreStmt(const MemberExpr *ME, CheckerContext &C) const; - }; } // namespace diff --git a/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp b/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp index e8d35aac2efd9..e1a18df640cfa 100644 --- a/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/Iterator.cpp @@ -142,13 +142,9 @@ bool isDereferenceOperator(OverloadedOperatorKind OK) { OK == OO_Subscript; } -bool isDereferenceOperator(UnaryOperatorKind OK) { - return OK == UO_Deref; -} +bool isDereferenceOperator(UnaryOperatorKind OK) { return OK == UO_Deref; } -bool isDereferenceOperator(BinaryOperatorKind OK) { - return OK == BO_PtrMemI; -} +bool isDereferenceOperator(BinaryOperatorKind OK) { return OK == BO_PtrMemI; } bool isIncrementOperator(OverloadedOperatorKind OK) { return OK == OO_PlusPlus; @@ -172,8 +168,8 @@ bool isRandomIncrOrDecrOperator(OverloadedOperatorKind OK) { } bool isRandomIncrOrDecrOperator(BinaryOperatorKind OK) { - return OK == BO_Add || OK == BO_AddAssign || - OK == BO_Sub || OK == BO_SubAssign; + return OK == BO_Add || OK == BO_AddAssign || OK == BO_Sub || + OK == BO_SubAssign; } const ContainerData *getContainerData(ProgramStateRef State, @@ -230,9 +226,9 @@ ProgramStateRef advancePosition(ProgramStateRef State, SVal Iter, auto &SVB = State->getStateManager().getSValBuilder(); auto &BVF = State->getStateManager().getBasicVals(); - assert ((Op == OO_Plus || Op == OO_PlusEqual || - Op == OO_Minus || Op == OO_MinusEqual) && - "Advance operator must be one of +, -, += and -=."); + assert((Op == OO_Plus || Op == OO_PlusEqual || Op == OO_Minus || + Op == OO_MinusEqual) && + "Advance operator must be one of +, -, += and -=."); auto BinOp = (Op == OO_Plus || Op == OO_PlusEqual) ? BO_Add : BO_Sub; const auto IntDistOp = Distance.getAs(); if (!IntDistOp) @@ -245,11 +241,10 @@ ProgramStateRef advancePosition(ProgramStateRef State, SVal Iter, IntDist = nonloc::ConcreteInt(BVF.getValue(-IntDist.getValue())); BinOp = (BinOp == BO_Add) ? BO_Sub : BO_Add; } - const auto NewPos = - Pos->setTo(SVB.evalBinOp(State, BinOp, - nonloc::SymbolVal(Pos->getOffset()), - IntDist, SymMgr.getType(Pos->getOffset())) - .getAsSymbol()); + const auto NewPos = Pos->setTo( + SVB.evalBinOp(State, BinOp, nonloc::SymbolVal(Pos->getOffset()), IntDist, + SymMgr.getType(Pos->getOffset())) + .getAsSymbol()); return setIteratorPosition(State, Iter, NewPos); } @@ -304,7 +299,7 @@ bool compare(ProgramStateRef State, NonLoc NL1, NonLoc NL2, auto &SVB = State->getStateManager().getSValBuilder(); const auto comparison = - SVB.evalBinOp(State, Opc, NL1, NL2, SVB.getConditionType()); + SVB.evalBinOp(State, Opc, NL1, NL2, SVB.getConditionType()); assert(isa(comparison) && "Symbol comparison must be a `DefinedSVal`"); diff --git a/clang/lib/StaticAnalyzer/Checkers/Iterator.h b/clang/lib/StaticAnalyzer/Checkers/Iterator.h index 46de8ea01d77b..3ac15f94b3878 100644 --- a/clang/lib/StaticAnalyzer/Checkers/Iterator.h +++ b/clang/lib/StaticAnalyzer/Checkers/Iterator.h @@ -25,7 +25,6 @@ namespace iterator { // of operators in a common way by using a symbolic position. struct IteratorPosition { private: - // Container the iterator belongs to const MemRegion *Cont; @@ -111,31 +110,40 @@ class IteratorSymbolMap {}; class IteratorRegionMap {}; class ContainerMap {}; -using IteratorSymbolMapTy = - CLANG_ENTO_PROGRAMSTATE_MAP(SymbolRef, IteratorPosition); -using IteratorRegionMapTy = - CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, IteratorPosition); -using ContainerMapTy = - CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, ContainerData); +using IteratorSymbolMapTy = CLANG_ENTO_PROGRAMSTATE_MAP(SymbolRef, + IteratorPosition); +using IteratorRegionMapTy = CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, + IteratorPosition); +using ContainerMapTy = CLANG_ENTO_PROGRAMSTATE_MAP(const MemRegion *, + ContainerData); } // namespace iterator -template<> +template <> struct ProgramStateTrait - : public ProgramStatePartialTrait { - static void *GDMIndex() { static int Index; return &Index; } + : public ProgramStatePartialTrait { + static void *GDMIndex() { + static int Index; + return &Index; + } }; -template<> +template <> struct ProgramStateTrait - : public ProgramStatePartialTrait { - static void *GDMIndex() { static int Index; return &Index; } + : public ProgramStatePartialTrait { + static void *GDMIndex() { + static int Index; + return &Index; + } }; -template<> +template <> struct ProgramStateTrait - : public ProgramStatePartialTrait { - static void *GDMIndex() { static int Index; return &Index; } + : public ProgramStatePartialTrait { + static void *GDMIndex() { + static int Index; + return &Index; + } }; namespace iterator { diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp index a95e811c2a418..76d9689453672 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp @@ -87,8 +87,8 @@ namespace { class IteratorModeling : public Checker, check::PostStmt, - check::PostStmt, - check::Bind, check::LiveSymbols, check::DeadSymbols> { + check::PostStmt, check::Bind, + check::LiveSymbols, check::DeadSymbols> { using AdvanceFn = void (IteratorModeling::*)(CheckerContext &, const Expr *, SVal, SVal, SVal) const; @@ -219,9 +219,13 @@ void IteratorModeling::checkPostCall(const CallEvent &Call, // FIXME: Add a more conservative mode for (unsigned i = 0; i < Call.getNumArgs(); ++i) { if (isIteratorType(Call.getArgExpr(i)->getType()) && - Call.getArgExpr(i)->getType().getNonReferenceType().getDesugaredType( - C.getASTContext()).getTypePtr() == - Call.getResultType().getDesugaredType(C.getASTContext()).getTypePtr()) { + Call.getArgExpr(i) + ->getType() + .getNonReferenceType() + .getDesugaredType(C.getASTContext()) + .getTypePtr() == Call.getResultType() + .getDesugaredType(C.getASTContext()) + .getTypePtr()) { if (const auto *Pos = getIteratorPosition(State, Call.getArgSVal(i))) { assignToContainer(C, OrigExpr, Call.getReturnValue(), Pos->getContainer()); @@ -344,88 +348,84 @@ void IteratorModeling::checkDeadSymbols(SymbolReaper &SR, C.addTransition(State); } -void -IteratorModeling::handleOverloadedOperator(CheckerContext &C, - const CallEvent &Call, - OverloadedOperatorKind Op) const { - if (isSimpleComparisonOperator(Op)) { - const auto *OrigExpr = Call.getOriginExpr(); - if (!OrigExpr) - return; +void IteratorModeling::handleOverloadedOperator( + CheckerContext &C, const CallEvent &Call, OverloadedOperatorKind Op) const { + if (isSimpleComparisonOperator(Op)) { + const auto *OrigExpr = Call.getOriginExpr(); + if (!OrigExpr) + return; - if (const auto *InstCall = dyn_cast(&Call)) { - handleComparison(C, OrigExpr, Call.getReturnValue(), - InstCall->getCXXThisVal(), Call.getArgSVal(0), Op); - return; - } + if (const auto *InstCall = dyn_cast(&Call)) { + handleComparison(C, OrigExpr, Call.getReturnValue(), + InstCall->getCXXThisVal(), Call.getArgSVal(0), Op); + return; + } - handleComparison(C, OrigExpr, Call.getReturnValue(), Call.getArgSVal(0), - Call.getArgSVal(1), Op); + handleComparison(C, OrigExpr, Call.getReturnValue(), Call.getArgSVal(0), + Call.getArgSVal(1), Op); + return; + } else if (isRandomIncrOrDecrOperator(Op)) { + const auto *OrigExpr = Call.getOriginExpr(); + if (!OrigExpr) return; - } else if (isRandomIncrOrDecrOperator(Op)) { - const auto *OrigExpr = Call.getOriginExpr(); - if (!OrigExpr) - return; - if (const auto *InstCall = dyn_cast(&Call)) { - if (Call.getNumArgs() >= 1 && - Call.getArgExpr(0)->getType()->isIntegralOrEnumerationType()) { - handleRandomIncrOrDecr(C, OrigExpr, Op, Call.getReturnValue(), - InstCall->getCXXThisVal(), Call.getArgSVal(0)); - return; - } - } else if (Call.getNumArgs() >= 2) { - const Expr *FirstArg = Call.getArgExpr(0); - const Expr *SecondArg = Call.getArgExpr(1); - const QualType FirstType = FirstArg->getType(); - const QualType SecondType = SecondArg->getType(); - - if (FirstType->isIntegralOrEnumerationType() || - SecondType->isIntegralOrEnumerationType()) { - // In case of operator+ the iterator can be either on the LHS (eg.: - // it + 1), or on the RHS (eg.: 1 + it). Both cases are modeled. - const bool IsIterFirst = FirstType->isStructureOrClassType(); - const SVal FirstArg = Call.getArgSVal(0); - const SVal SecondArg = Call.getArgSVal(1); - SVal Iterator = IsIterFirst ? FirstArg : SecondArg; - SVal Amount = IsIterFirst ? SecondArg : FirstArg; - - handleRandomIncrOrDecr(C, OrigExpr, Op, Call.getReturnValue(), - Iterator, Amount); - return; - } + if (const auto *InstCall = dyn_cast(&Call)) { + if (Call.getNumArgs() >= 1 && + Call.getArgExpr(0)->getType()->isIntegralOrEnumerationType()) { + handleRandomIncrOrDecr(C, OrigExpr, Op, Call.getReturnValue(), + InstCall->getCXXThisVal(), Call.getArgSVal(0)); + return; } - } else if (isIncrementOperator(Op)) { - if (const auto *InstCall = dyn_cast(&Call)) { - handleIncrement(C, Call.getReturnValue(), InstCall->getCXXThisVal(), - Call.getNumArgs()); + } else if (Call.getNumArgs() >= 2) { + const Expr *FirstArg = Call.getArgExpr(0); + const Expr *SecondArg = Call.getArgExpr(1); + const QualType FirstType = FirstArg->getType(); + const QualType SecondType = SecondArg->getType(); + + if (FirstType->isIntegralOrEnumerationType() || + SecondType->isIntegralOrEnumerationType()) { + // In case of operator+ the iterator can be either on the LHS (eg.: + // it + 1), or on the RHS (eg.: 1 + it). Both cases are modeled. + const bool IsIterFirst = FirstType->isStructureOrClassType(); + const SVal FirstArg = Call.getArgSVal(0); + const SVal SecondArg = Call.getArgSVal(1); + SVal Iterator = IsIterFirst ? FirstArg : SecondArg; + SVal Amount = IsIterFirst ? SecondArg : FirstArg; + + handleRandomIncrOrDecr(C, OrigExpr, Op, Call.getReturnValue(), Iterator, + Amount); return; } - - handleIncrement(C, Call.getReturnValue(), Call.getArgSVal(0), + } + } else if (isIncrementOperator(Op)) { + if (const auto *InstCall = dyn_cast(&Call)) { + handleIncrement(C, Call.getReturnValue(), InstCall->getCXXThisVal(), Call.getNumArgs()); return; - } else if (isDecrementOperator(Op)) { - if (const auto *InstCall = dyn_cast(&Call)) { - handleDecrement(C, Call.getReturnValue(), InstCall->getCXXThisVal(), - Call.getNumArgs()); - return; - } + } - handleDecrement(C, Call.getReturnValue(), Call.getArgSVal(0), - Call.getNumArgs()); + handleIncrement(C, Call.getReturnValue(), Call.getArgSVal(0), + Call.getNumArgs()); + return; + } else if (isDecrementOperator(Op)) { + if (const auto *InstCall = dyn_cast(&Call)) { + handleDecrement(C, Call.getReturnValue(), InstCall->getCXXThisVal(), + Call.getNumArgs()); return; } + + handleDecrement(C, Call.getReturnValue(), Call.getArgSVal(0), + Call.getNumArgs()); + return; + } } -void -IteratorModeling::handleAdvanceLikeFunction(CheckerContext &C, - const CallEvent &Call, - const Expr *OrigExpr, - const AdvanceFn *Handler) const { +void IteratorModeling::handleAdvanceLikeFunction( + CheckerContext &C, const CallEvent &Call, const Expr *OrigExpr, + const AdvanceFn *Handler) const { if (!C.wasInlined) { - (this->**Handler)(C, OrigExpr, Call.getReturnValue(), - Call.getArgSVal(0), Call.getArgSVal(1)); + (this->**Handler)(C, OrigExpr, Call.getReturnValue(), Call.getArgSVal(0), + Call.getArgSVal(1)); return; } @@ -506,8 +506,8 @@ void IteratorModeling::processComparison(CheckerContext &C, OverloadedOperatorKind Op) const { if (const auto TruthVal = RetVal.getAs()) { if ((State = relateSymbols(State, Sym1, Sym2, - (Op == OO_EqualEqual) == - (TruthVal->getValue() != 0)))) { + (Op == OO_EqualEqual) == + (TruthVal->getValue() != 0)))) { C.addTransition(State); } else { C.generateSink(State, C.getPredecessor()); @@ -542,8 +542,8 @@ void IteratorModeling::handleIncrement(CheckerContext &C, SVal RetVal, return; auto NewState = - advancePosition(State, Iter, OO_Plus, - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1)))); + advancePosition(State, Iter, OO_Plus, + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1)))); assert(NewState && "Advancing position by concrete int should always be successful"); @@ -568,8 +568,8 @@ void IteratorModeling::handleDecrement(CheckerContext &C, SVal RetVal, return; auto NewState = - advancePosition(State, Iter, OO_Minus, - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1)))); + advancePosition(State, Iter, OO_Minus, + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1)))); assert(NewState && "Advancing position by concrete int should always be successful"); @@ -740,7 +740,7 @@ void IteratorModeling::printState(raw_ostream &Out, ProgramStateRef State, const auto Pos = Sym.second; Out << (Pos.isValid() ? "Valid" : "Invalid") << " ; Container == "; Pos.getContainer()->dumpToStream(Out); - Out<<" ; Offset == "; + Out << " ; Offset == "; Pos.getOffset()->dumpToStream(Out); } @@ -753,7 +753,7 @@ void IteratorModeling::printState(raw_ostream &Out, ProgramStateRef State, const auto Pos = Reg.second; Out << (Pos.isValid() ? "Valid" : "Invalid") << " ; Container == "; Pos.getContainer()->dumpToStream(Out); - Out<<" ; Offset == "; + Out << " ; Offset == "; Pos.getOffset()->dumpToStream(Out); } } @@ -791,8 +791,8 @@ ProgramStateRef relateSymbols(ProgramStateRef State, SymbolRef Sym1, // 3. Compare the result to 0. // 4. Assume the result of the comparison. const auto comparison = - SVB.evalBinOp(State, BO_EQ, nonloc::SymbolVal(Sym1), - nonloc::SymbolVal(Sym2), SVB.getConditionType()); + SVB.evalBinOp(State, BO_EQ, nonloc::SymbolVal(Sym1), + nonloc::SymbolVal(Sym2), SVB.getConditionType()); assert(isa(comparison) && "Symbol comparison must be a `DefinedSVal`"); diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp index d2b61fb92483c..b53118a5effc2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp @@ -27,10 +27,10 @@ using namespace iterator; namespace { class IteratorRangeChecker - : public Checker, - check::PreStmt, - check::PreStmt, - check::PreStmt> { + : public Checker, + check::PreStmt, + check::PreStmt, + check::PreStmt> { const BugType OutOfRangeBugType{this, "Iterator out of range", "Misuse of STL APIs"}; @@ -102,8 +102,7 @@ void IteratorRangeChecker::checkPreCall(const CallEvent &Call, if (Call.getNumArgs() >= 1 && Call.getArgExpr(0)->getType()->isIntegralOrEnumerationType()) { verifyRandomIncrOrDecr(C, Func->getOverloadedOperator(), - InstCall->getCXXThisVal(), - Call.getArgSVal(0)); + InstCall->getCXXThisVal(), Call.getArgSVal(0)); } } else { if (Call.getNumArgs() >= 2 && @@ -202,14 +201,16 @@ void IteratorRangeChecker::verifyDereference(CheckerContext &C, void IteratorRangeChecker::verifyIncrement(CheckerContext &C, SVal Iter) const { auto &BVF = C.getSValBuilder().getBasicValueFactory(); - verifyRandomIncrOrDecr(C, OO_Plus, Iter, - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1)))); + verifyRandomIncrOrDecr( + C, OO_Plus, Iter, + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1)))); } void IteratorRangeChecker::verifyDecrement(CheckerContext &C, SVal Iter) const { auto &BVF = C.getSValBuilder().getBasicValueFactory(); - verifyRandomIncrOrDecr(C, OO_Minus, Iter, - nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1)))); + verifyRandomIncrOrDecr( + C, OO_Minus, Iter, + nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1)))); } void IteratorRangeChecker::verifyRandomIncrOrDecr(CheckerContext &C, @@ -242,15 +243,15 @@ void IteratorRangeChecker::verifyRandomIncrOrDecr(CheckerContext &C, auto *N = C.generateErrorNode(State); if (!N) return; - reportBug("Iterator decremented ahead of its valid range.", LHS, - C, N); + reportBug("Iterator decremented ahead of its valid range.", LHS, C, N); } if (isBehindPastTheEnd(State, *PosAfter)) { auto *N = C.generateErrorNode(State); if (!N) return; reportBug("Iterator incremented behind the past-the-end " - "iterator.", LHS, C, N); + "iterator.", + LHS, C, N); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp index f0276a57bdf98..1808cce63b4bb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp @@ -54,13 +54,13 @@ struct ChecksFilter { }; class IvarInvalidationCheckerImpl { - typedef llvm::SmallSetVector MethodSet; - typedef llvm::DenseMap MethToIvarMapTy; - typedef llvm::DenseMap PropToIvarMapTy; - typedef llvm::DenseMap IvarToPropMapTy; + typedef llvm::SmallSetVector MethodSet; + typedef llvm::DenseMap + MethToIvarMapTy; + typedef llvm::DenseMap + PropToIvarMapTy; + typedef llvm::DenseMap + IvarToPropMapTy; struct InvalidationInfo { /// Has the ivar been invalidated? @@ -74,9 +74,7 @@ class IvarInvalidationCheckerImpl { InvalidationMethods.insert(MD); } - bool needsInvalidation() const { - return !InvalidationMethods.empty(); - } + bool needsInvalidation() const { return !InvalidationMethods.empty(); } bool hasMethod(const ObjCMethodDecl *MD) { if (IsInvalidated) @@ -91,7 +89,7 @@ class IvarInvalidationCheckerImpl { } }; - typedef llvm::DenseMap IvarSet; + typedef llvm::DenseMap IvarSet; /// Statement visitor, which walks the method body and flags the ivars /// referenced in it (either directly or via property). @@ -142,19 +140,16 @@ class IvarInvalidationCheckerImpl { void check(const Expr *E); public: - MethodCrawler(IvarSet &InIVars, - bool &InCalledAnotherInvalidationMethod, + MethodCrawler(IvarSet &InIVars, bool &InCalledAnotherInvalidationMethod, const MethToIvarMapTy &InPropertySetterToIvarMap, const MethToIvarMapTy &InPropertyGetterToIvarMap, - const PropToIvarMapTy &InPropertyToIvarMap, - ASTContext &InCtx) - : IVars(InIVars), - CalledAnotherInvalidationMethod(InCalledAnotherInvalidationMethod), - PropertySetterToIvarMap(InPropertySetterToIvarMap), - PropertyGetterToIvarMap(InPropertyGetterToIvarMap), - PropertyToIvarMap(InPropertyToIvarMap), - InvalidationMethod(nullptr), - Ctx(InCtx) {} + const PropToIvarMapTy &InPropertyToIvarMap, ASTContext &InCtx) + : IVars(InIVars), + CalledAnotherInvalidationMethod(InCalledAnotherInvalidationMethod), + PropertySetterToIvarMap(InPropertySetterToIvarMap), + PropertyGetterToIvarMap(InPropertyGetterToIvarMap), + PropertyToIvarMap(InPropertyToIvarMap), InvalidationMethod(nullptr), + Ctx(InCtx) {} void VisitStmt(const Stmt *S) { VisitChildren(S); } @@ -189,10 +184,8 @@ class IvarInvalidationCheckerImpl { /// the ivar backing the property when possible. Returns '0' when no such /// ivar could be found. static const ObjCIvarDecl *findPropertyBackingIvar( - const ObjCPropertyDecl *Prop, - const ObjCInterfaceDecl *InterfaceD, - IvarSet &TrackedIvars, - const ObjCIvarDecl **FirstIvarDecl); + const ObjCPropertyDecl *Prop, const ObjCInterfaceDecl *InterfaceD, + IvarSet &TrackedIvars, const ObjCIvarDecl **FirstIvarDecl); /// Print ivar name or the property if the given ivar backs a property. static void printIvar(llvm::raw_svector_ostream &os, @@ -209,16 +202,15 @@ class IvarInvalidationCheckerImpl { const IvarToPropMapTy &IvarToPopertyMap, const ObjCMethodDecl *MethodD) const; - AnalysisManager& Mgr; + AnalysisManager &Mgr; BugReporter &BR; /// Filter on the checks performed. const ChecksFilter &Filter; public: - IvarInvalidationCheckerImpl(AnalysisManager& InMgr, - BugReporter &InBR, - const ChecksFilter &InFilter) : - Mgr (InMgr), BR(InBR), Filter(InFilter) {} + IvarInvalidationCheckerImpl(AnalysisManager &InMgr, BugReporter &InBR, + const ChecksFilter &InFilter) + : Mgr(InMgr), BR(InBR), Filter(InFilter) {} void visit(const ObjCImplementationDecl *D) const; }; @@ -275,9 +267,9 @@ void IvarInvalidationCheckerImpl::containsInvalidationMethod( } } -bool IvarInvalidationCheckerImpl::trackIvar(const ObjCIvarDecl *Iv, - IvarSet &TrackedIvars, - const ObjCIvarDecl **FirstIvarDecl) { +bool IvarInvalidationCheckerImpl::trackIvar( + const ObjCIvarDecl *Iv, IvarSet &TrackedIvars, + const ObjCIvarDecl **FirstIvarDecl) { QualType IvQTy = Iv->getType(); const ObjCObjectPointerType *IvTy = IvQTy->getAs(); if (!IvTy) @@ -297,10 +289,8 @@ bool IvarInvalidationCheckerImpl::trackIvar(const ObjCIvarDecl *Iv, } const ObjCIvarDecl *IvarInvalidationCheckerImpl::findPropertyBackingIvar( - const ObjCPropertyDecl *Prop, - const ObjCInterfaceDecl *InterfaceD, - IvarSet &TrackedIvars, - const ObjCIvarDecl **FirstIvarDecl) { + const ObjCPropertyDecl *Prop, const ObjCInterfaceDecl *InterfaceD, + IvarSet &TrackedIvars, const ObjCIvarDecl **FirstIvarDecl) { const ObjCIvarDecl *IvarD = nullptr; // Lookup for the synthesized case. @@ -339,22 +329,22 @@ const ObjCIvarDecl *IvarInvalidationCheckerImpl::findPropertyBackingIvar( return nullptr; } -void IvarInvalidationCheckerImpl::printIvar(llvm::raw_svector_ostream &os, - const ObjCIvarDecl *IvarDecl, - const IvarToPropMapTy &IvarToPopertyMap) { +void IvarInvalidationCheckerImpl::printIvar( + llvm::raw_svector_ostream &os, const ObjCIvarDecl *IvarDecl, + const IvarToPropMapTy &IvarToPopertyMap) { if (IvarDecl->getSynthesize()) { const ObjCPropertyDecl *PD = IvarToPopertyMap.lookup(IvarDecl); - assert(PD &&"Do we synthesize ivars for something other than properties?"); - os << "Property "<< PD->getName() << " "; + assert(PD && "Do we synthesize ivars for something other than properties?"); + os << "Property " << PD->getName() << " "; } else { - os << "Instance variable "<< IvarDecl->getName() << " "; + os << "Instance variable " << IvarDecl->getName() << " "; } } // Check that the invalidatable interfaces with ivars/properties implement the // invalidation methods. -void IvarInvalidationCheckerImpl:: -visit(const ObjCImplementationDecl *ImplD) const { +void IvarInvalidationCheckerImpl::visit( + const ObjCImplementationDecl *ImplD) const { // Collect all ivars that need cleanup. IvarSet Ivars; // Record the first Ivar needing invalidation; used in reporting when only @@ -366,7 +356,7 @@ visit(const ObjCImplementationDecl *ImplD) const { // Collect ivars declared in this class, its extensions and its implementation ObjCInterfaceDecl *IDecl = const_cast(InterfaceD); for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv; - Iv= Iv->getNextIvar()) + Iv = Iv->getNextIvar()) trackIvar(Iv, Ivars, &FirstIvarDecl); // Construct Property/Property Accessor to Ivar maps to assist checking if an @@ -383,8 +373,8 @@ visit(const ObjCImplementationDecl *ImplD) const { if (PD->isClassProperty()) continue; - const ObjCIvarDecl *ID = findPropertyBackingIvar(PD, InterfaceD, Ivars, - &FirstIvarDecl); + const ObjCIvarDecl *ID = + findPropertyBackingIvar(PD, InterfaceD, Ivars, &FirstIvarDecl); if (!ID) continue; @@ -420,19 +410,16 @@ visit(const ObjCImplementationDecl *ImplD) const { bool AtImplementationContainsAtLeastOnePartialInvalidationMethod = false; for (const ObjCMethodDecl *InterfD : PartialInfo.InvalidationMethods) { // Get the corresponding method in the @implementation. - const ObjCMethodDecl *D = ImplD->getMethod(InterfD->getSelector(), - InterfD->isInstanceMethod()); + const ObjCMethodDecl *D = + ImplD->getMethod(InterfD->getSelector(), InterfD->isInstanceMethod()); if (D && D->hasBody()) { AtImplementationContainsAtLeastOnePartialInvalidationMethod = true; bool CalledAnotherInvalidationMethod = false; // The MethodCrowler is going to remove the invalidated ivars. - MethodCrawler(Ivars, - CalledAnotherInvalidationMethod, - PropSetterToIvarMap, - PropGetterToIvarMap, - PropertyToIvarMap, - BR.getContext()).VisitStmt(D->getBody()); + MethodCrawler(Ivars, CalledAnotherInvalidationMethod, PropSetterToIvarMap, + PropGetterToIvarMap, PropertyToIvarMap, BR.getContext()) + .VisitStmt(D->getBody()); // If another invalidation method was called, trust that full invalidation // has occurred. if (CalledAnotherInvalidationMethod) @@ -469,8 +456,8 @@ visit(const ObjCImplementationDecl *ImplD) const { bool AtImplementationContainsAtLeastOneInvalidationMethod = false; for (const ObjCMethodDecl *InterfD : Info.InvalidationMethods) { // Get the corresponding method in the @implementation. - const ObjCMethodDecl *D = ImplD->getMethod(InterfD->getSelector(), - InterfD->isInstanceMethod()); + const ObjCMethodDecl *D = + ImplD->getMethod(InterfD->getSelector(), InterfD->isInstanceMethod()); if (D && D->hasBody()) { AtImplementationContainsAtLeastOneInvalidationMethod = true; @@ -478,12 +465,10 @@ visit(const ObjCImplementationDecl *ImplD) const { IvarSet IvarsI = Ivars; bool CalledAnotherInvalidationMethod = false; - MethodCrawler(IvarsI, - CalledAnotherInvalidationMethod, - PropSetterToIvarMap, - PropGetterToIvarMap, - PropertyToIvarMap, - BR.getContext()).VisitStmt(D->getBody()); + MethodCrawler(IvarsI, CalledAnotherInvalidationMethod, + PropSetterToIvarMap, PropGetterToIvarMap, PropertyToIvarMap, + BR.getContext()) + .VisitStmt(D->getBody()); // If another invalidation method was called, trust that full invalidation // has occurred. if (CalledAnotherInvalidationMethod) @@ -527,26 +512,25 @@ void IvarInvalidationCheckerImpl::reportNoInvalidationMethod( os << InterfaceD->getName(); PathDiagnosticLocation IvarDecLocation = - PathDiagnosticLocation::createBegin(FirstIvarDecl, BR.getSourceManager()); + PathDiagnosticLocation::createBegin(FirstIvarDecl, BR.getSourceManager()); BR.EmitBasicReport(FirstIvarDecl, CheckName, "Incomplete invalidation", categories::CoreFoundationObjectiveC, os.str(), IvarDecLocation); } -void IvarInvalidationCheckerImpl:: -reportIvarNeedsInvalidation(const ObjCIvarDecl *IvarD, - const IvarToPropMapTy &IvarToPopertyMap, - const ObjCMethodDecl *MethodD) const { +void IvarInvalidationCheckerImpl::reportIvarNeedsInvalidation( + const ObjCIvarDecl *IvarD, const IvarToPropMapTy &IvarToPopertyMap, + const ObjCMethodDecl *MethodD) const { SmallString<128> sbuf; llvm::raw_svector_ostream os(sbuf); printIvar(os, IvarD, IvarToPopertyMap); os << "needs to be invalidated or set to nil"; if (MethodD) { PathDiagnosticLocation MethodDecLocation = - PathDiagnosticLocation::createEnd(MethodD->getBody(), - BR.getSourceManager(), - Mgr.getAnalysisDeclContext(MethodD)); + PathDiagnosticLocation::createEnd(MethodD->getBody(), + BR.getSourceManager(), + Mgr.getAnalysisDeclContext(MethodD)); BR.EmitBasicReport(MethodD, Filter.checkName_InstanceVariableInvalidation, "Incomplete invalidation", categories::CoreFoundationObjectiveC, os.str(), @@ -572,7 +556,8 @@ void IvarInvalidationCheckerImpl::MethodCrawler::markInvalidated( } } -const Expr *IvarInvalidationCheckerImpl::MethodCrawler::peel(const Expr *E) const { +const Expr * +IvarInvalidationCheckerImpl::MethodCrawler::peel(const Expr *E) const { E = E->IgnoreParenCasts(); if (const PseudoObjectExpr *POE = dyn_cast(E)) E = POE->getSyntacticForm()->IgnoreParenCasts(); @@ -616,7 +601,7 @@ void IvarInvalidationCheckerImpl::MethodCrawler::checkObjCPropertyRefExpr( const ObjCMethodDecl *MD = PA->getImplicitPropertySetter(); if (MD) { MD = MD->getCanonicalDecl(); - MethToIvarMapTy::const_iterator IvI =PropertyGetterToIvarMap.find(MD); + MethToIvarMapTy::const_iterator IvI = PropertyGetterToIvarMap.find(MD); if (IvI != PropertyGetterToIvarMap.end()) markInvalidated(IvI->second); return; @@ -627,8 +612,8 @@ void IvarInvalidationCheckerImpl::MethodCrawler::checkObjCPropertyRefExpr( bool IvarInvalidationCheckerImpl::MethodCrawler::isZero(const Expr *E) const { E = peel(E); - return (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull) - != Expr::NPCK_NotNull); + return (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull) != + Expr::NPCK_NotNull); } void IvarInvalidationCheckerImpl::MethodCrawler::check(const Expr *E) { @@ -657,14 +642,12 @@ void IvarInvalidationCheckerImpl::MethodCrawler::VisitBinaryOperator( // Do we assign/compare against zero? If yes, check the variable we are // assigning to. BinaryOperatorKind Opcode = BO->getOpcode(); - if (Opcode != BO_Assign && - Opcode != BO_EQ && - Opcode != BO_NE) + if (Opcode != BO_Assign && Opcode != BO_EQ && Opcode != BO_NE) return; if (isZero(BO->getRHS())) { - check(BO->getLHS()); - return; + check(BO->getLHS()); + return; } if (Opcode != BO_Assign && isZero(BO->getLHS())) { @@ -674,7 +657,7 @@ void IvarInvalidationCheckerImpl::MethodCrawler::VisitBinaryOperator( } void IvarInvalidationCheckerImpl::MethodCrawler::VisitObjCMessageExpr( - const ObjCMessageExpr *ME) { + const ObjCMessageExpr *ME) { const ObjCMethodDecl *MD = ME->getMethodDecl(); const Expr *Receiver = ME->getInstanceReceiver(); @@ -708,12 +691,13 @@ void IvarInvalidationCheckerImpl::MethodCrawler::VisitObjCMessageExpr( // Register the checkers. namespace { -class IvarInvalidationChecker : - public Checker > { +class IvarInvalidationChecker + : public Checker> { public: ChecksFilter Filter; + public: - void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& Mgr, + void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager &Mgr, BugReporter &BR) const { IvarInvalidationCheckerImpl Walker(Mgr, BR, Filter); Walker.visit(D); diff --git a/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp index fa51aa80216b4..ade57171526e5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp @@ -11,9 +11,9 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/StmtVisitor.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "llvm/ADT/SmallString.h" @@ -128,6 +128,7 @@ class StringRefCheckerVisitor : public StmtVisitor { } void VisitStmt(Stmt *S) { VisitChildren(S); } void VisitDeclStmt(DeclStmt *DS); + private: void VisitVarDecl(VarDecl *VD); }; @@ -179,7 +180,7 @@ void StringRefCheckerVisitor::VisitVarDecl(VarDecl *VD) { const char *desc = "StringRef should not be bound to temporary " "std::string that it outlives"; PathDiagnosticLocation VDLoc = - PathDiagnosticLocation::createBegin(VD, BR.getSourceManager()); + PathDiagnosticLocation::createBegin(VD, BR.getSourceManager()); BR.EmitBasicReport(DeclWithIssue, Checker, desc, "LLVM Conventions", desc, VDLoc, Init->getSourceRange()); } @@ -212,7 +213,7 @@ static bool IsPartOfAST(const CXXRecordDecl *R) { namespace { class ASTFieldVisitor { - SmallVector FieldChain; + SmallVector FieldChain; const CXXRecordDecl *Root; BugReporter &BR; const CheckerBase *Checker; @@ -264,8 +265,9 @@ void ASTFieldVisitor::ReportError(QualType T) { if (FieldChain.size() > 1) { os << " via the following chain: "; bool isFirst = true; - for (SmallVectorImpl::iterator I=FieldChain.begin(), - E=FieldChain.end(); I!=E; ++I) { + for (SmallVectorImpl::iterator I = FieldChain.begin(), + E = FieldChain.end(); + I != E; ++I) { if (!isFirst) os << '.'; else @@ -283,7 +285,7 @@ void ASTFieldVisitor::ReportError(QualType T) { // class, as that heuristic doesn't always work (the complete definition of // the class may be in the header file, for example). PathDiagnosticLocation L = PathDiagnosticLocation::createBegin( - FieldChain.front(), BR.getSourceManager()); + FieldChain.front(), BR.getSourceManager()); BR.EmitBasicReport(Root, Checker, "AST node allocates heap memory", "LLVM Conventions", os.str(), L); } @@ -293,22 +295,21 @@ void ASTFieldVisitor::ReportError(QualType T) { //===----------------------------------------------------------------------===// namespace { -class LLVMConventionsChecker : public Checker< - check::ASTDecl, - check::ASTCodeBody > { +class LLVMConventionsChecker + : public Checker, check::ASTCodeBody> { public: - void checkASTDecl(const CXXRecordDecl *R, AnalysisManager& mgr, + void checkASTDecl(const CXXRecordDecl *R, AnalysisManager &mgr, BugReporter &BR) const { if (R->isCompleteDefinition()) CheckASTMemory(R, BR, this); } - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { CheckStringRefAssignedTemporary(D, BR, this); } }; -} +} // namespace void ento::registerLLVMConventionsChecker(CheckerManager &mgr) { mgr.registerChecker(); diff --git a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp index 812d787e2e37c..d6146d013413f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp @@ -67,7 +67,8 @@ class NonLocalizedStringChecker // Methods that require a localized string mutable llvm::DenseMap> UIMethods; + llvm::DenseMap> + UIMethods; // Methods that return a localized string mutable llvm::SmallSet, 12> LSM; // C Functions that return a localized string @@ -131,8 +132,9 @@ class NonLocalizedStringBRVisitor final : public BugReporterVisitor { #define NEW_RECEIVER(receiver) \ llvm::DenseMap &receiver##M = \ - UIMethods.insert({&Ctx.Idents.get(#receiver), \ - llvm::DenseMap()}) \ + UIMethods \ + .insert({&Ctx.Idents.get(#receiver), \ + llvm::DenseMap()}) \ .first->second; #define ADD_NULLARY_METHOD(receiver, method, argument) \ receiver##M.insert( \ @@ -710,7 +712,6 @@ void NonLocalizedStringChecker::setNonLocalizedState(const SVal S, } } - static bool isDebuggingName(std::string name) { return StringRef(name).contains_insensitive("debug"); } @@ -739,7 +740,6 @@ static bool isDebuggingContext(CheckerContext &C) { return false; } - /// Reports a localization error for the passed in method call and SVal void NonLocalizedStringChecker::reportLocalizationError( SVal S, const CallEvent &M, CheckerContext &C, int argumentNumber) const { @@ -751,7 +751,8 @@ void NonLocalizedStringChecker::reportLocalizationError( static CheckerProgramPointTag Tag("NonLocalizedStringChecker", "UnlocalizedString"); - ExplodedNode *ErrNode = C.addTransition(C.getState(), C.getPredecessor(), &Tag); + ExplodedNode *ErrNode = + C.addTransition(C.getState(), C.getPredecessor(), &Tag); if (!ErrNode) return; @@ -883,7 +884,8 @@ void NonLocalizedStringChecker::checkPreCall(const CallEvent &Call, auto formals = FD->parameters(); for (unsigned i = 0, ei = std::min(static_cast(formals.size()), - Call.getNumArgs()); i != ei; ++i) { + Call.getNumArgs()); + i != ei; ++i) { if (isAnnotatedAsTakingLocalized(formals[i])) { auto actual = Call.getArgSVal(i); if (hasNonLocalizedState(actual, C)) { @@ -1395,9 +1397,8 @@ void PluralMisuseChecker::MethodCrawler::reportPluralMisuseError( void ento::registerNonLocalizedStringChecker(CheckerManager &mgr) { NonLocalizedStringChecker *checker = mgr.registerChecker(); - checker->IsAggressive = - mgr.getAnalyzerOptions().getCheckerBooleanOption( - checker, "AggressiveReport"); + checker->IsAggressive = mgr.getAnalyzerOptions().getCheckerBooleanOption( + checker, "AggressiveReport"); } bool ento::shouldRegisterNonLocalizedStringChecker(const CheckerManager &mgr) { @@ -1409,7 +1410,7 @@ void ento::registerEmptyLocalizationContextChecker(CheckerManager &mgr) { } bool ento::shouldRegisterEmptyLocalizationContextChecker( - const CheckerManager &mgr) { + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp index 153a0a51e9802..176b9a5b3bc6f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp @@ -106,7 +106,6 @@ class MIGChecker : public Checker, void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const { checkReturnAux(RS, C); } - }; } // end anonymous namespace @@ -132,7 +131,7 @@ static const ParmVarDecl *getOriginParam(SVal V, CheckerContext &C, while (const MemRegion *MR = Sym->getOriginRegion()) { const auto *VR = dyn_cast(MR); if (VR && VR->hasStackParametersStorage() && - VR->getStackFrame()->inTopFrame()) + VR->getStackFrame()->inTopFrame()) return cast(VR->getDecl()); const SymbolicRegion *SR = MR->getSymbolicBase(); @@ -165,7 +164,8 @@ static bool isInMIGCall(CheckerContext &C) { // FIXME: AnyCall doesn't support blocks yet, so they remain unchecked // for now. if (!AC->getReturnType(C.getASTContext()) - .getCanonicalType()->isSignedIntegerType()) + .getCanonicalType() + ->isSignedIntegerType()) return false; } @@ -174,7 +174,7 @@ static bool isInMIGCall(CheckerContext &C) { // See if there's an annotated method in the superclass. if (const auto *MD = dyn_cast(D)) - for (const auto *OMD: MD->overridden_methods()) + for (const auto *OMD : MD->overridden_methods()) if (OMD->hasAttr()) return true; @@ -186,8 +186,8 @@ void MIGChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { // If the code is doing reference counting over the parameter, // it opens up an opportunity for safely calling a destructor function. // TODO: We should still check for over-releases. - if (const ParmVarDecl *PVD = - getOriginParam(Call.getArgSVal(0), C, /*IncludeBaseRegions=*/true)) { + if (const ParmVarDecl *PVD = getOriginParam(Call.getArgSVal(0), C, + /*IncludeBaseRegions=*/true)) { // We never need to clean up the program state because these are // top-level parameters anyway, so they're always live. C.addTransition(C.getState()->add(PVD)); @@ -213,7 +213,7 @@ void MIGChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { return; const NoteTag *T = - C.getNoteTag([this, PVD](PathSensitiveBugReport &BR) -> std::string { + C.getNoteTag([this, PVD](PathSensitiveBugReport &BR) -> std::string { if (&BR.getBugType() != &BT) return ""; SmallString<64> Str; @@ -296,6 +296,4 @@ void ento::registerMIGChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } -bool ento::shouldRegisterMIGChecker(const CheckerManager &mgr) { - return true; -} +bool ento::shouldRegisterMIGChecker(const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp index 3e374e6c240e7..3f995ca73a62b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp @@ -22,8 +22,7 @@ namespace mpi { void MPIBugReporter::reportDoubleNonblocking( const CallEvent &MPICallEvent, const ento::mpi::Request &Req, - const MemRegion *const RequestRegion, - const ExplodedNode *const ExplNode, + const MemRegion *const RequestRegion, const ExplodedNode *const ExplNode, BugReporter &BReporter) const { std::string ErrorText; @@ -46,10 +45,10 @@ void MPIBugReporter::reportDoubleNonblocking( BReporter.emitReport(std::move(Report)); } -void MPIBugReporter::reportMissingWait( - const ento::mpi::Request &Req, const MemRegion *const RequestRegion, - const ExplodedNode *const ExplNode, - BugReporter &BReporter) const { +void MPIBugReporter::reportMissingWait(const ento::mpi::Request &Req, + const MemRegion *const RequestRegion, + const ExplodedNode *const ExplNode, + BugReporter &BReporter) const { std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() + " has no matching wait. "}; @@ -68,8 +67,7 @@ void MPIBugReporter::reportMissingWait( void MPIBugReporter::reportUnmatchedWait( const CallEvent &CE, const clang::ento::MemRegion *const RequestRegion, - const ExplodedNode *const ExplNode, - BugReporter &BReporter) const { + const ExplodedNode *const ExplNode, BugReporter &BReporter) const { std::string ErrorText{"Request " + RequestRegion->getDescriptiveName() + " has no matching nonblocking call. "}; @@ -112,6 +110,6 @@ MPIBugReporter::RequestNodeVisitor::VisitNode(const ExplodedNode *N, return nullptr; } -} // end of namespace: mpi -} // end of namespace: ento -} // end of namespace: clang +} // namespace mpi +} // namespace ento +} // namespace clang diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h index 0222a2120b34f..dd84c8c898c19 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h +++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h @@ -42,7 +42,7 @@ class MPIBugReporter { const Request &Req, const MemRegion *const RequestRegion, const ExplodedNode *const ExplNode, - BugReporter &BReporter) const; + BugReporter &BReporter) const; /// Report a missing wait for a nonblocking call. /// @@ -97,8 +97,8 @@ class MPIBugReporter { }; }; -} // end of namespace: mpi -} // end of namespace: ento -} // end of namespace: clang +} // namespace mpi +} // namespace ento +} // namespace clang #endif diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp index 4c0a8ba2c7c09..280403167b38e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp @@ -181,9 +181,9 @@ void MPIChecker::allRegionsUsedByWait( } } -} // end of namespace: mpi -} // end of namespace: ento -} // end of namespace: clang +} // namespace mpi +} // namespace ento +} // namespace clang // Registers the checker for static analysis. void clang::ento::registerMPIChecker(CheckerManager &MGR) { diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h index ce9f1afac2090..23d0e7dd25430 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h +++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h @@ -97,8 +97,8 @@ class MPIChecker : public Checker { MPIBugReporter BReporter; }; -} // end of namespace: mpi -} // end of namespace: ento -} // end of namespace: clang +} // namespace mpi +} // namespace ento +} // namespace clang #endif diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp index 277b3ed2e1056..57d16193e386a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp @@ -278,6 +278,6 @@ bool MPIFunctionClassifier::isWaitType(const IdentifierInfo *IdentInfo) const { return IdentInfo == IdentInfo_MPI_Wait || IdentInfo == IdentInfo_MPI_Waitall; } -} // end of namespace: mpi -} // end of namespace: ento -} // end of namespace: clang +} // namespace mpi +} // namespace ento +} // namespace clang diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h index fe0fb2a4d0e72..22767273c21b7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h +++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h @@ -50,7 +50,7 @@ typedef llvm::ImmutableMap RequestMapImpl; -} // end of namespace: mpi +} // namespace mpi template <> struct ProgramStateTrait @@ -61,6 +61,6 @@ struct ProgramStateTrait } }; -} // end of namespace: ento -} // end of namespace: clang +} // namespace ento +} // namespace clang #endif diff --git a/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp index 12bf12a0b2322..70d4bfb450d2e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp @@ -28,11 +28,9 @@ using namespace clang; using namespace ento; namespace { -class MacOSKeychainAPIChecker : public Checker, - check::PostStmt, - check::DeadSymbols, - check::PointerEscape, - eval::Assume> { +class MacOSKeychainAPIChecker + : public Checker, check::PostStmt, + check::DeadSymbols, check::PointerEscape, eval::Assume> { const BugType BT{this, "Improper use of SecKeychain API", categories::AppleAPIMisuse}; @@ -44,13 +42,11 @@ class MacOSKeychainAPIChecker : public Checker, unsigned int AllocatorIdx; SymbolRef Region; - AllocationState(const Expr *E, unsigned int Idx, SymbolRef R) : - AllocatorIdx(Idx), - Region(R) {} + AllocationState(const Expr *E, unsigned int Idx, SymbolRef R) + : AllocatorIdx(Idx), Region(R) {} bool operator==(const AllocationState &X) const { - return (AllocatorIdx == X.AllocatorIdx && - Region == X.Region); + return (AllocatorIdx == X.AllocatorIdx && Region == X.Region); } void Profile(llvm::FoldingSetNodeID &ID) const { @@ -68,11 +64,11 @@ class MacOSKeychainAPIChecker : public Checker, PointerEscapeKind Kind) const; ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, bool Assumption) const; - void printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep) const override; + void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, + const char *Sep) const override; private: - typedef std::pair AllocationPair; + typedef std::pair AllocationPair; typedef SmallVector AllocationPairVec; enum APIKind { @@ -87,7 +83,7 @@ class MacOSKeychainAPIChecker : public Checker, /// Stores the information about the allocator and deallocator functions - /// these are the functions the checker is tracking. struct ADFunctionInfo { - const char* Name; + const char *Name; unsigned int Param; unsigned int DeallocatorIdx; APIKind Kind; @@ -144,13 +140,12 @@ class MacOSKeychainAPIChecker : public Checker, PathSensitiveBugReport &BR) override; }; }; -} +} // namespace /// ProgramState traits to store the currently allocated (and not yet freed) /// symbols. This is a map from the allocated content symbol to the /// corresponding AllocationState. -REGISTER_MAP_WITH_PROGRAMSTATE(AllocatedData, - SymbolRef, +REGISTER_MAP_WITH_PROGRAMSTATE(AllocatedData, SymbolRef, MacOSKeychainAPIChecker::AllocationState) static bool isEnclosingFunctionParam(const Expr *E) { @@ -164,15 +159,15 @@ static bool isEnclosingFunctionParam(const Expr *E) { } const MacOSKeychainAPIChecker::ADFunctionInfo - MacOSKeychainAPIChecker::FunctionsToTrack[FunctionsToTrackSize] = { - {"SecKeychainItemCopyContent", 4, 3, ValidAPI}, // 0 - {"SecKeychainFindGenericPassword", 6, 3, ValidAPI}, // 1 - {"SecKeychainFindInternetPassword", 13, 3, ValidAPI}, // 2 - {"SecKeychainItemFreeContent", 1, InvalidIdx, ValidAPI}, // 3 - {"SecKeychainItemCopyAttributesAndData", 5, 5, ValidAPI}, // 4 - {"SecKeychainItemFreeAttributesAndData", 1, InvalidIdx, ValidAPI}, // 5 - {"free", 0, InvalidIdx, ErrorAPI}, // 6 - {"CFStringCreateWithBytesNoCopy", 1, InvalidIdx, PossibleAPI}, // 7 + MacOSKeychainAPIChecker::FunctionsToTrack[FunctionsToTrackSize] = { + {"SecKeychainItemCopyContent", 4, 3, ValidAPI}, // 0 + {"SecKeychainFindGenericPassword", 6, 3, ValidAPI}, // 1 + {"SecKeychainFindInternetPassword", 13, 3, ValidAPI}, // 2 + {"SecKeychainItemFreeContent", 1, InvalidIdx, ValidAPI}, // 3 + {"SecKeychainItemCopyAttributesAndData", 5, 5, ValidAPI}, // 4 + {"SecKeychainItemFreeAttributesAndData", 1, InvalidIdx, ValidAPI}, // 5 + {"free", 0, InvalidIdx, ErrorAPI}, // 6 + {"CFStringCreateWithBytesNoCopy", 1, InvalidIdx, PossibleAPI}, // 7 }; unsigned MacOSKeychainAPIChecker::getTrackedFunctionIndex(StringRef Name, @@ -201,13 +196,12 @@ static bool isBadDeallocationArgument(const MemRegion *Arg) { /// Given the address expression, retrieve the value it's pointing to. Assume /// that value is itself an address, and return the corresponding symbol. -static SymbolRef getAsPointeeSymbol(const Expr *Expr, - CheckerContext &C) { +static SymbolRef getAsPointeeSymbol(const Expr *Expr, CheckerContext &C) { ProgramStateRef State = C.getState(); SVal ArgV = C.getSVal(Expr); if (std::optional X = ArgV.getAs()) { - StoreManager& SM = C.getStoreManager(); + StoreManager &SM = C.getStoreManager(); SymbolRef sym = SM.getBinding(State->getStore(), *X).getAsLocSymbol(); if (sym) return sym; @@ -217,10 +211,8 @@ static SymbolRef getAsPointeeSymbol(const Expr *Expr, // Report deallocator mismatch. Remove the region from tracking - reporting a // missing free error after this one is redundant. -void MacOSKeychainAPIChecker:: - generateDeallocatorMismatchReport(const AllocationPair &AP, - const Expr *ArgExpr, - CheckerContext &C) const { +void MacOSKeychainAPIChecker::generateDeallocatorMismatchReport( + const AllocationPair &AP, const Expr *ArgExpr, CheckerContext &C) const { ProgramStateRef State = C.getState(); State = State->remove(AP.first); ExplodedNode *N = C.generateNonFatalErrorNode(State); @@ -230,7 +222,7 @@ void MacOSKeychainAPIChecker:: SmallString<80> sbuf; llvm::raw_svector_ostream os(sbuf); unsigned int PDeallocIdx = - FunctionsToTrack[AP.second->AllocatorIdx].DeallocatorIdx; + FunctionsToTrack[AP.second->AllocatorIdx].DeallocatorIdx; os << "Deallocator doesn't match the allocator: '" << FunctionsToTrack[PDeallocIdx].Name << "' should be used."; @@ -274,9 +266,8 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE, llvm::raw_svector_ostream os(sbuf); unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx; os << "Allocated data should be released before another call to " - << "the allocator: missing a call to '" - << FunctionsToTrack[DIdx].Name - << "'."; + << "the allocator: missing a call to '" + << FunctionsToTrack[DIdx].Name << "'."; auto Report = std::make_unique(BT, os.str(), N); Report->addVisitor(std::make_unique(V)); Report->addRange(ArgExpr->getSourceRange()); @@ -345,8 +336,8 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE, if (funName == "CFStringCreateWithBytesNoCopy") { const Expr *DeallocatorExpr = CE->getArg(5)->IgnoreParenCasts(); // NULL ~ default deallocator, so warn. - if (DeallocatorExpr->isNullPointerConstant(C.getASTContext(), - Expr::NPC_ValueDependentIsNotNull)) { + if (DeallocatorExpr->isNullPointerConstant( + C.getASTContext(), Expr::NPC_ValueDependentIsNotNull)) { const AllocationPair AP = std::make_pair(ArgSM, AS); generateDeallocatorMismatchReport(AP, ArgExpr, C); return; @@ -429,8 +420,8 @@ void MacOSKeychainAPIChecker::checkPostStmt(const CallExpr *CE, C.getSymbolManager().addSymbolDependency(V, RetStatusSymbol); // Track the allocated value in the checker state. - State = State->set(V, AllocationState(ArgExpr, idx, - RetStatusSymbol)); + State = State->set( + V, AllocationState(ArgExpr, idx, RetStatusSymbol)); assert(State); C.addTransition(State); } @@ -438,8 +429,7 @@ void MacOSKeychainAPIChecker::checkPostStmt(const CallExpr *CE, // TODO: This logic is the same as in Malloc checker. const ExplodedNode * -MacOSKeychainAPIChecker::getAllocationNode(const ExplodedNode *N, - SymbolRef Sym, +MacOSKeychainAPIChecker::getAllocationNode(const ExplodedNode *N, SymbolRef Sym, CheckerContext &C) const { const LocationContext *LeakContext = N->getLocationContext(); // Walk the ExplodedGraph backwards and find the first node that referred to @@ -452,8 +442,7 @@ MacOSKeychainAPIChecker::getAllocationNode(const ExplodedNode *N, // Allocation node, is the last node in the current or parent context in // which the symbol was tracked. const LocationContext *NContext = N->getLocationContext(); - if (NContext == LeakContext || - NContext->isParentOf(LeakContext)) + if (NContext == LeakContext || NContext->isParentOf(LeakContext)) AllocNode = N; N = N->pred_empty() ? nullptr : *(N->pred_begin()); } @@ -468,7 +457,7 @@ MacOSKeychainAPIChecker::generateAllocatedDataNotReleasedReport( SmallString<70> sbuf; llvm::raw_svector_ostream os(sbuf); os << "Allocated data is not released: missing a call to '" - << FunctionsToTrack[FI.DeallocatorIdx].Name << "'."; + << FunctionsToTrack[FI.DeallocatorIdx].Name << "'."; // Most bug reports are cached at the location where they occurred. // With leaks, we want to unique them by the location where they were @@ -478,9 +467,8 @@ MacOSKeychainAPIChecker::generateAllocatedDataNotReleasedReport( const Stmt *AllocStmt = AllocNode->getStmtForDiagnostics(); if (AllocStmt) - LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocStmt, - C.getSourceManager(), - AllocNode->getLocationContext()); + LocUsedForUniqueing = PathDiagnosticLocation::createBegin( + AllocStmt, C.getSourceManager(), AllocNode->getLocationContext()); auto Report = std::make_unique( BT, os.str(), N, LocUsedForUniqueing, @@ -512,8 +500,8 @@ ProgramStateRef MacOSKeychainAPIChecker::evalAssume(ProgramStateRef State, SymbolRef ReturnSymbol = nullptr; if (auto *SIE = dyn_cast(CondBSE)) { const llvm::APInt &RHS = SIE->getRHS(); - bool ErrorIsReturned = (OpCode == BO_EQ && RHS != NoErr) || - (OpCode == BO_NE && RHS == NoErr); + bool ErrorIsReturned = + (OpCode == BO_EQ && RHS != NoErr) || (OpCode == BO_NE && RHS == NoErr); if (!Assumption) ErrorIsReturned = !ErrorIsReturned; if (ErrorIsReturned) @@ -639,8 +627,7 @@ MacOSKeychainAPIChecker::SecKeychainBugVisitor::VisitNode( } void MacOSKeychainAPIChecker::printState(raw_ostream &Out, - ProgramStateRef State, - const char *NL, + ProgramStateRef State, const char *NL, const char *Sep) const { AllocatedDataTy AMap = State->get(); @@ -653,7 +640,6 @@ void MacOSKeychainAPIChecker::printState(raw_ostream &Out, } } - void ento::registerMacOSKeychainAPIChecker(CheckerManager &mgr) { mgr.registerChecker(); } diff --git a/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp index 754b167642961..b6e33cc95e0a5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp @@ -31,7 +31,7 @@ using namespace clang; using namespace ento; namespace { -class MacOSXAPIChecker : public Checker< check::PreStmt > { +class MacOSXAPIChecker : public Checker> { const BugType BT_dispatchOnce{this, "Improper use of 'dispatch_once'", categories::AppleAPIMisuse}; @@ -47,7 +47,7 @@ class MacOSXAPIChecker : public Checker< check::PreStmt > { const CallExpr *, StringRef FName) const; }; -} //end anonymous namespace +} // end anonymous namespace //===----------------------------------------------------------------------===// // dispatch_once and dispatch_once_f @@ -155,12 +155,10 @@ void MacOSXAPIChecker::checkPreStmt(const CallExpr *CE, return; SubChecker SC = - llvm::StringSwitch(Name) - .Cases("dispatch_once", - "_dispatch_once", - "dispatch_once_f", - &MacOSXAPIChecker::CheckDispatchOnce) - .Default(nullptr); + llvm::StringSwitch(Name) + .Cases("dispatch_once", "_dispatch_once", "dispatch_once_f", + &MacOSXAPIChecker::CheckDispatchOnce) + .Default(nullptr); if (SC) (this->*SC)(C, CE, Name); diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 79ab05f2c7866..b19fcc71c07d6 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -199,12 +199,15 @@ class RefState { LLVM_DUMP_METHOD void dump(raw_ostream &OS) const { switch (K) { -#define CASE(ID) case ID: OS << #ID; break; - CASE(Allocated) - CASE(AllocatedOfSizeZero) - CASE(Released) - CASE(Relinquished) - CASE(Escaped) +#define CASE(ID) \ + case ID: \ + OS << #ID; \ + break; + CASE(Allocated) + CASE(AllocatedOfSizeZero) + CASE(Released) + CASE(Relinquished) + CASE(Escaped) } } @@ -272,8 +275,7 @@ struct ReallocPair { ID.AddPointer(ReallocatedSym); } bool operator==(const ReallocPair &X) const { - return ReallocatedSym == X.ReallocatedSym && - Kind == X.Kind; + return ReallocatedSym == X.ReallocatedSym && Kind == X.Kind; } }; @@ -333,27 +335,28 @@ class MallocChecker void checkPreCall(const CallEvent &Call, CheckerContext &C) const; void checkPostCall(const CallEvent &Call, CheckerContext &C) const; void checkNewAllocator(const CXXAllocatorCall &Call, CheckerContext &C) const; - void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const; + void checkPostObjCMessage(const ObjCMethodCall &Call, + CheckerContext &C) const; void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const; void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const; void checkEndFunction(const ReturnStmt *S, CheckerContext &C) const; ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, - bool Assumption) const; + bool Assumption) const; void checkLocation(SVal l, bool isLoad, const Stmt *S, CheckerContext &C) const; ProgramStateRef checkPointerEscape(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind) const; + const InvalidatedSymbols &Escaped, + const CallEvent *Call, + PointerEscapeKind Kind) const; ProgramStateRef checkConstPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind) const; - void printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep) const override; + void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, + const char *Sep) const override; private: mutable std::unique_ptr BT_DoubleFree[CK_NumCheckKinds]; @@ -655,9 +658,10 @@ class MallocChecker /// /// We assume that pointers do not escape through calls to system functions /// not handled by this checker. - bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call, - ProgramStateRef State, - SymbolRef &EscapingSymbol) const; + bool + mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call, + ProgramStateRef State, + SymbolRef &EscapingSymbol) const; /// Implementation of the checkPointerEscape callbacks. [[nodiscard]] ProgramStateRef @@ -1183,9 +1187,8 @@ MallocChecker::performKernelMalloc(const CallEvent &Call, CheckerContext &C, NonLoc ZeroFlag = C.getSValBuilder() .makeIntVal(*KernelZeroFlagVal, FlagsEx->getType()) .castAs(); - SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN(State, BO_And, - Flags, ZeroFlag, - FlagsEx->getType()); + SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN( + State, BO_And, Flags, ZeroFlag, FlagsEx->getType()); if (MaskedFlagsUC.isUnknownOrUndef()) return std::nullopt; DefinedSVal MaskedFlags = MaskedFlagsUC.castAs(); @@ -1404,7 +1407,8 @@ void MallocChecker::checkGMallocN(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); SVal Init = UndefinedVal(); - SVal TotalSize = evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1)); + SVal TotalSize = + evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1)); State = MallocMemAux(C, Call, TotalSize, Init, State, AF_Malloc); State = ProcessZeroAllocCheck(Call, 0, State); State = ProcessZeroAllocCheck(Call, 1, State); @@ -1416,7 +1420,8 @@ void MallocChecker::checkGMallocN0(const CallEvent &Call, ProgramStateRef State = C.getState(); SValBuilder &SB = C.getSValBuilder(); SVal Init = SB.makeZeroVal(SB.getContext().CharTy); - SVal TotalSize = evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1)); + SVal TotalSize = + evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1)); State = MallocMemAux(C, Call, TotalSize, Init, State, AF_Malloc); State = ProcessZeroAllocCheck(Call, 0, State); State = ProcessZeroAllocCheck(Call, 1, State); @@ -1543,8 +1548,8 @@ ProgramStateRef MallocChecker::ProcessZeroAllocCheck( const RefState *RS = State->get(Sym); if (RS) { if (RS->isAllocated()) - return TrueState->set(Sym, - RefState::getAllocatedOfSizeZero(RS)); + return TrueState->set( + Sym, RefState::getAllocatedOfSizeZero(RS)); else return State; } else { @@ -1818,8 +1823,8 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, /// Checks if the previous call to free on the given symbol failed - if free /// failed, returns true. Also, returns the corresponding return value symbol. -static bool didPreviousFreeFail(ProgramStateRef State, - SymbolRef Sym, SymbolRef &RetStatusSymbol) { +static bool didPreviousFreeFail(ProgramStateRef State, SymbolRef Sym, + SymbolRef &RetStatusSymbol) { const SymbolRef *Ret = State->get(Sym); if (Ret) { assert(*Ret && "We should not store the null return symbol"); @@ -1872,26 +1877,48 @@ static bool printMemFnName(raw_ostream &os, CheckerContext &C, const Expr *E) { static void printExpectedAllocName(raw_ostream &os, AllocationFamily Family) { - switch(Family) { - case AF_Malloc: os << "malloc()"; return; - case AF_CXXNew: os << "'new'"; return; - case AF_CXXNewArray: os << "'new[]'"; return; - case AF_IfNameIndex: os << "'if_nameindex()'"; return; - case AF_InnerBuffer: os << "container-specific allocator"; return; - case AF_Alloca: - case AF_None: llvm_unreachable("not a deallocation expression"); + switch (Family) { + case AF_Malloc: + os << "malloc()"; + return; + case AF_CXXNew: + os << "'new'"; + return; + case AF_CXXNewArray: + os << "'new[]'"; + return; + case AF_IfNameIndex: + os << "'if_nameindex()'"; + return; + case AF_InnerBuffer: + os << "container-specific allocator"; + return; + case AF_Alloca: + case AF_None: + llvm_unreachable("not a deallocation expression"); } } static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) { - switch(Family) { - case AF_Malloc: os << "free()"; return; - case AF_CXXNew: os << "'delete'"; return; - case AF_CXXNewArray: os << "'delete[]'"; return; - case AF_IfNameIndex: os << "'if_freenameindex()'"; return; - case AF_InnerBuffer: os << "container-specific deallocator"; return; - case AF_Alloca: - case AF_None: llvm_unreachable("suspicious argument"); + switch (Family) { + case AF_Malloc: + os << "free()"; + return; + case AF_CXXNew: + os << "'delete'"; + return; + case AF_CXXNewArray: + os << "'delete[]'"; + return; + case AF_IfNameIndex: + os << "'if_freenameindex()'"; + return; + case AF_InnerBuffer: + os << "container-specific deallocator"; + return; + case AF_Alloca: + case AF_None: + llvm_unreachable("suspicious argument"); } } @@ -2005,8 +2032,8 @@ ProgramStateRef MallocChecker::FreeMemAux( SymBase, PreviousRetStatusSymbol); return nullptr; - // If the pointer is allocated or escaped, but we are now trying to free it, - // check that the call to free is proper. + // If the pointer is allocated or escaped, but we are now trying to free + // it, check that the call to free is proper. } else if (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero() || RsBase->isEscaped()) { @@ -2021,8 +2048,7 @@ ProgramStateRef MallocChecker::FreeMemAux( // Check if the memory location being freed is the actual location // allocated, or an offset. RegionOffset Offset = R->getAsOffset(); - if (Offset.isValid() && - !Offset.hasSymbolicOffset() && + if (Offset.isValid() && !Offset.hasSymbolicOffset() && Offset.getOffset() != 0) { const Expr *AllocExpr = cast(RsBase->getStmt()); HandleOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr, @@ -2060,9 +2086,8 @@ ProgramStateRef MallocChecker::FreeMemAux( // Normal free. if (Hold) - return State->set(SymBase, - RefState::getRelinquished(Family, - ParentExpr)); + return State->set( + SymBase, RefState::getRelinquished(Family, ParentExpr)); return State->set(SymBase, RefState::getReleased(Family, ParentExpr)); @@ -2084,8 +2109,7 @@ MallocChecker::getCheckIfTracked(AllocationFamily Family, if (IsALeakCheck) { if (ChecksEnabled[CK_NewDeleteLeaksChecker]) return CK_NewDeleteLeaksChecker; - } - else { + } else { if (ChecksEnabled[CK_NewDeleteChecker]) return CK_NewDeleteChecker; } @@ -2129,8 +2153,7 @@ bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) { return true; } -bool MallocChecker::SummarizeRegion(raw_ostream &os, - const MemRegion *MR) { +bool MallocChecker::SummarizeRegion(raw_ostream &os, const MemRegion *MR) { switch (MR->getKind()) { case MemRegion::FunctionCodeRegionKind: { const NamedDecl *FD = cast(MR)->getDecl(); @@ -2234,8 +2257,7 @@ void MallocChecker::HandleNonHeapDealloc(CheckerContext &C, SVal ArgVal, os << "deallocator"; os << " is "; - bool Summarized = MR ? SummarizeRegion(os, MR) - : SummarizeValue(os, ArgVal); + bool Summarized = MR ? SummarizeRegion(os, MR) : SummarizeValue(os, ArgVal); if (Summarized) os << ", which is not memory allocated by "; else @@ -2321,10 +2343,10 @@ void MallocChecker::HandleMismatchedDealloc(CheckerContext &C, os << " allocated by " << AllocOs.str(); os << " should be deallocated by "; - printExpectedDeallocName(os, RS->getAllocationFamily()); + printExpectedDeallocName(os, RS->getAllocationFamily()); - if (printMemFnName(DeallocOs, C, DeallocExpr)) - os << ", not " << DeallocOs.str(); + if (printMemFnName(DeallocOs, C, DeallocExpr)) + os << ", not " << DeallocOs.str(); } auto R = std::make_unique(*BT_MismatchedDealloc, @@ -2367,8 +2389,7 @@ void MallocChecker::HandleOffsetFree(CheckerContext &C, SVal ArgVal, assert(MR && "Only MemRegion based symbols can have offset free errors"); RegionOffset Offset = MR->getAsOffset(); - assert((Offset.isValid() && - !Offset.hasSymbolicOffset() && + assert((Offset.isValid() && !Offset.hasSymbolicOffset() && Offset.getOffset() != 0) && "Only symbols with a valid offset can have offset free errors"); @@ -2377,11 +2398,8 @@ void MallocChecker::HandleOffsetFree(CheckerContext &C, SVal ArgVal, os << "Argument to "; if (!printMemFnName(os, C, DeallocExpr)) os << "deallocator"; - os << " is offset by " - << offsetBytes - << " " - << ((abs(offsetBytes) > 1) ? "bytes" : "byte") - << " from the start of "; + os << " is offset by " << offsetBytes << " " + << ((abs(offsetBytes) > 1) ? "bytes" : "byte") << " from the start of "; if (AllocExpr && printMemFnName(AllocNameOs, C, AllocExpr)) os << "memory allocated by " << AllocNameOs.str(); else @@ -2662,8 +2680,8 @@ MallocChecker::ReallocMemAux(CheckerContext &C, const CallEvent &Call, // Record the info about the reallocated symbol so that we could properly // process failed reallocation. - stateRealloc = stateRealloc->set(ToPtr, - ReallocPair(FromPtr, Kind)); + stateRealloc = + stateRealloc->set(ToPtr, ReallocPair(FromPtr, Kind)); // The reallocated symbol should stay alive for as long as the new symbol. C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr); return stateRealloc; @@ -2720,8 +2738,7 @@ MallocChecker::LeakInfo MallocChecker::getAllocationSite(const ExplodedNode *N, // Allocation node, is the last node in the current or parent context in // which the symbol was tracked. const LocationContext *NContext = N->getLocationContext(); - if (NContext == LeakContext || - NContext->isParentOf(LeakContext)) + if (NContext == LeakContext || NContext->isParentOf(LeakContext)) AllocNode = N; N = N->pred_empty() ? nullptr : *(N->pred_begin()); } @@ -2771,9 +2788,8 @@ void MallocChecker::HandleLeak(SymbolRef Sym, ExplodedNode *N, const Stmt *AllocationStmt = AllocNode->getStmtForDiagnostics(); if (AllocationStmt) - LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt, - C.getSourceManager(), - AllocNode->getLocationContext()); + LocUsedForUniqueing = PathDiagnosticLocation::createBegin( + AllocationStmt, C.getSourceManager(), AllocNode->getLocationContext()); SmallString<200> buf; llvm::raw_svector_ostream os(buf); @@ -2795,8 +2811,7 @@ void MallocChecker::HandleLeak(SymbolRef Sym, ExplodedNode *N, } void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper, - CheckerContext &C) const -{ + CheckerContext &C) const { ProgramStateRef state = C.getState(); RegionStateTy OldRS = state->get(); RegionStateTy::Factory &F = state->get_context(); @@ -2814,8 +2829,7 @@ void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper, if (RS == OldRS) { // We shouldn't have touched other maps yet. - assert(state->get() == - C.getState()->get()); + assert(state->get() == C.getState()->get()); assert(state->get() == C.getState()->get()); return; @@ -2911,8 +2925,7 @@ void MallocChecker::checkPreCall(const CallEvent &Call, } } -void MallocChecker::checkPreStmt(const ReturnStmt *S, - CheckerContext &C) const { +void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const { checkEscapeOnReturn(S, C); } @@ -2944,7 +2957,7 @@ void MallocChecker::checkEscapeOnReturn(const ReturnStmt *S, if (const MemRegion *MR = RetVal.getAsRegion()) if (isa(MR)) if (const SymbolicRegion *BMR = - dyn_cast(MR->getBaseRegion())) + dyn_cast(MR->getBaseRegion())) Sym = BMR->getSymbol(); // Check if we are returning freed memory. @@ -2964,14 +2977,13 @@ void MallocChecker::checkPostStmt(const BlockExpr *BE, return; ProgramStateRef state = C.getState(); - const BlockDataRegion *R = - cast(C.getSVal(BE).getAsRegion()); + const BlockDataRegion *R = cast(C.getSVal(BE).getAsRegion()); auto ReferencedVars = R->referenced_vars(); if (ReferencedVars.empty()) return; - SmallVector Regions; + SmallVector Regions; const LocationContext *LC = C.getLocationContext(); MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager(); @@ -2983,8 +2995,7 @@ void MallocChecker::checkPostStmt(const BlockExpr *BE, Regions.push_back(VR); } - state = - state->scanReachableSymbols(Regions).getState(); + state = state->scanReachableSymbols(Regions).getState(); C.addTransition(state); } @@ -3041,8 +3052,7 @@ void MallocChecker::checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C, if (const RefState *RS = C.getState()->get(Sym)) { if (RS->isAllocatedOfSizeZero()) HandleUseZeroAlloc(C, RS->getStmt()->getSourceRange(), Sym); - } - else if (C.getState()->contains(Sym)) { + } else if (C.getState()->contains(Sym)) { HandleUseZeroAlloc(C, S->getSourceRange(), Sym); } } @@ -3068,9 +3078,8 @@ void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S, // If a symbolic region is assumed to NULL (or another constant), stop tracking // it - assuming that allocation failed on this path. -ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, - SVal Cond, - bool Assumption) const { +ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, SVal Cond, + bool Assumption) const { RegionStateTy RS = state->get(); for (SymbolRef Sym : llvm::make_first_range(RS)) { // If the symbol is assumed to be NULL, remove it from consideration. @@ -3095,7 +3104,8 @@ ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, if (RS->isReleased()) { switch (ReallocPair.Kind) { case OAR_ToBeFreedAfterFailure: - state = state->set(ReallocSym, + state = state->set( + ReallocSym, RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt())); break; case OAR_DoNotTrackAfterFailure: @@ -3113,9 +3123,8 @@ ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, } bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( - const CallEvent *Call, - ProgramStateRef State, - SymbolRef &EscapingSymbol) const { + const CallEvent *Call, ProgramStateRef State, + SymbolRef &EscapingSymbol) const { assert(Call); EscapingSymbol = nullptr; @@ -3225,8 +3234,8 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( // Do not warn on pointers passed to 'setbuf' when used with std streams, // these leaks might be intentional when setting the buffer for stdio. // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer - if (FName == "setbuf" || FName =="setbuffer" || - FName == "setlinebuf" || FName == "setvbuf") { + if (FName == "setbuf" || FName == "setbuffer" || FName == "setlinebuf" || + FName == "setvbuf") { if (Call->getNumArgs() >= 1) { const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts(); if (const DeclRefExpr *ArgDRE = dyn_cast(ArgE)) @@ -3276,18 +3285,16 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( return false; } -ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind) const { +ProgramStateRef MallocChecker::checkPointerEscape( + ProgramStateRef State, const InvalidatedSymbols &Escaped, + const CallEvent *Call, PointerEscapeKind Kind) const { return checkPointerEscapeAux(State, Escaped, Call, Kind, /*IsConstPointerEscape*/ false); } -ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind) const { +ProgramStateRef MallocChecker::checkConstPointerEscape( + ProgramStateRef State, const InvalidatedSymbols &Escaped, + const CallEvent *Call, PointerEscapeKind Kind) const { // If a const pointer escapes, it may not be freed(), but it could be deleted. return checkPointerEscapeAux(State, Escaped, Call, Kind, /*IsConstPointerEscape*/ true); @@ -3418,51 +3425,51 @@ PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N, } else if (isReleased(RSCurr, RSPrev, S)) { const auto Family = RSCurr->getAllocationFamily(); switch (Family) { - case AF_Alloca: - case AF_Malloc: - case AF_CXXNew: - case AF_CXXNewArray: - case AF_IfNameIndex: - Msg = "Memory is released"; + case AF_Alloca: + case AF_Malloc: + case AF_CXXNew: + case AF_CXXNewArray: + case AF_IfNameIndex: + Msg = "Memory is released"; + StackHint = std::make_unique( + Sym, "Returning; memory was released"); + break; + case AF_InnerBuffer: { + const MemRegion *ObjRegion = + allocation_state::getContainerObjRegion(statePrev, Sym); + const auto *TypedRegion = cast(ObjRegion); + QualType ObjTy = TypedRegion->getValueType(); + OS << "Inner buffer of '" << ObjTy << "' "; + + if (N->getLocation().getKind() == ProgramPoint::PostImplicitCallKind) { + OS << "deallocated by call to destructor"; StackHint = std::make_unique( - Sym, "Returning; memory was released"); - break; - case AF_InnerBuffer: { - const MemRegion *ObjRegion = - allocation_state::getContainerObjRegion(statePrev, Sym); - const auto *TypedRegion = cast(ObjRegion); - QualType ObjTy = TypedRegion->getValueType(); - OS << "Inner buffer of '" << ObjTy << "' "; - - if (N->getLocation().getKind() == ProgramPoint::PostImplicitCallKind) { - OS << "deallocated by call to destructor"; - StackHint = std::make_unique( - Sym, "Returning; inner buffer was deallocated"); - } else { - OS << "reallocated by call to '"; - const Stmt *S = RSCurr->getStmt(); - if (const auto *MemCallE = dyn_cast(S)) { - OS << MemCallE->getMethodDecl()->getDeclName(); - } else if (const auto *OpCallE = dyn_cast(S)) { - OS << OpCallE->getDirectCallee()->getDeclName(); - } else if (const auto *CallE = dyn_cast(S)) { - auto &CEMgr = BRC.getStateManager().getCallEventManager(); - CallEventRef<> Call = - CEMgr.getSimpleCall(CallE, state, CurrentLC, {nullptr, 0}); - if (const auto *D = dyn_cast_or_null(Call->getDecl())) - OS << D->getDeclName(); - else - OS << "unknown"; - } - OS << "'"; - StackHint = std::make_unique( - Sym, "Returning; inner buffer was reallocated"); + Sym, "Returning; inner buffer was deallocated"); + } else { + OS << "reallocated by call to '"; + const Stmt *S = RSCurr->getStmt(); + if (const auto *MemCallE = dyn_cast(S)) { + OS << MemCallE->getMethodDecl()->getDeclName(); + } else if (const auto *OpCallE = dyn_cast(S)) { + OS << OpCallE->getDirectCallee()->getDeclName(); + } else if (const auto *CallE = dyn_cast(S)) { + auto &CEMgr = BRC.getStateManager().getCallEventManager(); + CallEventRef<> Call = + CEMgr.getSimpleCall(CallE, state, CurrentLC, {nullptr, 0}); + if (const auto *D = dyn_cast_or_null(Call->getDecl())) + OS << D->getDeclName(); + else + OS << "unknown"; } - Msg = OS.str(); - break; + OS << "'"; + StackHint = std::make_unique( + Sym, "Returning; inner buffer was reallocated"); } - case AF_None: - llvm_unreachable("Unhandled allocation family!"); + Msg = OS.str(); + break; + } + case AF_None: + llvm_unreachable("Unhandled allocation family!"); } // See if we're releasing memory while inlining a destructor @@ -3506,13 +3513,13 @@ PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N, if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) { // Is it possible to fail two reallocs WITHOUT testing in between? assert((!FailedReallocSymbol || FailedReallocSymbol == sym) && - "We only support one failed realloc at a time."); + "We only support one failed realloc at a time."); BR.markInteresting(sym); FailedReallocSymbol = sym; } } - // We are in a special mode if a reallocation failed later in the path. + // We are in a special mode if a reallocation failed later in the path. } else if (Mode == ReallocationFailed) { assert(FailedReallocSymbol && "No symbol to look for."); @@ -3582,8 +3589,8 @@ namespace clang { namespace ento { namespace allocation_state { -ProgramStateRef -markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) { +ProgramStateRef markReleased(ProgramStateRef State, SymbolRef Sym, + const Expr *Origin) { AllocationFamily Family = AF_InnerBuffer; return State->set(Sym, RefState::getReleased(Family, Origin)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp index 3c8b38973c6b8..fe3e6a74a468c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp @@ -17,8 +17,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/EvaluatedExprVisitor.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -53,9 +53,8 @@ class MallocOverflowSecurityChecker : public Checker { const CallExpr *TheCall, ASTContext &Context) const; void OutputPossibleOverflows( - SmallVectorImpl &PossibleMallocOverflows, - const Decl *D, BugReporter &BR, AnalysisManager &mgr) const; - + SmallVectorImpl &PossibleMallocOverflows, + const Decl *D, BugReporter &BR, AnalysisManager &mgr) const; }; } // end anonymous namespace @@ -74,7 +73,7 @@ void MallocOverflowSecurityChecker::CheckMallocArgument( conditional expression, an operation that could reduce the range of the result, or anything too complicated :-). */ const Expr *e = TheCall->getArg(0); - const BinaryOperator * mulop = nullptr; + const BinaryOperator *mulop = nullptr; APSInt maxVal; for (;;) { @@ -122,144 +121,136 @@ void MallocOverflowSecurityChecker::CheckMallocArgument( namespace { // A worker class for OutputPossibleOverflows. -class CheckOverflowOps : - public EvaluatedExprVisitor { +class CheckOverflowOps : public EvaluatedExprVisitor { public: typedef SmallVectorImpl theVecType; private: - theVecType &toScanFor; - ASTContext &Context; - - bool isIntZeroExpr(const Expr *E) const { - if (!E->getType()->isIntegralOrEnumerationType()) - return false; - Expr::EvalResult Result; - if (E->EvaluateAsInt(Result, Context)) - return Result.Val.getInt() == 0; + theVecType &toScanFor; + ASTContext &Context; + + bool isIntZeroExpr(const Expr *E) const { + if (!E->getType()->isIntegralOrEnumerationType()) return false; - } + Expr::EvalResult Result; + if (E->EvaluateAsInt(Result, Context)) + return Result.Val.getInt() == 0; + return false; + } - static const Decl *getDecl(const DeclRefExpr *DR) { return DR->getDecl(); } - static const Decl *getDecl(const MemberExpr *ME) { - return ME->getMemberDecl(); - } + static const Decl *getDecl(const DeclRefExpr *DR) { return DR->getDecl(); } + static const Decl *getDecl(const MemberExpr *ME) { + return ME->getMemberDecl(); + } - template - void Erase(const T1 *DR, - llvm::function_ref Pred) { - auto P = [DR, Pred](const MallocOverflowCheck &Check) { - if (const auto *CheckDR = dyn_cast(Check.variable)) - return getDecl(CheckDR) == getDecl(DR) && Pred(Check); - return false; - }; - llvm::erase_if(toScanFor, P); - } + template + void Erase(const T1 *DR, + llvm::function_ref Pred) { + auto P = [DR, Pred](const MallocOverflowCheck &Check) { + if (const auto *CheckDR = dyn_cast(Check.variable)) + return getDecl(CheckDR) == getDecl(DR) && Pred(Check); + return false; + }; + llvm::erase_if(toScanFor, P); + } - void CheckExpr(const Expr *E_p) { - const Expr *E = E_p->IgnoreParenImpCasts(); - const auto PrecedesMalloc = [E, this](const MallocOverflowCheck &c) { - return Context.getSourceManager().isBeforeInTranslationUnit( - E->getExprLoc(), c.call->getExprLoc()); - }; - if (const DeclRefExpr *DR = dyn_cast(E)) - Erase(DR, PrecedesMalloc); - else if (const auto *ME = dyn_cast(E)) { - Erase(ME, PrecedesMalloc); - } + void CheckExpr(const Expr *E_p) { + const Expr *E = E_p->IgnoreParenImpCasts(); + const auto PrecedesMalloc = [E, this](const MallocOverflowCheck &c) { + return Context.getSourceManager().isBeforeInTranslationUnit( + E->getExprLoc(), c.call->getExprLoc()); + }; + if (const DeclRefExpr *DR = dyn_cast(E)) + Erase(DR, PrecedesMalloc); + else if (const auto *ME = dyn_cast(E)) { + Erase(ME, PrecedesMalloc); } + } - // Check if the argument to malloc is assigned a value - // which cannot cause an overflow. - // e.g., malloc (mul * x) and, - // case 1: mul = - // case 2: mul = a/b, where b > x - void CheckAssignmentExpr(BinaryOperator *AssignEx) { - bool assignKnown = false; - bool numeratorKnown = false, denomKnown = false; - APSInt denomVal; - denomVal = 0; - - // Erase if the multiplicand was assigned a constant value. - const Expr *rhs = AssignEx->getRHS(); - if (rhs->isEvaluatable(Context)) - assignKnown = true; - - // Discard the report if the multiplicand was assigned a value, - // that can never overflow after multiplication. e.g., the assignment - // is a division operator and the denominator is > other multiplicand. - const Expr *rhse = rhs->IgnoreParenImpCasts(); - if (const BinaryOperator *BOp = dyn_cast(rhse)) { - if (BOp->getOpcode() == BO_Div) { - const Expr *denom = BOp->getRHS()->IgnoreParenImpCasts(); - Expr::EvalResult Result; - if (denom->EvaluateAsInt(Result, Context)) { - denomVal = Result.Val.getInt(); - denomKnown = true; - } - const Expr *numerator = BOp->getLHS()->IgnoreParenImpCasts(); - if (numerator->isEvaluatable(Context)) - numeratorKnown = true; + // Check if the argument to malloc is assigned a value + // which cannot cause an overflow. + // e.g., malloc (mul * x) and, + // case 1: mul = + // case 2: mul = a/b, where b > x + void CheckAssignmentExpr(BinaryOperator *AssignEx) { + bool assignKnown = false; + bool numeratorKnown = false, denomKnown = false; + APSInt denomVal; + denomVal = 0; + + // Erase if the multiplicand was assigned a constant value. + const Expr *rhs = AssignEx->getRHS(); + if (rhs->isEvaluatable(Context)) + assignKnown = true; + + // Discard the report if the multiplicand was assigned a value, + // that can never overflow after multiplication. e.g., the assignment + // is a division operator and the denominator is > other multiplicand. + const Expr *rhse = rhs->IgnoreParenImpCasts(); + if (const BinaryOperator *BOp = dyn_cast(rhse)) { + if (BOp->getOpcode() == BO_Div) { + const Expr *denom = BOp->getRHS()->IgnoreParenImpCasts(); + Expr::EvalResult Result; + if (denom->EvaluateAsInt(Result, Context)) { + denomVal = Result.Val.getInt(); + denomKnown = true; } + const Expr *numerator = BOp->getLHS()->IgnoreParenImpCasts(); + if (numerator->isEvaluatable(Context)) + numeratorKnown = true; } - if (!assignKnown && !denomKnown) - return; - auto denomExtVal = denomVal.getExtValue(); + } + if (!assignKnown && !denomKnown) + return; + auto denomExtVal = denomVal.getExtValue(); - // Ignore negative denominator. - if (denomExtVal < 0) - return; + // Ignore negative denominator. + if (denomExtVal < 0) + return; - const Expr *lhs = AssignEx->getLHS(); - const Expr *E = lhs->IgnoreParenImpCasts(); + const Expr *lhs = AssignEx->getLHS(); + const Expr *E = lhs->IgnoreParenImpCasts(); - auto pred = [assignKnown, numeratorKnown, - denomExtVal](const MallocOverflowCheck &Check) { - return assignKnown || - (numeratorKnown && (denomExtVal >= Check.maxVal.getExtValue())); - }; + auto pred = [assignKnown, numeratorKnown, + denomExtVal](const MallocOverflowCheck &Check) { + return assignKnown || + (numeratorKnown && (denomExtVal >= Check.maxVal.getExtValue())); + }; - if (const DeclRefExpr *DR = dyn_cast(E)) - Erase(DR, pred); - else if (const auto *ME = dyn_cast(E)) - Erase(ME, pred); - } + if (const DeclRefExpr *DR = dyn_cast(E)) + Erase(DR, pred); + else if (const auto *ME = dyn_cast(E)) + Erase(ME, pred); + } - public: - void VisitBinaryOperator(BinaryOperator *E) { - if (E->isComparisonOp()) { - const Expr * lhs = E->getLHS(); - const Expr * rhs = E->getRHS(); - // Ignore comparisons against zero, since they generally don't - // protect against an overflow. - if (!isIntZeroExpr(lhs) && !isIntZeroExpr(rhs)) { - CheckExpr(lhs); - CheckExpr(rhs); - } +public: + void VisitBinaryOperator(BinaryOperator *E) { + if (E->isComparisonOp()) { + const Expr *lhs = E->getLHS(); + const Expr *rhs = E->getRHS(); + // Ignore comparisons against zero, since they generally don't + // protect against an overflow. + if (!isIntZeroExpr(lhs) && !isIntZeroExpr(rhs)) { + CheckExpr(lhs); + CheckExpr(rhs); } - if (E->isAssignmentOp()) - CheckAssignmentExpr(E); - EvaluatedExprVisitor::VisitBinaryOperator(E); } + if (E->isAssignmentOp()) + CheckAssignmentExpr(E); + EvaluatedExprVisitor::VisitBinaryOperator(E); + } - /* We specifically ignore loop conditions, because they're typically - not error checks. */ - void VisitWhileStmt(WhileStmt *S) { - return this->Visit(S->getBody()); - } - void VisitForStmt(ForStmt *S) { - return this->Visit(S->getBody()); - } - void VisitDoStmt(DoStmt *S) { - return this->Visit(S->getBody()); - } + /* We specifically ignore loop conditions, because they're typically + not error checks. */ + void VisitWhileStmt(WhileStmt *S) { return this->Visit(S->getBody()); } + void VisitForStmt(ForStmt *S) { return this->Visit(S->getBody()); } + void VisitDoStmt(DoStmt *S) { return this->Visit(S->getBody()); } - CheckOverflowOps(theVecType &v, ASTContext &ctx) - : EvaluatedExprVisitor(ctx), - toScanFor(v), Context(ctx) - { } - }; -} + CheckOverflowOps(theVecType &v, ASTContext &ctx) + : EvaluatedExprVisitor(ctx), toScanFor(v), + Context(ctx) {} +}; +} // namespace // OutputPossibleOverflows - We've found a possible overflow earlier, // now check whether Body might contain a comparison which might be @@ -269,8 +260,8 @@ class CheckOverflowOps : // detect the most blatent cases of overflow and educate the // programmer. void MallocOverflowSecurityChecker::OutputPossibleOverflows( - SmallVectorImpl &PossibleMallocOverflows, - const Decl *D, BugReporter &BR, AnalysisManager &mgr) const { + SmallVectorImpl &PossibleMallocOverflows, + const Decl *D, BugReporter &BR, AnalysisManager &mgr) const { // By far the most common case: nothing to check. if (PossibleMallocOverflows.empty()) return; @@ -291,8 +282,8 @@ void MallocOverflowSecurityChecker::OutputPossibleOverflows( } void MallocOverflowSecurityChecker::checkASTCodeBody(const Decl *D, - AnalysisManager &mgr, - BugReporter &BR) const { + AnalysisManager &mgr, + BugReporter &BR) const { CFG *cfg = mgr.getCFG(D); if (!cfg) @@ -303,29 +294,29 @@ void MallocOverflowSecurityChecker::checkASTCodeBody(const Decl *D, for (CFG::iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it) { CFGBlock *block = *it; - for (CFGBlock::iterator bi = block->begin(), be = block->end(); - bi != be; ++bi) { - if (std::optional CS = bi->getAs()) { - if (const CallExpr *TheCall = dyn_cast(CS->getStmt())) { - // Get the callee. - const FunctionDecl *FD = TheCall->getDirectCallee(); - - if (!FD) - continue; - - // Get the name of the callee. If it's a builtin, strip off the - // prefix. - IdentifierInfo *FnInfo = FD->getIdentifier(); - if (!FnInfo) - continue; - - if (FnInfo->isStr("malloc") || FnInfo->isStr("_MALLOC")) { - if (TheCall->getNumArgs() == 1) - CheckMallocArgument(PossibleMallocOverflows, TheCall, - mgr.getASTContext()); - } + for (CFGBlock::iterator bi = block->begin(), be = block->end(); bi != be; + ++bi) { + if (std::optional CS = bi->getAs()) { + if (const CallExpr *TheCall = dyn_cast(CS->getStmt())) { + // Get the callee. + const FunctionDecl *FD = TheCall->getDirectCallee(); + + if (!FD) + continue; + + // Get the name of the callee. If it's a builtin, strip off the + // prefix. + IdentifierInfo *FnInfo = FD->getIdentifier(); + if (!FnInfo) + continue; + + if (FnInfo->isStr("malloc") || FnInfo->isStr("_MALLOC")) { + if (TheCall->getNumArgs() == 1) + CheckMallocArgument(PossibleMallocOverflows, TheCall, + mgr.getASTContext()); } } + } } } @@ -336,6 +327,7 @@ void ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterMallocOverflowSecurityChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterMallocOverflowSecurityChecker( + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp index 9e81a6bd19fc5..f06ef3500c58e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp @@ -32,7 +32,7 @@ typedef std::pair TypeCallPair; typedef llvm::PointerUnion ExprParent; class CastedAllocFinder - : public ConstStmtVisitor { + : public ConstStmtVisitor { IdentifierInfo *II_malloc, *II_calloc, *II_realloc; public: @@ -45,23 +45,23 @@ class CastedAllocFinder CallRecord(ExprParent CastedExprParent, const Expr *CastedExpr, const TypeSourceInfo *ExplicitCastType, const CallExpr *AllocCall) - : CastedExprParent(CastedExprParent), CastedExpr(CastedExpr), - ExplicitCastType(ExplicitCastType), AllocCall(AllocCall) {} + : CastedExprParent(CastedExprParent), CastedExpr(CastedExpr), + ExplicitCastType(ExplicitCastType), AllocCall(AllocCall) {} }; typedef std::vector CallVec; CallVec Calls; - CastedAllocFinder(ASTContext *Ctx) : - II_malloc(&Ctx->Idents.get("malloc")), - II_calloc(&Ctx->Idents.get("calloc")), - II_realloc(&Ctx->Idents.get("realloc")) {} + CastedAllocFinder(ASTContext *Ctx) + : II_malloc(&Ctx->Idents.get("malloc")), + II_calloc(&Ctx->Idents.get("calloc")), + II_realloc(&Ctx->Idents.get("realloc")) {} void VisitChild(ExprParent Parent, const Stmt *S) { TypeCallPair AllocCall = Visit(S); if (AllocCall.second && AllocCall.second != S) - Calls.push_back(CallRecord(Parent, cast(S), AllocCall.first, - AllocCall.second)); + Calls.push_back( + CallRecord(Parent, cast(S), AllocCall.first, AllocCall.second)); } void VisitChildren(const Stmt *S) { @@ -121,9 +121,7 @@ class SizeofFinder : public ConstStmtVisitor { return Visit(E->getSubExpr()); } - void VisitParenExpr(const ParenExpr *E) { - return Visit(E->getSubExpr()); - } + void VisitParenExpr(const ParenExpr *E) { return Visit(E->getSubExpr()); } void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E) { if (E->getKind() != UETT_SizeOf) @@ -178,7 +176,7 @@ static bool compatibleWithArrayType(ASTContext &C, QualType PT, QualType T) { class MallocSizeofChecker : public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) const { AnalysisDeclContext *ADC = mgr.getAnalysisDeclContext(D); CastedAllocFinder Finder(&BR.getContext()); @@ -228,8 +226,8 @@ class MallocSizeofChecker : public Checker { else OS << "call"; OS << " is converted to a pointer of type '" << PointeeType - << "', which is incompatible with " - << "sizeof operand type '" << SizeofType << "'"; + << "', which is incompatible with " << "sizeof operand type '" + << SizeofType << "'"; SmallVector Ranges; Ranges.push_back(CallRec.AllocCall->getCallee()->getSourceRange()); Ranges.push_back(SFinder.Sizeofs[0]->getSourceRange()); @@ -246,7 +244,7 @@ class MallocSizeofChecker : public Checker { } }; -} +} // namespace void ento::registerMallocSizeofChecker(CheckerManager &mgr) { mgr.registerChecker(); diff --git a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp index 82a6228318179..8dd8639ac0bd0 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp @@ -18,7 +18,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" - #include "Iterator.h" using namespace clang; @@ -28,7 +27,7 @@ using namespace iterator; namespace { class MismatchedIteratorChecker - : public Checker> { + : public Checker> { const BugType MismatchedBugType{this, "Iterator(s) mismatched", "Misuse of STL APIs", @@ -44,7 +43,6 @@ class MismatchedIteratorChecker public: void checkPreCall(const CallEvent &Call, CheckerContext &C) const; void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; - }; } // namespace @@ -223,8 +221,8 @@ void MismatchedIteratorChecker::verifyMatch(CheckerContext &C, SVal Iter, if (!N) { return; } - reportBug("Container accessed using foreign iterator argument.", - Iter, Cont, C, N); + reportBug("Container accessed using foreign iterator argument.", Iter, Cont, + C, N); } } @@ -262,7 +260,8 @@ void MismatchedIteratorChecker::verifyMatch(CheckerContext &C, SVal Iter1, if (!N) return; reportBug("Iterators of different containers used where the " - "same container is expected.", Iter1, Iter2, C, N); + "same container is expected.", + Iter1, Iter2, C, N); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp index 2e31c16e457c2..6304367c6c7f4 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp @@ -41,14 +41,14 @@ class MmapWriteExecChecker : public Checker { int ProtExecOv; int ProtReadOv; }; -} +} // namespace int MmapWriteExecChecker::ProtWrite = 0x02; -int MmapWriteExecChecker::ProtExec = 0x04; -int MmapWriteExecChecker::ProtRead = 0x01; +int MmapWriteExecChecker::ProtExec = 0x04; +int MmapWriteExecChecker::ProtRead = 0x01; void MmapWriteExecChecker::checkPreCall(const CallEvent &Call, - CheckerContext &C) const { + CheckerContext &C) const { if (matchesAny(Call, MmapFn, MprotectFn)) { SVal ProtVal = Call.getArgSVal(2); auto ProtLoc = ProtVal.getAs(); @@ -82,14 +82,11 @@ void MmapWriteExecChecker::checkPreCall(const CallEvent &Call, } void ento::registerMmapWriteExecChecker(CheckerManager &mgr) { - MmapWriteExecChecker *Mwec = - mgr.registerChecker(); + MmapWriteExecChecker *Mwec = mgr.registerChecker(); Mwec->ProtExecOv = - mgr.getAnalyzerOptions() - .getCheckerIntegerOption(Mwec, "MmapProtExec"); + mgr.getAnalyzerOptions().getCheckerIntegerOption(Mwec, "MmapProtExec"); Mwec->ProtReadOv = - mgr.getAnalyzerOptions() - .getCheckerIntegerOption(Mwec, "MmapProtRead"); + mgr.getAnalyzerOptions().getCheckerIntegerOption(Mwec, "MmapProtRead"); } bool ento::shouldRegisterMmapWriteExecChecker(const CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp index 5240352a9bd2f..636500c5dc4b3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp @@ -45,9 +45,8 @@ struct RegionState { } // end of anonymous namespace namespace { -class MoveChecker - : public Checker { +class MoveChecker : public Checker { public: void checkPreCall(const CallEvent &MC, CheckerContext &C) const; void checkPostCall(const CallEvent &MC, CheckerContext &C) const; @@ -58,8 +57,8 @@ class MoveChecker ArrayRef RequestedRegions, ArrayRef InvalidatedRegions, const LocationContext *LCtx, const CallEvent *Call) const; - void printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep) const override; + void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, + const char *Sep) const override; private: enum MisuseKind { MK_FunCall, MK_Copy, MK_Move, MK_Dereference }; @@ -73,9 +72,7 @@ class MoveChecker AK_NumKinds = AK_All }; - static bool misuseCausesCrash(MisuseKind MK) { - return MK == MK_Dereference; - } + static bool misuseCausesCrash(MisuseKind MK) { return MK == MK_Dereference; } struct ObjectKind { // Is this a local variable or a local rvalue reference? @@ -99,16 +96,9 @@ class MoveChecker // TODO: We can still try to identify *unsafe* use after move, // like we did with smart pointers. const llvm::StringSet<> StdSafeClasses = { - "basic_filebuf", - "basic_ios", - "future", - "optional", - "packaged_task", - "promise", - "shared_future", - "shared_lock", - "thread", - "unique_lock", + "basic_filebuf", "basic_ios", "future", "optional", + "packaged_task", "promise", "shared_future", "shared_lock", + "thread", "unique_lock", }; // Should we bother tracking the state of the object? @@ -188,15 +178,15 @@ class MoveChecker public: void setAggressiveness(StringRef Str, CheckerManager &Mgr) { - Aggressiveness = - llvm::StringSwitch(Str) - .Case("KnownsOnly", AK_KnownsOnly) - .Case("KnownsAndLocals", AK_KnownsAndLocals) - .Case("All", AK_All) - .Default(AK_Invalid); + Aggressiveness = llvm::StringSwitch(Str) + .Case("KnownsOnly", AK_KnownsOnly) + .Case("KnownsAndLocals", AK_KnownsAndLocals) + .Case("All", AK_All) + .Default(AK_Invalid); if (Aggressiveness == AK_Invalid) - Mgr.reportInvalidCheckerOptionValue(this, "WarnOn", + Mgr.reportInvalidCheckerOptionValue( + this, "WarnOn", "either \"KnownsOnly\", \"KnownsAndLocals\" or \"All\" string value"); }; @@ -300,28 +290,28 @@ MoveChecker::MovedBugVisitor::VisitNode(const ExplodedNode *N, ObjectKind OK = Chk.classifyObject(Region, RD); switch (OK.StdKind) { - case SK_SmartPtr: - if (MK == MK_Dereference) { - OS << "Smart pointer"; - Chk.explainObject(OS, Region, RD, MK); - OS << " is reset to null when moved from"; - break; - } - - // If it's not a dereference, we don't care if it was reset to null - // or that it is even a smart pointer. - [[fallthrough]]; - case SK_NonStd: - case SK_Safe: - OS << "Object"; + case SK_SmartPtr: + if (MK == MK_Dereference) { + OS << "Smart pointer"; Chk.explainObject(OS, Region, RD, MK); - OS << " is moved"; - break; - case SK_Unsafe: - OS << "Object"; - Chk.explainObject(OS, Region, RD, MK); - OS << " is left in a valid but unspecified state after move"; + OS << " is reset to null when moved from"; break; + } + + // If it's not a dereference, we don't care if it was reset to null + // or that it is even a smart pointer. + [[fallthrough]]; + case SK_NonStd: + case SK_Safe: + OS << "Object"; + Chk.explainObject(OS, Region, RD, MK); + OS << " is moved"; + break; + case SK_Unsafe: + OS << "Object"; + Chk.explainObject(OS, Region, RD, MK); + OS << " is left in a valid but unspecified state after move"; + break; } // Generate the extra diagnostic. @@ -359,8 +349,8 @@ void MoveChecker::modelUse(ProgramStateRef State, const MemRegion *Region, if (MK == MK_Dereference && OK.StdKind != SK_SmartPtr) MK = MK_FunCall; - if (!RS || !shouldWarnAbout(OK, MK) - || isInMoveSafeContext(C.getLocationContext())) { + if (!RS || !shouldWarnAbout(OK, MK) || + isInMoveSafeContext(C.getLocationContext())) { // Finalize changes made by the caller. C.addTransition(State); return; @@ -405,25 +395,25 @@ ExplodedNode *MoveChecker::tryToReportBug(const MemRegion *Region, // Creating the error message. llvm::SmallString<128> Str; llvm::raw_svector_ostream OS(Str); - switch(MK) { - case MK_FunCall: - OS << "Method called on moved-from object"; - explainObject(OS, Region, RD, MK); - break; - case MK_Copy: - OS << "Moved-from object"; - explainObject(OS, Region, RD, MK); - OS << " is copied"; - break; - case MK_Move: - OS << "Moved-from object"; - explainObject(OS, Region, RD, MK); - OS << " is moved"; - break; - case MK_Dereference: - OS << "Dereference of null smart pointer"; - explainObject(OS, Region, RD, MK); - break; + switch (MK) { + case MK_FunCall: + OS << "Method called on moved-from object"; + explainObject(OS, Region, RD, MK); + break; + case MK_Copy: + OS << "Moved-from object"; + explainObject(OS, Region, RD, MK); + OS << " is copied"; + break; + case MK_Move: + OS << "Moved-from object"; + explainObject(OS, Region, RD, MK); + OS << " is moved"; + break; + case MK_Dereference: + OS << "Dereference of null smart pointer"; + explainObject(OS, Region, RD, MK); + break; } auto R = std::make_unique( @@ -503,15 +493,15 @@ bool MoveChecker::isMoveSafeMethod(const CXXMethodDecl *MethodDec) const { } // Function call `empty` can be skipped. return (MethodDec && MethodDec->getDeclName().isIdentifier() && - (MethodDec->getName().lower() == "empty" || - MethodDec->getName().lower() == "isempty")); + (MethodDec->getName().lower() == "empty" || + MethodDec->getName().lower() == "isempty")); } bool MoveChecker::isStateResetMethod(const CXXMethodDecl *MethodDec) const { if (!MethodDec) - return false; + return false; if (MethodDec->hasAttr()) - return true; + return true; if (MethodDec->getDeclName().isIdentifier()) { std::string MethodName = MethodDec->getName().lower(); // TODO: Some of these methods (eg., resize) are not always resetting @@ -559,15 +549,15 @@ MoveChecker::classifyObject(const MemRegion *MR, isa(MR->getMemorySpace()); if (!RD || !RD->getDeclContext()->isStdNamespace()) - return { IsLocal, SK_NonStd }; + return {IsLocal, SK_NonStd}; if (belongsTo(RD, StdSmartPtrClasses)) - return { IsLocal, SK_SmartPtr }; + return {IsLocal, SK_SmartPtr}; if (belongsTo(RD, StdSafeClasses)) - return { IsLocal, SK_Safe }; + return {IsLocal, SK_Safe}; - return { IsLocal, SK_Unsafe }; + return {IsLocal, SK_Unsafe}; } void MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, @@ -582,18 +572,18 @@ void MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR, ObjectKind OK = classifyObject(MR, RD); switch (OK.StdKind) { - case SK_NonStd: - case SK_Safe: - break; - case SK_SmartPtr: - if (MK != MK_Dereference) - break; - - // We only care about the type if it's a dereference. - [[fallthrough]]; - case SK_Unsafe: - OS << " of type '" << RD->getQualifiedNameAsString() << "'"; + case SK_NonStd: + case SK_Safe: + break; + case SK_SmartPtr: + if (MK != MK_Dereference) break; + + // We only care about the type if it's a dereference. + [[fallthrough]]; + case SK_Unsafe: + OS << " of type '" << RD->getQualifiedNameAsString() << "'"; + break; }; } @@ -698,8 +688,8 @@ void MoveChecker::checkDeadSymbols(SymbolReaper &SymReaper, ProgramStateRef MoveChecker::checkRegionChanges( ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef RequestedRegions, - ArrayRef InvalidatedRegions, - const LocationContext *LCtx, const CallEvent *Call) const { + ArrayRef InvalidatedRegions, const LocationContext *LCtx, + const CallEvent *Call) const { if (Call) { // Relax invalidation upon function calls: only invalidate parameters // that are passed directly via non-const pointers or non-const references @@ -735,7 +725,7 @@ void MoveChecker::printState(raw_ostream &Out, ProgramStateRef State, if (!RS.isEmpty()) { Out << Sep << "Moved-from objects :" << NL; - for (auto I: RS) { + for (auto I : RS) { I.first->dumpToStream(Out); if (I.second.isMoved()) Out << ": moved"; @@ -751,6 +741,4 @@ void ento::registerMoveChecker(CheckerManager &mgr) { mgr.getAnalyzerOptions().getCheckerStringOption(chk, "WarnOn"), mgr); } -bool ento::shouldRegisterMoveChecker(const CheckerManager &mgr) { - return true; -} +bool ento::shouldRegisterMoveChecker(const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp index 0648084a7d399..cd66a28c58717 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp @@ -14,9 +14,9 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -29,8 +29,7 @@ using namespace clang; using namespace ento; namespace { -class NSAutoreleasePoolChecker - : public Checker { +class NSAutoreleasePoolChecker : public Checker { const BugType BT{this, "Use -drain instead of -release", "API Upgrade (Apple)"}; mutable Selector releaseS; diff --git a/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp index 54870bcb4bb22..f86278d6a20ed 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp @@ -14,9 +14,9 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -37,17 +37,16 @@ static bool IsCFError(QualType T, IdentifierInfo *II); //===----------------------------------------------------------------------===// namespace { -class NSErrorMethodChecker - : public Checker< check::ASTDecl > { +class NSErrorMethodChecker : public Checker> { mutable IdentifierInfo *II = nullptr; public: NSErrorMethodChecker() = default; - void checkASTDecl(const ObjCMethodDecl *D, - AnalysisManager &mgr, BugReporter &BR) const; + void checkASTDecl(const ObjCMethodDecl *D, AnalysisManager &mgr, + BugReporter &BR) const; }; -} +} // namespace void NSErrorMethodChecker::checkASTDecl(const ObjCMethodDecl *D, AnalysisManager &mgr, @@ -61,7 +60,7 @@ void NSErrorMethodChecker::checkASTDecl(const ObjCMethodDecl *D, II = &D->getASTContext().Idents.get("NSError"); bool hasNSError = false; - for (const auto *I : D->parameters()) { + for (const auto *I : D->parameters()) { if (IsNSError(I->getType(), II)) { hasNSError = true; break; @@ -69,11 +68,12 @@ void NSErrorMethodChecker::checkASTDecl(const ObjCMethodDecl *D, } if (hasNSError) { - const char *err = "Method accepting NSError** " + const char *err = + "Method accepting NSError** " "should have a non-void return value to indicate whether or not an " "error occurred"; PathDiagnosticLocation L = - PathDiagnosticLocation::create(D, BR.getSourceManager()); + PathDiagnosticLocation::create(D, BR.getSourceManager()); BR.EmitBasicReport(D, this, "Bad return type when passing NSError**", "Coding conventions (Apple)", err, L); } @@ -84,17 +84,16 @@ void NSErrorMethodChecker::checkASTDecl(const ObjCMethodDecl *D, //===----------------------------------------------------------------------===// namespace { -class CFErrorFunctionChecker - : public Checker< check::ASTDecl > { +class CFErrorFunctionChecker : public Checker> { mutable IdentifierInfo *II; public: CFErrorFunctionChecker() : II(nullptr) {} - void checkASTDecl(const FunctionDecl *D, - AnalysisManager &mgr, BugReporter &BR) const; + void checkASTDecl(const FunctionDecl *D, AnalysisManager &mgr, + BugReporter &BR) const; }; -} +} // namespace static bool hasReservedReturnType(const FunctionDecl *D) { if (isa(D)) @@ -106,8 +105,8 @@ static bool hasReservedReturnType(const FunctionDecl *D) { } void CFErrorFunctionChecker::checkASTDecl(const FunctionDecl *D, - AnalysisManager &mgr, - BugReporter &BR) const { + AnalysisManager &mgr, + BugReporter &BR) const { if (!D->doesThisDeclarationHaveABody()) return; if (!D->getReturnType()->isVoidType()) @@ -119,7 +118,7 @@ void CFErrorFunctionChecker::checkASTDecl(const FunctionDecl *D, II = &D->getASTContext().Idents.get("CFErrorRef"); bool hasCFError = false; - for (auto *I : D->parameters()) { + for (auto *I : D->parameters()) { if (IsCFError(I->getType(), II)) { hasCFError = true; break; @@ -127,11 +126,12 @@ void CFErrorFunctionChecker::checkASTDecl(const FunctionDecl *D, } if (hasCFError) { - const char *err = "Function accepting CFErrorRef* " + const char *err = + "Function accepting CFErrorRef* " "should have a non-void return value to indicate whether or not an " "error occurred"; PathDiagnosticLocation L = - PathDiagnosticLocation::create(D, BR.getSourceManager()); + PathDiagnosticLocation::create(D, BR.getSourceManager()); BR.EmitBasicReport(D, this, "Bad return type when passing CFErrorRef*", "Coding conventions (Apple)", err, L); } @@ -157,15 +157,15 @@ class CFErrorDerefBug : public BugType { "Coding conventions (Apple)") {} }; -} +} // namespace namespace { class NSOrCFErrorDerefChecker - : public Checker< check::Location, - check::Event > { + : public Checker> { mutable IdentifierInfo *NSErrorII, *CFErrorII; mutable std::unique_ptr NSBT; mutable std::unique_ptr CFBT; + public: bool ShouldCheckNSError = false, ShouldCheckCFError = false; CheckerNameRef NSErrorName, CFErrorName; @@ -175,14 +175,13 @@ class NSOrCFErrorDerefChecker CheckerContext &C) const; void checkEvent(ImplicitNullDerefEvent event) const; }; -} +} // namespace typedef llvm::ImmutableMap ErrorOutFlag; REGISTER_TRAIT_WITH_PROGRAMSTATE(NSErrorOut, ErrorOutFlag) REGISTER_TRAIT_WITH_PROGRAMSTATE(CFErrorOut, ErrorOutFlag) -template -static bool hasFlag(SVal val, ProgramStateRef state) { +template static bool hasFlag(SVal val, ProgramStateRef state) { if (SymbolRef sym = val.getAsSymbol()) if (const unsigned *attachedFlags = state->get(sym)) return *attachedFlags; @@ -197,12 +196,12 @@ static void setFlag(ProgramStateRef state, SVal val, CheckerContext &C) { } static QualType parameterTypeFromSVal(SVal val, CheckerContext &C) { - const StackFrameContext * SFC = C.getStackFrame(); + const StackFrameContext *SFC = C.getStackFrame(); if (std::optional X = val.getAs()) { - const MemRegion* R = X->getRegion(); + const MemRegion *R = X->getRegion(); if (const VarRegion *VR = R->getAs()) - if (const StackArgumentsSpaceRegion * - stackReg = dyn_cast(VR->getMemorySpace())) + if (const StackArgumentsSpaceRegion *stackReg = + dyn_cast(VR->getMemorySpace())) if (stackReg->getStackFrame() == SFC) return VR->getValueType(); } @@ -268,19 +267,17 @@ void NSOrCFErrorDerefChecker::checkEvent(ImplicitNullDerefEvent event) const { llvm::raw_svector_ostream os(Buf); os << "Potential null dereference. According to coding standards "; - os << (isNSError - ? "in 'Creating and Returning NSError Objects' the parameter" - : "documented in CoreFoundation/CFError.h the parameter"); + os << (isNSError ? "in 'Creating and Returning NSError Objects' the parameter" + : "documented in CoreFoundation/CFError.h the parameter"); - os << " may be null"; + os << " may be null"; BugType *bug = nullptr; if (isNSError) { if (!NSBT) NSBT.reset(new NSErrorDerefBug(NSErrorName)); bug = NSBT.get(); - } - else { + } else { if (!CFBT) CFBT.reset(new CFErrorDerefBug(CFErrorName)); bug = CFBT.get(); @@ -291,12 +288,12 @@ void NSOrCFErrorDerefChecker::checkEvent(ImplicitNullDerefEvent event) const { static bool IsNSError(QualType T, IdentifierInfo *II) { - const PointerType* PPT = T->getAs(); + const PointerType *PPT = T->getAs(); if (!PPT) return false; - const ObjCObjectPointerType* PT = - PPT->getPointeeType()->getAs(); + const ObjCObjectPointerType *PT = + PPT->getPointeeType()->getAs(); if (!PT) return false; @@ -311,11 +308,13 @@ static bool IsNSError(QualType T, IdentifierInfo *II) { } static bool IsCFError(QualType T, IdentifierInfo *II) { - const PointerType* PPT = T->getAs(); - if (!PPT) return false; + const PointerType *PPT = T->getAs(); + if (!PPT) + return false; - const TypedefType* TT = PPT->getPointeeType()->getAs(); - if (!TT) return false; + const TypedefType *TT = PPT->getPointeeType()->getAs(); + if (!TT) + return false; return TT->getDecl()->getIdentifier() == II; } diff --git a/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp index 17c3cb4e9e04c..97fba082292b1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp @@ -11,9 +11,9 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" #include "clang/Analysis/SelectorExtras.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" @@ -26,16 +26,17 @@ using namespace ento; namespace { -class NoReturnFunctionChecker : public Checker< check::PostCall, - check::PostObjCMessage > { +class NoReturnFunctionChecker + : public Checker { mutable Selector HandleFailureInFunctionSel; mutable Selector HandleFailureInMethodSel; + public: void checkPostCall(const CallEvent &CE, CheckerContext &C) const; void checkPostObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const; }; -} +} // namespace void NoReturnFunctionChecker::checkPostCall(const CallEvent &CE, CheckerContext &C) const { @@ -55,30 +56,32 @@ void NoReturnFunctionChecker::checkPostCall(const CallEvent &CE, // HACK: Some functions are not marked noreturn, and don't return. // Here are a few hardwired ones. If this takes too long, we can // potentially cache these results. - BuildSinks - = llvm::StringSwitch(StringRef(II->getName())) - .Case("exit", true) - .Case("panic", true) - .Case("error", true) - .Case("Assert", true) - // FIXME: This is just a wrapper around throwing an exception. - // Eventually inter-procedural analysis should handle this easily. - .Case("ziperr", true) - .Case("assfail", true) - .Case("db_error", true) - .Case("__assert", true) - .Case("__assert2", true) - // For the purpose of static analysis, we do not care that - // this MSVC function will return if the user decides to continue. - .Case("_wassert", true) - .Case("__assert_rtn", true) - .Case("__assert_fail", true) - .Case("dtrace_assfail", true) - .Case("yy_fatal_error", true) - .Case("_XCAssertionFailureHandler", true) - .Case("_DTAssertionFailureHandler", true) - .Case("_TSAssertionFailureHandler", true) - .Default(false); + BuildSinks = + llvm::StringSwitch(StringRef(II->getName())) + .Case("exit", true) + .Case("panic", true) + .Case("error", true) + .Case("Assert", true) + // FIXME: This is just a wrapper around throwing an exception. + // Eventually inter-procedural analysis should handle this + // easily. + .Case("ziperr", true) + .Case("assfail", true) + .Case("db_error", true) + .Case("__assert", true) + .Case("__assert2", true) + // For the purpose of static analysis, we do not care that + // this MSVC function will return if the user decides to + // continue. + .Case("_wassert", true) + .Case("__assert_rtn", true) + .Case("__assert_fail", true) + .Case("dtrace_assfail", true) + .Case("yy_fatal_error", true) + .Case("_XCAssertionFailureHandler", true) + .Case("_DTAssertionFailureHandler", true) + .Case("_TSAssertionFailureHandler", true) + .Default(false); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index a9002ee7c9661..707b8799345b3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -282,9 +282,8 @@ NonNullParamChecker::genReportNullAttrNonNull(const ExplodedNode *ErrorNode, unsigned IdxOfArg) const { llvm::SmallString<256> SBuf; llvm::raw_svector_ostream OS(SBuf); - OS << "Null pointer passed to " - << IdxOfArg << llvm::getOrdinalSuffix(IdxOfArg) - << " parameter expecting 'nonnull'"; + OS << "Null pointer passed to " << IdxOfArg + << llvm::getOrdinalSuffix(IdxOfArg) << " parameter expecting 'nonnull'"; auto R = std::make_unique(BTAttrNonNull, SBuf, ErrorNode); diff --git a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp index 72c6a869d2251..cf603c6689d32 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp @@ -68,8 +68,8 @@ void NonnullGlobalConstantsChecker::initIdentifierInfo(ASTContext &Ctx) const { /// Add an assumption that const string-like globals are non-null. void NonnullGlobalConstantsChecker::checkLocation(SVal location, bool isLoad, - const Stmt *S, - CheckerContext &C) const { + const Stmt *S, + CheckerContext &C) const { initIdentifierInfo(C.getASTContext()); if (!isLoad || !location.isValid()) return; @@ -140,9 +140,9 @@ bool NonnullGlobalConstantsChecker::isNonnullType(QualType Ty) const { if (auto *T = dyn_cast(Ty)) { return T->getInterfaceDecl() && - T->getInterfaceDecl()->getIdentifier() == NSStringII; + T->getInterfaceDecl()->getIdentifier() == NSStringII; } else if (auto *T = Ty->getAs()) { - IdentifierInfo* II = T->getDecl()->getIdentifier(); + IdentifierInfo *II = T->getDecl()->getIdentifier(); return II == CFStringRefII || II == CFBooleanRefII || II == CFNullRefII; } return false; @@ -152,6 +152,7 @@ void ento::registerNonnullGlobalConstantsChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } -bool ento::shouldRegisterNonnullGlobalConstantsChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterNonnullGlobalConstantsChecker( + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp index 06f1ad00eaf20..5380e67f4f95c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -459,7 +459,7 @@ static bool checkInvariantViolation(ProgramStateRef State, ExplodedNode *N, if (!D) return false; - ArrayRef Params; + ArrayRef Params; if (const auto *BD = dyn_cast(D)) Params = BD->parameters(); else if (const auto *FD = dyn_cast(D)) @@ -699,7 +699,7 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S, // function with a _Nonnull return type: // return (NSString * _Nonnull)0; Nullability RetExprTypeLevelNullability = - getNullabilityAnnotation(lookThroughImplicitCasts(RetExpr)->getType()); + getNullabilityAnnotation(lookThroughImplicitCasts(RetExpr)->getType()); bool NullReturnedFromNonNull = (RequiredNullability == Nullability::Nonnull && Nullness == NullConstraint::IsNull); @@ -714,8 +714,8 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S, SmallString<256> SBuf; llvm::raw_svector_ostream OS(SBuf); OS << (RetExpr->getType()->isObjCObjectPointerType() ? "nil" : "Null"); - OS << " returned from a " << C.getDeclDescription(D) << - " that is expected to return a non-null value"; + OS << " returned from a " << C.getDeclDescription(D) + << " that is expected to return a non-null value"; reportBugIfInvariantHolds(OS.str(), ErrorKind::NilReturnedToNonnull, CK_NullReturnedFromNonnull, N, nullptr, C, RetExpr); @@ -747,8 +747,8 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S, SmallString<256> SBuf; llvm::raw_svector_ostream OS(SBuf); - OS << "Nullable pointer is returned from a " << C.getDeclDescription(D) << - " that is expected to return a non-null value"; + OS << "Nullable pointer is returned from a " << C.getDeclDescription(D) + << " that is expected to return a non-null value"; reportBugIfInvariantHolds(OS.str(), ErrorKind::NullableReturnedToNonnull, CK_NullableReturnedFromNonnull, N, Region, C); @@ -756,9 +756,8 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S, return; } if (RequiredNullability == Nullability::Nullable) { - State = State->set(Region, - NullabilityState(RequiredNullability, - S)); + State = State->set( + Region, NullabilityState(RequiredNullability, S)); C.addTransition(State); } } @@ -1009,9 +1008,8 @@ void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M, } // For similar reasons ignore some methods of Cocoa arrays. StringRef FirstSelectorSlot = M.getSelector().getNameForSlot(0); - if (Name.contains("Array") && - (FirstSelectorSlot == "firstObject" || - FirstSelectorSlot == "lastObject")) { + if (Name.contains("Array") && (FirstSelectorSlot == "firstObject" || + FirstSelectorSlot == "lastObject")) { State = State->set(ReturnRegion, Nullability::Contradicted); C.addTransition(State); @@ -1182,7 +1180,7 @@ void NullabilityChecker::checkPostStmt(const ExplicitCastExpr *CE, /// For a given statement performing a bind, attempt to syntactically /// match the expression resulting in the bound value. -static const Expr * matchValueExprForBind(const Stmt *S) { +static const Expr *matchValueExprForBind(const Stmt *S) { // For `x = e` the value expression is the right-hand side. if (auto *BinOp = dyn_cast(S)) { if (BinOp->getOpcode() == BO_Assign) @@ -1190,7 +1188,7 @@ static const Expr * matchValueExprForBind(const Stmt *S) { } // For `int x = e` the value expression is the initializer. - if (auto *DS = dyn_cast(S)) { + if (auto *DS = dyn_cast(S)) { if (DS->isSingleDecl()) { auto *VD = dyn_cast(DS->getSingleDecl()); if (!VD) @@ -1233,7 +1231,7 @@ static bool isARCNilInitializedLocal(CheckerContext &C, const Stmt *S) { return false; // Sema only zero-initializes locals with ObjCLifetimes. - if(!VD->getType().getQualifiers().hasObjCLifetime()) + if (!VD->getType().getQualifiers().hasObjCLifetime()) return false; const Expr *Init = VD->getInit(); @@ -1280,8 +1278,8 @@ void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S, Nullability ValueExprTypeLevelNullability = Nullability::Unspecified; const Expr *ValueExpr = matchValueExprForBind(S); if (ValueExpr) { - ValueExprTypeLevelNullability = - getNullabilityAnnotation(lookThroughImplicitCasts(ValueExpr)->getType()); + ValueExprTypeLevelNullability = getNullabilityAnnotation( + lookThroughImplicitCasts(ValueExpr)->getType()); } bool NullAssignedToNonNull = (LocNullability == Nullability::Nonnull && @@ -1295,7 +1293,6 @@ void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S, if (!N) return; - const Stmt *ValueStmt = S; if (ValueExpr) ValueStmt = ValueExpr; diff --git a/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp index f217520d8f4a0..201e4af6caa40 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp @@ -25,13 +25,13 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" -#include "clang/Lex/Lexer.h" #include "llvm/ADT/APSInt.h" using namespace clang; @@ -54,23 +54,21 @@ class Callback : public MatchFinder::MatchCallback { AnalysisDeclContext *ADC; public: - Callback(const NumberObjectConversionChecker *C, - BugReporter &BR, AnalysisDeclContext *ADC) + Callback(const NumberObjectConversionChecker *C, BugReporter &BR, + AnalysisDeclContext *ADC) : C(C), BR(BR), ADC(ADC) {} void run(const MatchFinder::MatchResult &Result) override; }; } // end of anonymous namespace void Callback::run(const MatchFinder::MatchResult &Result) { - bool IsPedanticMatch = - (Result.Nodes.getNodeAs("pedantic") != nullptr); + bool IsPedanticMatch = (Result.Nodes.getNodeAs("pedantic") != nullptr); if (IsPedanticMatch && !C->Pedantic) return; ASTContext &ACtx = ADC->getASTContext(); - if (const Expr *CheckIfNull = - Result.Nodes.getNodeAs("check_if_null")) { + if (const Expr *CheckIfNull = Result.Nodes.getNodeAs("check_if_null")) { // Unless the macro indicates that the intended type is clearly not // a pointer type, we should avoid warning on comparing pointers // to zero literals in non-pedantic mode. @@ -107,19 +105,16 @@ void Callback::run(const MatchFinder::MatchResult &Result) { const Expr *ConvertedObjCObject = Result.Nodes.getNodeAs("objc_object"); bool IsCpp = (ConvertedCppObject != nullptr); bool IsObjC = (ConvertedObjCObject != nullptr); - const Expr *Obj = IsObjC ? ConvertedObjCObject - : IsCpp ? ConvertedCppObject - : ConvertedCObject; + const Expr *Obj = IsObjC ? ConvertedObjCObject + : IsCpp ? ConvertedCppObject + : ConvertedCObject; assert(Obj); - bool IsComparison = - (Result.Nodes.getNodeAs("comparison") != nullptr); + bool IsComparison = (Result.Nodes.getNodeAs("comparison") != nullptr); - bool IsOSNumber = - (Result.Nodes.getNodeAs("osnumber") != nullptr); + bool IsOSNumber = (Result.Nodes.getNodeAs("osnumber") != nullptr); - bool IsInteger = - (Result.Nodes.getNodeAs("int_type") != nullptr); + bool IsInteger = (Result.Nodes.getNodeAs("int_type") != nullptr); bool IsObjCBool = (Result.Nodes.getNodeAs("objc_bool_type") != nullptr); bool IsCppBool = @@ -146,9 +141,9 @@ void Callback::run(const MatchFinder::MatchResult &Result) { OS << "a pointer value of type '" << ObjT << "' to a "; std::string EuphemismForPlain = "primitive"; - std::string SuggestedApi = IsObjC ? (IsInteger ? "" : "-boolValue") - : IsCpp ? (IsOSNumber ? "" : "getValue()") - : "CFNumberGetValue()"; + std::string SuggestedApi = IsObjC ? (IsInteger ? "" : "-boolValue") + : IsCpp ? (IsOSNumber ? "" : "getValue()") + : "CFNumberGetValue()"; if (SuggestedApi.empty()) { // A generic message if we're not sure what API should be called. // FIXME: Pattern-match the integer type to make a better guess? @@ -170,10 +165,12 @@ void Callback::run(const MatchFinder::MatchResult &Result) { else // Branch condition? OS << EuphemismForPlain << " boolean value"; - if (IsPedanticMatch) OS << "; instead, either compare the pointer to " - << (IsObjC ? "nil" : IsCpp ? "nullptr" : "NULL") << " or "; + << (IsObjC ? "nil" + : IsCpp ? "nullptr" + : "NULL") + << " or "; else OS << "; did you mean to "; @@ -203,38 +200,28 @@ void NumberObjectConversionChecker::checkASTCodeBody(const Decl *D, .bind("c_object"))); // Currently this matches XNU kernel number-object pointers. - auto CppSuspiciousNumberObjectExprM = - expr(ignoringParenImpCasts( - expr(hasType(hasCanonicalType( - pointerType(pointee(hasCanonicalType( - recordType(hasDeclaration( - anyOf( - cxxRecordDecl(hasName("OSBoolean")), - cxxRecordDecl(hasName("OSNumber")) - .bind("osnumber")))))))))) + auto CppSuspiciousNumberObjectExprM = expr(ignoringParenImpCasts( + expr(hasType(hasCanonicalType(pointerType( + pointee(hasCanonicalType(recordType(hasDeclaration(anyOf( + cxxRecordDecl(hasName("OSBoolean")), + cxxRecordDecl(hasName("OSNumber")).bind("osnumber")))))))))) .bind("cpp_object"))); // Currently this matches NeXTSTEP number objects. - auto ObjCSuspiciousNumberObjectExprM = - expr(ignoringParenImpCasts( - expr(hasType(hasCanonicalType( - objcObjectPointerType(pointee( - qualType(hasCanonicalType( - qualType(hasDeclaration( - objcInterfaceDecl(hasName("NSNumber"))))))))))) + auto ObjCSuspiciousNumberObjectExprM = expr(ignoringParenImpCasts( + expr(hasType(hasCanonicalType(objcObjectPointerType( + pointee(qualType(hasCanonicalType(qualType(hasDeclaration( + objcInterfaceDecl(hasName("NSNumber"))))))))))) .bind("objc_object"))); - auto SuspiciousNumberObjectExprM = anyOf( - CSuspiciousNumberObjectExprM, - CppSuspiciousNumberObjectExprM, - ObjCSuspiciousNumberObjectExprM); + auto SuspiciousNumberObjectExprM = + anyOf(CSuspiciousNumberObjectExprM, CppSuspiciousNumberObjectExprM, + ObjCSuspiciousNumberObjectExprM); // Useful for predicates like "Unless we've seen the same object elsewhere". auto AnotherSuspiciousNumberObjectExprM = - expr(anyOf( - equalsBoundNode("c_object"), - equalsBoundNode("objc_object"), - equalsBoundNode("cpp_object"))); + expr(anyOf(equalsBoundNode("c_object"), equalsBoundNode("objc_object"), + equalsBoundNode("cpp_object"))); // The .bind here is in order to compose the error message more accurately. auto ObjCSuspiciousScalarBooleanTypeM = @@ -256,59 +243,54 @@ void NumberObjectConversionChecker::checkASTCodeBody(const Decl *D, typedefDecl(matchesName("^::u?intptr_t$")))))))) .bind("int_type"); - auto SuspiciousScalarTypeM = - qualType(anyOf(SuspiciousScalarBooleanTypeM, - SuspiciousScalarNumberTypeM)); + auto SuspiciousScalarTypeM = qualType( + anyOf(SuspiciousScalarBooleanTypeM, SuspiciousScalarNumberTypeM)); auto SuspiciousScalarExprM = expr(ignoringParenImpCasts(expr(hasType(SuspiciousScalarTypeM)))); auto ConversionThroughAssignmentM = - binaryOperator(allOf(hasOperatorName("="), - hasLHS(SuspiciousScalarExprM), + binaryOperator(allOf(hasOperatorName("="), hasLHS(SuspiciousScalarExprM), hasRHS(SuspiciousNumberObjectExprM))); auto ConversionThroughBranchingM = - ifStmt(allOf( - hasCondition(SuspiciousNumberObjectExprM), - unless(hasConditionVariableStatement(declStmt()) - ))).bind("pedantic"); + ifStmt(allOf(hasCondition(SuspiciousNumberObjectExprM), + unless(hasConditionVariableStatement(declStmt())))) + .bind("pedantic"); - auto ConversionThroughCallM = - callExpr(hasAnyArgument(allOf(hasType(SuspiciousScalarTypeM), - ignoringParenImpCasts( - SuspiciousNumberObjectExprM)))); + auto ConversionThroughCallM = callExpr(hasAnyArgument( + allOf(hasType(SuspiciousScalarTypeM), + ignoringParenImpCasts(SuspiciousNumberObjectExprM)))); // We bind "check_if_null" to modify the warning message // in case it was intended to compare a pointer to 0 with a relatively-ok // construct "x == 0" or "x != 0". auto ConversionThroughEquivalenceM = - binaryOperator(allOf(anyOf(hasOperatorName("=="), hasOperatorName("!=")), - hasEitherOperand(SuspiciousNumberObjectExprM), - hasEitherOperand(SuspiciousScalarExprM - .bind("check_if_null")))) - .bind("comparison"); + binaryOperator( + allOf(anyOf(hasOperatorName("=="), hasOperatorName("!=")), + hasEitherOperand(SuspiciousNumberObjectExprM), + hasEitherOperand(SuspiciousScalarExprM.bind("check_if_null")))) + .bind("comparison"); auto ConversionThroughComparisonM = binaryOperator(allOf(anyOf(hasOperatorName(">="), hasOperatorName(">"), hasOperatorName("<="), hasOperatorName("<")), hasEitherOperand(SuspiciousNumberObjectExprM), hasEitherOperand(SuspiciousScalarExprM))) - .bind("comparison"); + .bind("comparison"); auto ConversionThroughConditionalOperatorM = - conditionalOperator(allOf( - hasCondition(SuspiciousNumberObjectExprM), - unless(hasTrueExpression( - hasDescendant(AnotherSuspiciousNumberObjectExprM))), - unless(hasFalseExpression( - hasDescendant(AnotherSuspiciousNumberObjectExprM))))) - .bind("pedantic"); + conditionalOperator(allOf(hasCondition(SuspiciousNumberObjectExprM), + unless(hasTrueExpression(hasDescendant( + AnotherSuspiciousNumberObjectExprM))), + unless(hasFalseExpression(hasDescendant( + AnotherSuspiciousNumberObjectExprM))))) + .bind("pedantic"); auto ConversionThroughExclamationMarkM = - unaryOperator(allOf(hasOperatorName("!"), - has(expr(SuspiciousNumberObjectExprM)))) - .bind("pedantic"); + unaryOperator( + allOf(hasOperatorName("!"), has(expr(SuspiciousNumberObjectExprM)))) + .bind("pedantic"); auto ConversionThroughExplicitBooleanCastM = explicitCastExpr(allOf(hasType(SuspiciousScalarBooleanTypeM), @@ -318,21 +300,20 @@ void NumberObjectConversionChecker::checkASTCodeBody(const Decl *D, explicitCastExpr(allOf(hasType(SuspiciousScalarNumberTypeM), has(expr(SuspiciousNumberObjectExprM)))); - auto ConversionThroughInitializerM = - declStmt(hasSingleDecl( - varDecl(hasType(SuspiciousScalarTypeM), - hasInitializer(SuspiciousNumberObjectExprM)))); - - auto FinalM = stmt(anyOf(ConversionThroughAssignmentM, - ConversionThroughBranchingM, - ConversionThroughCallM, - ConversionThroughComparisonM, - ConversionThroughConditionalOperatorM, - ConversionThroughEquivalenceM, - ConversionThroughExclamationMarkM, - ConversionThroughExplicitBooleanCastM, - ConversionThroughExplicitNumberCastM, - ConversionThroughInitializerM)).bind("conv"); + auto ConversionThroughInitializerM = declStmt( + hasSingleDecl(varDecl(hasType(SuspiciousScalarTypeM), + hasInitializer(SuspiciousNumberObjectExprM)))); + + auto FinalM = + stmt(anyOf(ConversionThroughAssignmentM, ConversionThroughBranchingM, + ConversionThroughCallM, ConversionThroughComparisonM, + ConversionThroughConditionalOperatorM, + ConversionThroughEquivalenceM, + ConversionThroughExclamationMarkM, + ConversionThroughExplicitBooleanCastM, + ConversionThroughExplicitNumberCastM, + ConversionThroughInitializerM)) + .bind("conv"); MatchFinder F; Callback CB(this, BR, AM.getAnalysisDeclContext(D)); @@ -348,6 +329,7 @@ void ento::registerNumberObjectConversionChecker(CheckerManager &Mgr) { Mgr.getAnalyzerOptions().getCheckerBooleanOption(Chk, "Pedantic"); } -bool ento::shouldRegisterNumberObjectConversionChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterNumberObjectConversionChecker( + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp b/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp index 0a8379d9ab99d..6efaea73afbe7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp @@ -11,8 +11,8 @@ // as an explicit static or dynamic cast should be used instead. //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -48,8 +48,7 @@ AST_MATCHER_P(StringLiteral, mentionsBoundType, std::string, BindingID) { } // end namespace ast_matchers } // end namespace clang -static void emitDiagnostics(const BoundNodes &Nodes, - BugReporter &BR, +static void emitDiagnostics(const BoundNodes &Nodes, BugReporter &BR, AnalysisDeclContext *ADC, const OSObjectCStyleCastChecker *Checker) { const auto *CE = Nodes.getNodeAs(WarnAtNode); @@ -63,14 +62,11 @@ static void emitDiagnostics(const BoundNodes &Nodes, << RD->getNameAsString() << "', or 'OSDynamicCast' followed by " << "a null check if unsure", - BR.EmitBasicReport( - ADC->getDecl(), - Checker, - /*Name=*/"OSObject C-Style Cast", - categories::SecurityError, - OS.str(), - PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), ADC), - CE->getSourceRange()); + BR.EmitBasicReport( + ADC->getDecl(), Checker, + /*Name=*/"OSObject C-Style Cast", categories::SecurityError, OS.str(), + PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), ADC), + CE->getSourceRange()); } static decltype(auto) hasTypePointingTo(DeclarationMatcher DeclM) { diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp index 552c222a251a6..83b0a31dd1dd9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/StmtObjC.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -24,7 +24,7 @@ using namespace ento; namespace { class ObjCAtSyncChecker - : public Checker< check::PreStmt > { + : public Checker> { const BugType BT_null{this, "Nil value used as mutex for @synchronized() " "(no synchronization will occur)"}; const BugType BT_undef{this, "Uninitialized value used as mutex " diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp index 514f53b4804f5..03e1068bc2119 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp @@ -1,4 +1,5 @@ -//===- ObjCAutoreleaseWriteChecker.cpp ----------------------------*- C++ -*-==// +//===- ObjCAutoreleaseWriteChecker.cpp ----------------------------*- C++ +//-*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -26,8 +27,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" @@ -49,54 +50,44 @@ const char *IsARPBind = "isautoreleasepoolbind"; class ObjCAutoreleaseWriteChecker : public Checker { public: - void checkASTCodeBody(const Decl *D, - AnalysisManager &AM, + void checkASTCodeBody(const Decl *D, AnalysisManager &AM, BugReporter &BR) const; + private: std::vector SelectorsWithAutoreleasingPool = { // Common to NSArray, NSSet, NSOrderedSet - "enumerateObjectsUsingBlock:", - "enumerateObjectsWithOptions:usingBlock:", + "enumerateObjectsUsingBlock:", "enumerateObjectsWithOptions:usingBlock:", // Common to NSArray and NSOrderedSet "enumerateObjectsAtIndexes:options:usingBlock:", "indexOfObjectAtIndexes:options:passingTest:", "indexesOfObjectsAtIndexes:options:passingTest:", - "indexOfObjectPassingTest:", - "indexOfObjectWithOptions:passingTest:", + "indexOfObjectPassingTest:", "indexOfObjectWithOptions:passingTest:", "indexesOfObjectsPassingTest:", "indexesOfObjectsWithOptions:passingTest:", // NSDictionary "enumerateKeysAndObjectsUsingBlock:", "enumerateKeysAndObjectsWithOptions:usingBlock:", - "keysOfEntriesPassingTest:", - "keysOfEntriesWithOptions:passingTest:", + "keysOfEntriesPassingTest:", "keysOfEntriesWithOptions:passingTest:", // NSSet - "objectsPassingTest:", - "objectsWithOptions:passingTest:", + "objectsPassingTest:", "objectsWithOptions:passingTest:", "enumerateIndexPathsWithOptions:usingBlock:", // NSIndexSet - "enumerateIndexesWithOptions:usingBlock:", - "enumerateIndexesUsingBlock:", + "enumerateIndexesWithOptions:usingBlock:", "enumerateIndexesUsingBlock:", "enumerateIndexesInRange:options:usingBlock:", - "enumerateRangesUsingBlock:", - "enumerateRangesWithOptions:usingBlock:", - "enumerateRangesInRange:options:usingBlock:", - "indexPassingTest:", - "indexesPassingTest:", - "indexWithOptions:passingTest:", - "indexesWithOptions:passingTest:", - "indexInRange:options:passingTest:", - "indexesInRange:options:passingTest:" - }; + "enumerateRangesUsingBlock:", "enumerateRangesWithOptions:usingBlock:", + "enumerateRangesInRange:options:usingBlock:", "indexPassingTest:", + "indexesPassingTest:", "indexWithOptions:passingTest:", + "indexesWithOptions:passingTest:", "indexInRange:options:passingTest:", + "indexesInRange:options:passingTest:"}; std::vector FunctionsWithAutoreleasingPool = { "dispatch_async", "dispatch_group_async", "dispatch_barrier_async"}; }; -} +} // namespace static inline std::vector toRefs(const std::vector &V) { @@ -168,8 +159,8 @@ static void emitDiagnostics(BoundNodes &Match, const Decl *D, BugReporter &BR, } void ObjCAutoreleaseWriteChecker::checkASTCodeBody(const Decl *D, - AnalysisManager &AM, - BugReporter &BR) const { + AnalysisManager &AM, + BugReporter &BR) const { auto DoublePointerParamM = parmVarDecl(hasType(hasCanonicalType(pointerType( @@ -180,35 +171,29 @@ void ObjCAutoreleaseWriteChecker::checkASTCodeBody(const Decl *D, declRefExpr(to(parmVarDecl(DoublePointerParamM))).bind(CapturedBind); // Write into a binded object, e.g. *ParamBind = X. - auto WritesIntoM = binaryOperator( - hasLHS(unaryOperator( - hasOperatorName("*"), - hasUnaryOperand( - ignoringParenImpCasts(ReferencedParamM)) - )), - hasOperatorName("=") - ).bind(ProblematicWriteBind); - - auto ArgumentCaptureM = hasAnyArgument( - ignoringParenImpCasts(ReferencedParamM)); - auto CapturedInParamM = stmt(anyOf( - callExpr(ArgumentCaptureM), - objcMessageExpr(ArgumentCaptureM))); + auto WritesIntoM = + binaryOperator(hasLHS(unaryOperator(hasOperatorName("*"), + hasUnaryOperand(ignoringParenImpCasts( + ReferencedParamM)))), + hasOperatorName("=")) + .bind(ProblematicWriteBind); + + auto ArgumentCaptureM = + hasAnyArgument(ignoringParenImpCasts(ReferencedParamM)); + auto CapturedInParamM = stmt( + anyOf(callExpr(ArgumentCaptureM), objcMessageExpr(ArgumentCaptureM))); // WritesIntoM happens inside a block passed as an argument. - auto WritesOrCapturesInBlockM = hasAnyArgument(allOf( - hasType(hasCanonicalType(blockPointerType())), - forEachDescendant( - stmt(anyOf(WritesIntoM, CapturedInParamM)) - ))); - - auto BlockPassedToMarkedFuncM = stmt(anyOf( - callExpr(allOf( - callsNames(FunctionsWithAutoreleasingPool), WritesOrCapturesInBlockM)), - objcMessageExpr(allOf( - hasAnySelector(toRefs(SelectorsWithAutoreleasingPool)), - WritesOrCapturesInBlockM)) - )); + auto WritesOrCapturesInBlockM = hasAnyArgument( + allOf(hasType(hasCanonicalType(blockPointerType())), + forEachDescendant(stmt(anyOf(WritesIntoM, CapturedInParamM))))); + + auto BlockPassedToMarkedFuncM = + stmt(anyOf(callExpr(allOf(callsNames(FunctionsWithAutoreleasingPool), + WritesOrCapturesInBlockM)), + objcMessageExpr(allOf( + hasAnySelector(toRefs(SelectorsWithAutoreleasingPool)), + WritesOrCapturesInBlockM)))); // WritesIntoM happens inside an explicit @autoreleasepool. auto WritesOrCapturesInPoolM = @@ -221,10 +206,10 @@ void ObjCAutoreleaseWriteChecker::checkASTCodeBody(const Decl *D, anyOf(forEachDescendant(BlockPassedToMarkedFuncM), forEachDescendant(WritesOrCapturesInPoolM))); - auto MatcherM = decl(anyOf( - objcMethodDecl(HasParamAndWritesInMarkedFuncM).bind(IsMethodBind), - functionDecl(HasParamAndWritesInMarkedFuncM), - blockDecl(HasParamAndWritesInMarkedFuncM))); + auto MatcherM = decl( + anyOf(objcMethodDecl(HasParamAndWritesInMarkedFuncM).bind(IsMethodBind), + functionDecl(HasParamAndWritesInMarkedFuncM), + blockDecl(HasParamAndWritesInMarkedFuncM))); auto Matches = match(MatcherM, *D, AM.getASTContext()); for (BoundNodes Match : Matches) diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp index 2b008d1c775a2..c30a1c20bbc99 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp @@ -10,10 +10,10 @@ // 'CFDictionary', 'CFSet' APIs. // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/StmtVisitor.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Basic/TargetInfo.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -27,7 +27,7 @@ namespace { class WalkAST : public StmtVisitor { BugReporter &BR; const CheckerBase *Checker; - AnalysisDeclContext* AC; + AnalysisDeclContext *AC; ASTContext &ASTC; uint64_t PtrWidth; @@ -87,7 +87,7 @@ static StringRef getCalleeName(CallExpr *CE) { return StringRef(); IdentifierInfo *II = FD->getIdentifier(); - if (!II) // if no identifier, not a simple C function + if (!II) // if no identifier, not a simple C function return StringRef(); return II->getName(); @@ -107,7 +107,7 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { ArgNum = 1; Arg = CE->getArg(ArgNum)->IgnoreParenCasts(); if (hasPointerToPointerSizedType(Arg)) - return; + return; } else if (Name.equals("CFDictionaryCreate")) { if (CE->getNumArgs() != 6) return; @@ -129,7 +129,7 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { SmallString<64> BufName; llvm::raw_svector_ostream OsName(BufName); - OsName << " Invalid use of '" << Name << "'" ; + OsName << " Invalid use of '" << Name << "'"; SmallString<256> Buf; llvm::raw_svector_ostream Os(Buf); @@ -159,14 +159,13 @@ void WalkAST::VisitChildren(Stmt *S) { namespace { class ObjCContainersASTChecker : public Checker { public: - - void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr, + void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr, BugReporter &BR) const { WalkAST walker(BR, this, Mgr.getAnalysisDeclContext(D)); walker.Visit(D->getBody()); } }; -} +} // namespace void ento::registerObjCContainersASTChecker(CheckerManager &mgr) { mgr.registerChecker(); diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp index 28e88245ca95a..16595ade24c7f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp @@ -15,8 +15,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -27,9 +27,9 @@ using namespace clang; using namespace ento; namespace { -class ObjCContainersChecker : public Checker< check::PreStmt, - check::PostStmt, - check::PointerEscape> { +class ObjCContainersChecker + : public Checker, check::PostStmt, + check::PointerEscape> { const BugType BT{this, "CFArray API", categories::CoreFoundationObjectiveC}; inline SymbolRef getArraySym(const Expr *E, CheckerContext &C) const { @@ -49,8 +49,8 @@ class ObjCContainersChecker : public Checker< check::PreStmt, const CallEvent *Call, PointerEscapeKind Kind) const; - void printState(raw_ostream &OS, ProgramStateRef State, - const char *NL, const char *Sep) const override; + void printState(raw_ostream &OS, ProgramStateRef State, const char *NL, + const char *Sep) const override; }; } // end anonymous namespace @@ -148,11 +148,9 @@ void ObjCContainersChecker::checkPreStmt(const CallExpr *CE, } } -ProgramStateRef -ObjCContainersChecker::checkPointerEscape(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind) const { +ProgramStateRef ObjCContainersChecker::checkPointerEscape( + ProgramStateRef State, const InvalidatedSymbols &Escaped, + const CallEvent *Call, PointerEscapeKind Kind) const { for (const auto &Sym : Escaped) { // When a symbol for a mutable array escapes, we can't reason precisely // about its size any more -- so remove it from the map. diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp index 598b368e74d47..20c2aede0baf8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp @@ -12,12 +12,12 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/Analysis/PathDiagnostic.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Analysis/PathDiagnostic.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -61,13 +61,14 @@ class FindSuperCallVisitor : public RecursiveASTVisitor { // ObjCSuperCallChecker //===----------------------------------------------------------------------===// -class ObjCSuperCallChecker : public Checker< - check::ASTDecl > { +class ObjCSuperCallChecker + : public Checker> { public: ObjCSuperCallChecker() = default; void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager &Mgr, BugReporter &BR) const; + private: bool isCheckableClass(const ObjCImplementationDecl *D, StringRef &SuperclassName) const; @@ -78,7 +79,7 @@ class ObjCSuperCallChecker : public Checker< mutable bool IsInitialized = false; }; -} +} // namespace /// Determine whether the given class has a superclass that we want /// to check. The name of the found superclass is stored in SuperclassName. @@ -88,8 +89,7 @@ class ObjCSuperCallChecker : public Checker< bool ObjCSuperCallChecker::isCheckableClass(const ObjCImplementationDecl *D, StringRef &SuperclassName) const { const ObjCInterfaceDecl *ID = D->getClassInterface()->getSuperClass(); - for ( ; ID ; ID = ID->getSuperClass()) - { + for (; ID; ID = ID->getSuperClass()) { SuperclassName = ID->getIdentifier()->getName(); if (SelectorsForClass.count(SuperclassName)) return true; @@ -118,42 +118,39 @@ void ObjCSuperCallChecker::initializeSelectors(ASTContext &Ctx) const { { // Initialize selectors for: UIViewController const SelectorDescriptor Selectors[] = { - { "addChildViewController", 1 }, - { "viewDidAppear", 1 }, - { "viewDidDisappear", 1 }, - { "viewWillAppear", 1 }, - { "viewWillDisappear", 1 }, - { "removeFromParentViewController", 0 }, - { "didReceiveMemoryWarning", 0 }, - { "viewDidUnload", 0 }, - { "viewDidLoad", 0 }, - { "viewWillUnload", 0 }, - { "updateViewConstraints", 0 }, - { "encodeRestorableStateWithCoder", 1 }, - { "restoreStateWithCoder", 1 }}; + {"addChildViewController", 1}, + {"viewDidAppear", 1}, + {"viewDidDisappear", 1}, + {"viewWillAppear", 1}, + {"viewWillDisappear", 1}, + {"removeFromParentViewController", 0}, + {"didReceiveMemoryWarning", 0}, + {"viewDidUnload", 0}, + {"viewDidLoad", 0}, + {"viewWillUnload", 0}, + {"updateViewConstraints", 0}, + {"encodeRestorableStateWithCoder", 1}, + {"restoreStateWithCoder", 1}}; fillSelectors(Ctx, Selectors, "UIViewController"); } { // Initialize selectors for: UIResponder - const SelectorDescriptor Selectors[] = { - { "resignFirstResponder", 0 }}; + const SelectorDescriptor Selectors[] = {{"resignFirstResponder", 0}}; fillSelectors(Ctx, Selectors, "UIResponder"); } { // Initialize selectors for: NSResponder const SelectorDescriptor Selectors[] = { - { "encodeRestorableStateWithCoder", 1 }, - { "restoreStateWithCoder", 1 }}; + {"encodeRestorableStateWithCoder", 1}, {"restoreStateWithCoder", 1}}; fillSelectors(Ctx, Selectors, "NSResponder"); } { // Initialize selectors for: NSDocument const SelectorDescriptor Selectors[] = { - { "encodeRestorableStateWithCoder", 1 }, - { "restoreStateWithCoder", 1 }}; + {"encodeRestorableStateWithCoder", 1}, {"restoreStateWithCoder", 1}}; fillSelectors(Ctx, Selectors, "NSDocument"); } @@ -175,7 +172,6 @@ void ObjCSuperCallChecker::checkASTDecl(const ObjCImplementationDecl *D, if (!isCheckableClass(D, SuperclassName)) return; - // Iterate over all instance methods. for (auto *MD : D->instance_methods()) { Selector S = MD->getSelector(); @@ -184,25 +180,23 @@ void ObjCSuperCallChecker::checkASTDecl(const ObjCImplementationDecl *D, continue; // Check if the method calls its superclass implementation. - if (MD->getBody()) - { + if (MD->getBody()) { FindSuperCallVisitor Visitor(S); Visitor.TraverseDecl(MD); // It doesn't call super, emit a diagnostic. if (!Visitor.DoesCallSuper) { - PathDiagnosticLocation DLoc = - PathDiagnosticLocation::createEnd(MD->getBody(), - BR.getSourceManager(), - Mgr.getAnalysisDeclContext(D)); + PathDiagnosticLocation DLoc = PathDiagnosticLocation::createEnd( + MD->getBody(), BR.getSourceManager(), + Mgr.getAnalysisDeclContext(D)); const char *Name = "Missing call to superclass"; SmallString<320> Buf; llvm::raw_svector_ostream os(Buf); - os << "The '" << S.getAsString() - << "' instance method in " << SuperclassName.str() << " subclass '" - << *D << "' is missing a [super " << S.getAsString() << "] call"; + os << "The '" << S.getAsString() << "' instance method in " + << SuperclassName.str() << " subclass '" << *D + << "' is missing a [super " << S.getAsString() << "] call"; BR.EmitBasicReport(MD, this, Name, categories::CoreFoundationObjectiveC, os.str(), DLoc); @@ -211,7 +205,6 @@ void ObjCSuperCallChecker::checkASTDecl(const ObjCImplementationDecl *D, } } - //===----------------------------------------------------------------------===// // Check registration. //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp index 08ad6877cbe6b..f07b03ae95dae 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp @@ -22,8 +22,7 @@ using namespace clang; using namespace ento; namespace { -class ObjCPropertyChecker - : public Checker> { +class ObjCPropertyChecker : public Checker> { void checkCopyMutable(const ObjCPropertyDecl *D, BugReporter &BR) const; public: @@ -47,9 +46,10 @@ void ObjCPropertyChecker::checkCopyMutable(const ObjCPropertyDecl *D, if (!T->isObjCObjectPointerType()) return; - const std::string &PropTypeName(T->getPointeeType().getCanonicalType() - .getUnqualifiedType() - .getAsString()); + const std::string &PropTypeName(T->getPointeeType() + .getCanonicalType() + .getUnqualifiedType() + .getAsString()); if (!StringRef(PropTypeName).starts_with("NSMutable")) return; diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp index 217c46451f80f..9eaa3ceadc257 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp @@ -35,8 +35,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -54,13 +54,10 @@ static bool isInitMessage(const ObjCMethodCall &Msg); static bool isSelfVar(SVal location, CheckerContext &C); namespace { -class ObjCSelfInitChecker : public Checker< check::PostObjCMessage, - check::PostStmt, - check::PreStmt, - check::PreCall, - check::PostCall, - check::Location, - check::Bind > { +class ObjCSelfInitChecker + : public Checker, + check::PreStmt, check::PreCall, + check::PostCall, check::Location, check::Bind> { const BugType BT{this, "Missing \"self = [(super or self) init...]\"", categories::CoreFoundationObjectiveC}; @@ -78,8 +75,8 @@ class ObjCSelfInitChecker : public Checker< check::PostObjCMessage, void checkPreCall(const CallEvent &CE, CheckerContext &C) const; void checkPostCall(const CallEvent &CE, CheckerContext &C) const; - void printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep) const override; + void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, + const char *Sep) const override; }; } // end anonymous namespace @@ -88,7 +85,7 @@ enum SelfFlagEnum { /// No flag set. SelfFlag_None = 0x0, /// Value came from 'self'. - SelfFlag_Self = 0x1, + SelfFlag_Self = 0x1, /// Value came from the result of an initializer (e.g. [super init]). SelfFlag_InitRes = 0x2 }; @@ -114,8 +111,8 @@ static SelfFlagEnum getSelfFlags(SVal val, CheckerContext &C) { return getSelfFlags(val, C.getState()); } -static void addSelfFlag(ProgramStateRef state, SVal val, - SelfFlagEnum flag, CheckerContext &C) { +static void addSelfFlag(ProgramStateRef state, SVal val, SelfFlagEnum flag, + CheckerContext &C) { // We tag the symbol that the SVal wraps. if (SymbolRef sym = val.getAsSymbol()) { state = state->set(sym, @@ -167,8 +164,8 @@ void ObjCSelfInitChecker::checkPostObjCMessage(const ObjCMethodCall &Msg, // then it is properly initialized. // FIXME: A callback should disable checkers at the start of functions. - if (!shouldRunOnFunctionOrMethod(dyn_cast( - C.getCurrentAnalysisDeclContext()->getDecl()))) + if (!shouldRunOnFunctionOrMethod( + dyn_cast(C.getCurrentAnalysisDeclContext()->getDecl()))) return; if (isInitMessage(Msg)) { @@ -194,8 +191,8 @@ void ObjCSelfInitChecker::checkPostObjCMessage(const ObjCMethodCall &Msg, void ObjCSelfInitChecker::checkPostStmt(const ObjCIvarRefExpr *E, CheckerContext &C) const { // FIXME: A callback should disable checkers at the start of functions. - if (!shouldRunOnFunctionOrMethod(dyn_cast( - C.getCurrentAnalysisDeclContext()->getDecl()))) + if (!shouldRunOnFunctionOrMethod( + dyn_cast(C.getCurrentAnalysisDeclContext()->getDecl()))) return; checkForInvalidSelf( @@ -207,8 +204,8 @@ void ObjCSelfInitChecker::checkPostStmt(const ObjCIvarRefExpr *E, void ObjCSelfInitChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const { // FIXME: A callback should disable checkers at the start of functions. - if (!shouldRunOnFunctionOrMethod(dyn_cast( - C.getCurrentAnalysisDeclContext()->getDecl()))) + if (!shouldRunOnFunctionOrMethod( + dyn_cast(C.getCurrentAnalysisDeclContext()->getDecl()))) return; checkForInvalidSelf(S->getRetValue(), C, @@ -235,8 +232,8 @@ void ObjCSelfInitChecker::checkPreStmt(const ReturnStmt *S, void ObjCSelfInitChecker::checkPreCall(const CallEvent &CE, CheckerContext &C) const { // FIXME: A callback should disable checkers at the start of functions. - if (!shouldRunOnFunctionOrMethod(dyn_cast( - C.getCurrentAnalysisDeclContext()->getDecl()))) + if (!shouldRunOnFunctionOrMethod( + dyn_cast(C.getCurrentAnalysisDeclContext()->getDecl()))) return; ProgramStateRef state = C.getState(); @@ -264,8 +261,8 @@ void ObjCSelfInitChecker::checkPreCall(const CallEvent &CE, void ObjCSelfInitChecker::checkPostCall(const CallEvent &CE, CheckerContext &C) const { // FIXME: A callback should disable checkers at the start of functions. - if (!shouldRunOnFunctionOrMethod(dyn_cast( - C.getCurrentAnalysisDeclContext()->getDecl()))) + if (!shouldRunOnFunctionOrMethod( + dyn_cast(C.getCurrentAnalysisDeclContext()->getDecl()))) return; ProgramStateRef state = C.getState(); @@ -299,8 +296,8 @@ void ObjCSelfInitChecker::checkPostCall(const CallEvent &CE, void ObjCSelfInitChecker::checkLocation(SVal location, bool isLoad, const Stmt *S, CheckerContext &C) const { - if (!shouldRunOnFunctionOrMethod(dyn_cast( - C.getCurrentAnalysisDeclContext()->getDecl()))) + if (!shouldRunOnFunctionOrMethod( + dyn_cast(C.getCurrentAnalysisDeclContext()->getDecl()))) return; // Tag the result of a load from 'self' so that we can easily know that the @@ -311,7 +308,6 @@ void ObjCSelfInitChecker::checkLocation(SVal location, bool isLoad, C); } - void ObjCSelfInitChecker::checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const { // Allow assignment of anything to self. Self is a local variable in the @@ -319,10 +315,8 @@ void ObjCSelfInitChecker::checkBind(SVal loc, SVal val, const Stmt *S, // static functions/method calls. After self is assigned something we cannot // reason about, stop enforcing the rules. // (Only continue checking if the assigned value should be treated as self.) - if ((isSelfVar(loc, C)) && - !hasSelfFlag(val, SelfFlag_InitRes, C) && - !hasSelfFlag(val, SelfFlag_Self, C) && - !isSelfVar(val, C)) { + if ((isSelfVar(loc, C)) && !hasSelfFlag(val, SelfFlag_InitRes, C) && + !hasSelfFlag(val, SelfFlag_Self, C) && !isSelfVar(val, C)) { // Stop tracking the checker-specific state in the state. ProgramStateRef State = C.getState(); @@ -378,7 +372,6 @@ void ObjCSelfInitChecker::printState(raw_ostream &Out, ProgramStateRef State, } } - // FIXME: A callback should disable checkers at the start of functions. static bool shouldRunOnFunctionOrMethod(const NamedDecl *ND) { if (!ND) @@ -393,9 +386,9 @@ static bool shouldRunOnFunctionOrMethod(const NamedDecl *ND) { // self = [super init] applies only to NSObject subclasses. // For instance, NSProxy doesn't implement -init. ASTContext &Ctx = MD->getASTContext(); - IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject"); + IdentifierInfo *NSObjectII = &Ctx.Idents.get("NSObject"); ObjCInterfaceDecl *ID = MD->getClassInterface()->getSuperClass(); - for ( ; ID ; ID = ID->getSuperClass()) { + for (; ID; ID = ID->getSuperClass()) { IdentifierInfo *II = ID->getIdentifier(); if (II == NSObjectII) diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp index eb40711812e16..24e03d43fefc1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp @@ -48,7 +48,6 @@ class ObjCSuperDeallocChecker CheckerContext &C) const; private: - void diagnoseCallArguments(const CallEvent &CE, CheckerContext &C) const; void reportUseAfterDealloc(SymbolRef Sym, StringRef Desc, const Stmt *S, @@ -129,7 +128,7 @@ void ObjCSuperDeallocChecker::checkPostObjCMessage(const ObjCMethodCall &M, } void ObjCSuperDeallocChecker::checkLocation(SVal L, bool IsLoad, const Stmt *S, - CheckerContext &C) const { + CheckerContext &C) const { SymbolRef BaseSym = L.getLocSymbolInBase(); if (!BaseSym) return; @@ -162,8 +161,8 @@ void ObjCSuperDeallocChecker::checkLocation(SVal L, bool IsLoad, const Stmt *S, std::string Buf; llvm::raw_string_ostream OS(Buf); if (IvarRegion) { - OS << "Use of instance variable '" << *IvarRegion->getDecl() << - "' after 'self' has been deallocated"; + OS << "Use of instance variable '" << *IvarRegion->getDecl() + << "' after 'self' has been deallocated"; Desc = OS.str(); } @@ -214,8 +213,8 @@ void ObjCSuperDeallocChecker::diagnoseCallArguments(const CallEvent &CE, } } -void -ObjCSuperDeallocChecker::initIdentifierInfoAndSelectors(ASTContext &Ctx) const { +void ObjCSuperDeallocChecker::initIdentifierInfoAndSelectors( + ASTContext &Ctx) const { if (IIdealloc) return; @@ -225,8 +224,8 @@ ObjCSuperDeallocChecker::initIdentifierInfoAndSelectors(ASTContext &Ctx) const { SELdealloc = Ctx.Selectors.getSelector(0, &IIdealloc); } -bool -ObjCSuperDeallocChecker::isSuperDeallocMessage(const ObjCMethodCall &M) const { +bool ObjCSuperDeallocChecker::isSuperDeallocMessage( + const ObjCMethodCall &M) const { if (M.getOriginExpr()->getReceiverKind() != ObjCMessageExpr::SuperInstance) return false; diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp index 2f2df63468b4b..ac86b09e8e6be 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp @@ -28,9 +28,9 @@ using namespace clang; using namespace ento; enum IVarState { Unused, Used }; -typedef llvm::DenseMap IvarUsageMap; +typedef llvm::DenseMap IvarUsageMap; -static void Scan(IvarUsageMap& M, const Stmt *S) { +static void Scan(IvarUsageMap &M, const Stmt *S) { if (!S) return; @@ -59,7 +59,7 @@ static void Scan(IvarUsageMap& M, const Stmt *S) { Scan(M, SubStmt); } -static void Scan(IvarUsageMap& M, const ObjCPropertyImplDecl *D) { +static void Scan(IvarUsageMap &M, const ObjCPropertyImplDecl *D) { if (!D) return; @@ -73,7 +73,7 @@ static void Scan(IvarUsageMap& M, const ObjCPropertyImplDecl *D) { I->second = Used; } -static void Scan(IvarUsageMap& M, const ObjCContainerDecl *D) { +static void Scan(IvarUsageMap &M, const ObjCContainerDecl *D) { // Scan the methods for accesses. for (const auto *I : D->instance_methods()) Scan(M, I->getBody()); @@ -103,8 +103,7 @@ static void Scan(IvarUsageMap &M, const DeclContext *C, const FileID FID, } static void checkObjCUnusedIvar(const ObjCImplementationDecl *D, - BugReporter &BR, - const CheckerBase *Checker) { + BugReporter &BR, const CheckerBase *Checker) { const ObjCInterfaceDecl *ID = D->getClassInterface(); IvarUsageMap M; @@ -118,8 +117,7 @@ static void checkObjCUnusedIvar(const ObjCImplementationDecl *D, // (d) are unnamed bitfields if (Ivar->getAccessControl() != ObjCIvarDecl::Private || Ivar->hasAttr() || Ivar->hasAttr() || - Ivar->hasAttr() || - Ivar->isUnnamedBitfield()) + Ivar->hasAttr() || Ivar->isUnnamedBitfield()) continue; M[Ivar] = Unused; @@ -171,15 +169,15 @@ static void checkObjCUnusedIvar(const ObjCImplementationDecl *D, //===----------------------------------------------------------------------===// namespace { -class ObjCUnusedIvarsChecker : public Checker< - check::ASTDecl > { +class ObjCUnusedIvarsChecker + : public Checker> { public: - void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& mgr, + void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager &mgr, BugReporter &BR) const { checkObjCUnusedIvar(D, BR, this); } }; -} +} // namespace void ento::registerObjCUnusedIvarsChecker(CheckerManager &mgr) { mgr.registerChecker(); diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp index eee9449f31805..9f936d99d41a9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -11,12 +11,12 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/CharUnits.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Driver/DriverDiagnostic.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -347,11 +347,11 @@ class PaddingChecker : public Checker> { void ento::registerPaddingChecker(CheckerManager &Mgr) { auto *Checker = Mgr.registerChecker(); - Checker->AllowedPad = Mgr.getAnalyzerOptions() - .getCheckerIntegerOption(Checker, "AllowedPad"); + Checker->AllowedPad = + Mgr.getAnalyzerOptions().getCheckerIntegerOption(Checker, "AllowedPad"); if (Checker->AllowedPad < 0) - Mgr.reportInvalidCheckerOptionValue( - Checker, "AllowedPad", "a non-negative value"); + Mgr.reportInvalidCheckerOptionValue(Checker, "AllowedPad", + "a non-negative value"); } bool ento::shouldRegisterPaddingChecker(const CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerIterationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerIterationChecker.cpp index 8aca6d009cdb0..4c65fde1c2867 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PointerIterationChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PointerIterationChecker.cpp @@ -27,8 +27,7 @@ constexpr llvm::StringLiteral WarnAtNode = "iter"; class PointerIterationChecker : public Checker { public: - void checkASTCodeBody(const Decl *D, - AnalysisManager &AM, + void checkASTCodeBody(const Decl *D, AnalysisManager &AM, BugReporter &BR) const; }; @@ -41,9 +40,8 @@ static void emitDiagnostics(const BoundNodes &Match, const Decl *D, assert(MarkedStmt); auto Range = MarkedStmt->getSourceRange(); - auto Location = PathDiagnosticLocation::createBegin(MarkedStmt, - BR.getSourceManager(), - ADC); + auto Location = PathDiagnosticLocation::createBegin( + MarkedStmt, BR.getSourceManager(), ADC); std::string Diagnostics; llvm::raw_string_ostream OS(Diagnostics); OS << "Iteration of pointer-like elements " @@ -65,23 +63,21 @@ static void emitDiagnostics(const BoundNodes &Match, const Decl *D, auto matchUnorderedIterWithPointers() -> decltype(decl()) { - auto UnorderedContainerM = declRefExpr(to(varDecl(hasType( - recordDecl(hasName("std::unordered_set") - ))))); + auto UnorderedContainerM = declRefExpr( + to(varDecl(hasType(recordDecl(hasName("std::unordered_set")))))); auto PointerTypeM = varDecl(hasType(hasCanonicalType(pointerType()))); - auto PointerIterM = stmt(cxxForRangeStmt( - hasLoopVariable(PointerTypeM), - hasRangeInit(UnorderedContainerM) - )).bind(WarnAtNode); + auto PointerIterM = stmt(cxxForRangeStmt(hasLoopVariable(PointerTypeM), + hasRangeInit(UnorderedContainerM))) + .bind(WarnAtNode); return decl(forEachDescendant(PointerIterM)); } void PointerIterationChecker::checkASTCodeBody(const Decl *D, - AnalysisManager &AM, - BugReporter &BR) const { + AnalysisManager &AM, + BugReporter &BR) const { auto MatcherM = matchUnorderedIterWithPointers(); auto Matches = match(MatcherM, *D, AM.getASTContext()); diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerSortingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerSortingChecker.cpp index 25d87f4acfc91..3092baf3765e9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PointerSortingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PointerSortingChecker.cpp @@ -27,8 +27,7 @@ constexpr llvm::StringLiteral WarnAtNode = "sort"; class PointerSortingChecker : public Checker { public: - void checkASTCodeBody(const Decl *D, - AnalysisManager &AM, + void checkASTCodeBody(const Decl *D, AnalysisManager &AM, BugReporter &BR) const; }; @@ -41,9 +40,8 @@ static void emitDiagnostics(const BoundNodes &Match, const Decl *D, assert(MarkedStmt); auto Range = MarkedStmt->getSourceRange(); - auto Location = PathDiagnosticLocation::createBegin(MarkedStmt, - BR.getSourceManager(), - ADC); + auto Location = PathDiagnosticLocation::createBegin( + MarkedStmt, BR.getSourceManager(), ADC); std::string Diagnostics; llvm::raw_string_ostream OS(Diagnostics); OS << "Sorting pointer-like elements " @@ -68,23 +66,16 @@ decltype(auto) callsName(const char *FunctionName) { // sort-unique-erase and the sort call will emit a report. auto matchSortWithPointers() -> decltype(decl()) { // Match any of these function calls. - auto SortFuncM = anyOf( - callsName("std::is_sorted"), - callsName("std::nth_element"), - callsName("std::partial_sort"), - callsName("std::partition"), - callsName("std::sort"), - callsName("std::stable_partition"), - callsName("std::stable_sort") - ); + auto SortFuncM = + anyOf(callsName("std::is_sorted"), callsName("std::nth_element"), + callsName("std::partial_sort"), callsName("std::partition"), + callsName("std::sort"), callsName("std::stable_partition"), + callsName("std::stable_sort")); // Match only if the container has pointer-type elements. - auto IteratesPointerEltsM = hasArgument(0, - hasType(cxxRecordDecl(has( - fieldDecl(hasType(hasCanonicalType( - pointsTo(hasCanonicalType(pointerType())) - ))) - )))); + auto IteratesPointerEltsM = hasArgument( + 0, hasType(cxxRecordDecl(has(fieldDecl(hasType( + hasCanonicalType(pointsTo(hasCanonicalType(pointerType()))))))))); auto PointerSortM = traverse( TK_AsIs, @@ -93,8 +84,7 @@ auto matchSortWithPointers() -> decltype(decl()) { return decl(forEachDescendant(PointerSortM)); } -void PointerSortingChecker::checkASTCodeBody(const Decl *D, - AnalysisManager &AM, +void PointerSortingChecker::checkASTCodeBody(const Decl *D, AnalysisManager &AM, BugReporter &BR) const { auto MatcherM = matchSortWithPointers(); diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp index 2438cf30b39b5..26983362b8d42 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp @@ -23,14 +23,13 @@ using namespace clang; using namespace ento; namespace { -class PointerSubChecker - : public Checker< check::PreStmt > { +class PointerSubChecker : public Checker> { const BugType BT{this, "Pointer subtraction"}; public: void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; }; -} +} // namespace void PointerSubChecker::checkPreStmt(const BinaryOperator *B, CheckerContext &C) const { diff --git a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp index fa8572cf85edf..2a324d7f40350 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp @@ -701,7 +701,9 @@ void ento::registerPthreadLockBase(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterPthreadLockBase(const CheckerManager &mgr) { return true; } +bool ento::shouldRegisterPthreadLockBase(const CheckerManager &mgr) { + return true; +} #define REGISTER_CHECKER(name) \ void ento::register##name(CheckerManager &mgr) { \ diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp index 7e74b418b3353..151aa1f978de1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp @@ -49,66 +49,71 @@ void RefVal::print(raw_ostream &Out) const { Out << "Tracked " << T << " | "; switch (getKind()) { - default: llvm_unreachable("Invalid RefVal kind"); - case Owned: { - Out << "Owned"; - unsigned cnt = getCount(); - if (cnt) Out << " (+ " << cnt << ")"; - break; - } + default: + llvm_unreachable("Invalid RefVal kind"); + case Owned: { + Out << "Owned"; + unsigned cnt = getCount(); + if (cnt) + Out << " (+ " << cnt << ")"; + break; + } - case NotOwned: { - Out << "NotOwned"; - unsigned cnt = getCount(); - if (cnt) Out << " (+ " << cnt << ")"; - break; - } + case NotOwned: { + Out << "NotOwned"; + unsigned cnt = getCount(); + if (cnt) + Out << " (+ " << cnt << ")"; + break; + } - case ReturnedOwned: { - Out << "ReturnedOwned"; - unsigned cnt = getCount(); - if (cnt) Out << " (+ " << cnt << ")"; - break; - } + case ReturnedOwned: { + Out << "ReturnedOwned"; + unsigned cnt = getCount(); + if (cnt) + Out << " (+ " << cnt << ")"; + break; + } - case ReturnedNotOwned: { - Out << "ReturnedNotOwned"; - unsigned cnt = getCount(); - if (cnt) Out << " (+ " << cnt << ")"; - break; - } + case ReturnedNotOwned: { + Out << "ReturnedNotOwned"; + unsigned cnt = getCount(); + if (cnt) + Out << " (+ " << cnt << ")"; + break; + } - case Released: - Out << "Released"; - break; + case Released: + Out << "Released"; + break; - case ErrorDeallocNotOwned: - Out << "-dealloc (not-owned)"; - break; + case ErrorDeallocNotOwned: + Out << "-dealloc (not-owned)"; + break; - case ErrorLeak: - Out << "Leaked"; - break; + case ErrorLeak: + Out << "Leaked"; + break; - case ErrorLeakReturned: - Out << "Leaked (Bad naming)"; - break; + case ErrorLeakReturned: + Out << "Leaked (Bad naming)"; + break; - case ErrorUseAfterRelease: - Out << "Use-After-Release [ERROR]"; - break; + case ErrorUseAfterRelease: + Out << "Use-After-Release [ERROR]"; + break; - case ErrorReleaseNotOwned: - Out << "Release of Not-Owned [ERROR]"; - break; + case ErrorReleaseNotOwned: + Out << "Release of Not-Owned [ERROR]"; + break; - case RefVal::ErrorOverAutorelease: - Out << "Over-autoreleased"; - break; + case RefVal::ErrorOverAutorelease: + Out << "Over-autoreleased"; + break; - case RefVal::ErrorReturnedNotOwned: - Out << "Non-owned object returned instead of owned"; - break; + case RefVal::ErrorReturnedNotOwned: + Out << "Non-owned object returned instead of owned"; + break; } switch (getIvarAccessHistory()) { @@ -129,6 +134,7 @@ void RefVal::print(raw_ostream &Out) const { namespace { class StopTrackingCallback final : public SymbolVisitor { ProgramStateRef state; + public: StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {} ProgramStateRef getState() const { return state; } @@ -162,7 +168,7 @@ void RetainCountChecker::checkPostStmt(const BlockExpr *BE, // FIXME: For now we invalidate the tracking of all symbols passed to blocks // via captured variables, even though captured variables result in a copy // and in implicit increment/decrement of a retain count. - SmallVector Regions; + SmallVector Regions; const LocationContext *LC = C.getLocationContext(); MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager(); @@ -195,26 +201,26 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE, ArgEffect AE = ArgEffect(IncRef, K); switch (BE->getBridgeKind()) { - case OBC_Bridge: - // Do nothing. - return; - case OBC_BridgeRetained: - AE = AE.withKind(IncRef); - break; - case OBC_BridgeTransfer: - AE = AE.withKind(DecRefBridgedTransferred); - break; + case OBC_Bridge: + // Do nothing. + return; + case OBC_BridgeRetained: + AE = AE.withKind(IncRef); + break; + case OBC_BridgeTransfer: + AE = AE.withKind(DecRefBridgedTransferred); + break; } ProgramStateRef state = C.getState(); SymbolRef Sym = C.getSVal(CE).getAsLocSymbol(); if (!Sym) return; - const RefVal* T = getRefBinding(state, Sym); + const RefVal *T = getRefBinding(state, Sym); if (!T) return; - RefVal::Kind hasErr = (RefVal::Kind) 0; + RefVal::Kind hasErr = (RefVal::Kind)0; state = updateSymbol(state, Sym, *T, AE, hasErr, C); if (hasErr) { @@ -232,8 +238,8 @@ void RetainCountChecker::processObjCLiterals(CheckerContext &C, for (const Stmt *Child : Ex->children()) { SVal V = pred->getSVal(Child); if (SymbolRef sym = V.getAsSymbol()) - if (const RefVal* T = getRefBinding(state, sym)) { - RefVal::Kind hasErr = (RefVal::Kind) 0; + if (const RefVal *T = getRefBinding(state, sym)) { + RefVal::Kind hasErr = (RefVal::Kind)0; state = updateSymbol(state, sym, *T, ArgEffect(MayEscape, ObjKind::ObjC), hasErr, C); if (hasErr) { @@ -246,7 +252,7 @@ void RetainCountChecker::processObjCLiterals(CheckerContext &C, // Return the object as autoreleased. // RetEffect RE = RetEffect::MakeNotOwned(ObjKind::ObjC); if (SymbolRef sym = - state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) { + state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) { QualType ResultTy = Ex->getType(); state = setRefBinding(state, sym, RefVal::makeNotOwned(ObjKind::ObjC, ResultTy)); @@ -352,9 +358,8 @@ const static RetainSummary *getSummary(RetainSummaryManager &Summaries, const CallEvent &Call, QualType ReceiverType) { const Expr *CE = Call.getOriginExpr(); - AnyCall C = - CE ? *AnyCall::forExpr(CE) - : AnyCall(cast(Call.getDecl())); + AnyCall C = CE ? *AnyCall::forExpr(CE) + : AnyCall(cast(Call.getDecl())); return Summaries.getSummary(C, Call.hasNonZeroCallbackArg(), isReceiverUnconsumedSelf(Call), ReceiverType); } @@ -404,8 +409,8 @@ static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) { // is a call to a class method whose type we can resolve. In such // cases, promote the return type to XXX* (where XXX is the class). const ObjCInterfaceDecl *D = ME->getReceiverInterface(); - return !D ? RetTy : - Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D)); + return !D ? RetTy + : Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D)); } return RetTy; @@ -433,7 +438,7 @@ static bool isPointerToObject(QualType QT) { /// Whether the tracked value should be escaped on a given call. /// OSObjects are escaped when passed to void * / etc. static bool shouldEscapeOSArgumentOnCall(const CallEvent &CE, unsigned ArgIdx, - const RefVal *TrackedValue) { + const RefVal *TrackedValue) { if (TrackedValue->getObjKind() != ObjKind::OS) return false; if (ArgIdx >= CE.parameters().size()) @@ -485,12 +490,11 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ, } static bool isSmartPtrField(const MemRegion *MR) { - const auto *TR = dyn_cast( - cast(MR)->getSuperRegion()); + const auto *TR = + dyn_cast(cast(MR)->getSuperRegion()); return TR && RetainSummaryManager::isKnownSmartPointer(TR->getValueType()); } - /// A value escapes in these possible cases: /// /// - binding to something that is not a memory region. @@ -607,7 +611,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ, ProgramStateRef state = C.getState(); // Evaluate the effect of the arguments. - RefVal::Kind hasErr = (RefVal::Kind) 0; + RefVal::Kind hasErr = (RefVal::Kind)0; SourceRange ErrorRange; SymbolRef ErrorSym = nullptr; @@ -644,8 +648,8 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ, if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) { if (const RefVal *T = getRefBinding(state, Sym)) { ReceiverIsTracked = true; - state = updateSymbol(state, Sym, *T, - Summ.getReceiverEffect(), hasErr, C); + state = + updateSymbol(state, Sym, *T, Summ.getReceiverEffect(), hasErr, C); if (hasErr) { ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange(); ErrorSym = Sym; @@ -657,8 +661,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ, } else if (const auto *MCall = dyn_cast(&CallOrMsg)) { if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) { if (const RefVal *T = getRefBinding(state, Sym)) { - state = updateSymbol(state, Sym, *T, Summ.getThisEffect(), - hasErr, C); + state = updateSymbol(state, Sym, *T, Summ.getThisEffect(), hasErr, C); if (hasErr) { ErrorRange = MCall->getOriginExpr()->getSourceRange(); ErrorSym = Sym; @@ -737,103 +740,103 @@ ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state, } switch (AE.getKind()) { - case UnretainedOutParameter: - case RetainedOutParameter: - case RetainedOutParameterOnZero: - case RetainedOutParameterOnNonZero: - llvm_unreachable("Applies to pointer-to-pointer parameters, which should " - "not have ref state."); - - case Dealloc: // NB. we only need to add a note in a non-error case. - switch (V.getKind()) { - default: - llvm_unreachable("Invalid RefVal state for an explicit dealloc."); - case RefVal::Owned: - // The object immediately transitions to the released state. - V = V ^ RefVal::Released; - V.clearCounts(); - return setRefBinding(state, sym, V); - case RefVal::NotOwned: - V = V ^ RefVal::ErrorDeallocNotOwned; - hasErr = V.getKind(); - break; - } + case UnretainedOutParameter: + case RetainedOutParameter: + case RetainedOutParameterOnZero: + case RetainedOutParameterOnNonZero: + llvm_unreachable("Applies to pointer-to-pointer parameters, which should " + "not have ref state."); + + case Dealloc: // NB. we only need to add a note in a non-error case. + switch (V.getKind()) { + default: + llvm_unreachable("Invalid RefVal state for an explicit dealloc."); + case RefVal::Owned: + // The object immediately transitions to the released state. + V = V ^ RefVal::Released; + V.clearCounts(); + return setRefBinding(state, sym, V); + case RefVal::NotOwned: + V = V ^ RefVal::ErrorDeallocNotOwned; + hasErr = V.getKind(); break; + } + break; - case MayEscape: - if (V.getKind() == RefVal::Owned) { - V = V ^ RefVal::NotOwned; - break; - } + case MayEscape: + if (V.getKind() == RefVal::Owned) { + V = V ^ RefVal::NotOwned; + break; + } - [[fallthrough]]; + [[fallthrough]]; - case DoNothing: - return state; + case DoNothing: + return state; - case Autorelease: - // Update the autorelease counts. - V = V.autorelease(); - break; + case Autorelease: + // Update the autorelease counts. + V = V.autorelease(); + break; - case StopTracking: - case StopTrackingHard: - return removeRefBinding(state, sym); + case StopTracking: + case StopTrackingHard: + return removeRefBinding(state, sym); - case IncRef: - switch (V.getKind()) { - default: - llvm_unreachable("Invalid RefVal state for a retain."); - case RefVal::Owned: - case RefVal::NotOwned: - V = V + 1; - break; - } + case IncRef: + switch (V.getKind()) { + default: + llvm_unreachable("Invalid RefVal state for a retain."); + case RefVal::Owned: + case RefVal::NotOwned: + V = V + 1; break; + } + break; - case DecRef: - case DecRefBridgedTransferred: - case DecRefAndStopTrackingHard: - switch (V.getKind()) { - default: - // case 'RefVal::Released' handled above. - llvm_unreachable("Invalid RefVal state for a release."); - - case RefVal::Owned: - assert(V.getCount() > 0); - if (V.getCount() == 1) { - if (AE.getKind() == DecRefBridgedTransferred || - V.getIvarAccessHistory() == - RefVal::IvarAccessHistory::AccessedDirectly) - V = V ^ RefVal::NotOwned; - else - V = V ^ RefVal::Released; - } else if (AE.getKind() == DecRefAndStopTrackingHard) { - return removeRefBinding(state, sym); - } + case DecRef: + case DecRefBridgedTransferred: + case DecRefAndStopTrackingHard: + switch (V.getKind()) { + default: + // case 'RefVal::Released' handled above. + llvm_unreachable("Invalid RefVal state for a release."); + + case RefVal::Owned: + assert(V.getCount() > 0); + if (V.getCount() == 1) { + if (AE.getKind() == DecRefBridgedTransferred || + V.getIvarAccessHistory() == + RefVal::IvarAccessHistory::AccessedDirectly) + V = V ^ RefVal::NotOwned; + else + V = V ^ RefVal::Released; + } else if (AE.getKind() == DecRefAndStopTrackingHard) { + return removeRefBinding(state, sym); + } - V = V - 1; - break; + V = V - 1; + break; - case RefVal::NotOwned: - if (V.getCount() > 0) { - if (AE.getKind() == DecRefAndStopTrackingHard) - return removeRefBinding(state, sym); - V = V - 1; - } else if (V.getIvarAccessHistory() == - RefVal::IvarAccessHistory::AccessedDirectly) { - // Assume that the instance variable was holding on the object at - // +1, and we just didn't know. - if (AE.getKind() == DecRefAndStopTrackingHard) - return removeRefBinding(state, sym); - V = V.releaseViaIvar() ^ RefVal::Released; - } else { - V = V ^ RefVal::ErrorReleaseNotOwned; - hasErr = V.getKind(); - } - break; + case RefVal::NotOwned: + if (V.getCount() > 0) { + if (AE.getKind() == DecRefAndStopTrackingHard) + return removeRefBinding(state, sym); + V = V - 1; + } else if (V.getIvarAccessHistory() == + RefVal::IvarAccessHistory::AccessedDirectly) { + // Assume that the instance variable was holding on the object at + // +1, and we just didn't know. + if (AE.getKind() == DecRefAndStopTrackingHard) + return removeRefBinding(state, sym); + V = V.releaseViaIvar() ^ RefVal::Released; + } else { + V = V ^ RefVal::ErrorReleaseNotOwned; + hasErr = V.getKind(); } break; + } + break; } return setRefBinding(state, sym, V); } @@ -842,16 +845,16 @@ const RefCountBug & RetainCountChecker::errorKindToBugKind(RefVal::Kind ErrorKind, SymbolRef Sym) const { switch (ErrorKind) { - case RefVal::ErrorUseAfterRelease: - return *UseAfterRelease; - case RefVal::ErrorReleaseNotOwned: - return *ReleaseNotOwned; - case RefVal::ErrorDeallocNotOwned: - if (Sym->getType()->getPointeeCXXRecordDecl()) - return *FreeNotOwned; - return *DeallocNotOwned; - default: - llvm_unreachable("Unhandled error."); + case RefVal::ErrorUseAfterRelease: + return *UseAfterRelease; + case RefVal::ErrorReleaseNotOwned: + return *ReleaseNotOwned; + case RefVal::ErrorDeallocNotOwned: + if (Sym->getType()->getPointeeCXXRecordDecl()) + return *FreeNotOwned; + return *DeallocNotOwned; + default: + llvm_unreachable("Unhandled error."); } } @@ -874,9 +877,9 @@ void RetainCountChecker::processNonLeakError(ProgramStateRef St, if (!N) return; - auto report = std::make_unique( - errorKindToBugKind(ErrorKind, Sym), - C.getASTContext().getLangOpts(), N, Sym); + auto report = + std::make_unique(errorKindToBugKind(ErrorKind, Sym), + C.getASTContext().getLangOpts(), N, Sym); report->addRange(ErrorRange); C.emitReport(std::move(report)); } @@ -952,7 +955,6 @@ bool RetainCountChecker::evalCall(const CallEvent &Call, // output are non-zero. if (auto L = RetVal.getAs()) state = state->assume(*L, /*assumption=*/true); - } } @@ -960,8 +962,8 @@ bool RetainCountChecker::evalCall(const CallEvent &Call, return true; } -ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S, - CheckerContext &C) const { +ExplodedNode *RetainCountChecker::processReturn(const ReturnStmt *S, + CheckerContext &C) const { ExplodedNode *Pred = C.getPredecessor(); // Only adjust the reference count if this is the top-level call frame, @@ -996,27 +998,27 @@ ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S, RefVal X = *T; switch (X.getKind()) { - case RefVal::Owned: { - unsigned cnt = X.getCount(); - assert(cnt > 0); + case RefVal::Owned: { + unsigned cnt = X.getCount(); + assert(cnt > 0); + X.setCount(cnt - 1); + X = X ^ RefVal::ReturnedOwned; + break; + } + + case RefVal::NotOwned: { + unsigned cnt = X.getCount(); + if (cnt) { X.setCount(cnt - 1); X = X ^ RefVal::ReturnedOwned; - break; - } - - case RefVal::NotOwned: { - unsigned cnt = X.getCount(); - if (cnt) { - X.setCount(cnt - 1); - X = X ^ RefVal::ReturnedOwned; - } else { - X = X ^ RefVal::ReturnedNotOwned; - } - break; + } else { + X = X ^ RefVal::ReturnedNotOwned; } + break; + } - default: - return Pred; + default: + return Pred; } // Update the binding. @@ -1063,12 +1065,9 @@ ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S, return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state); } -ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S, - CheckerContext &C, - ExplodedNode *Pred, - RetEffect RE, RefVal X, - SymbolRef Sym, - ProgramStateRef state) const { +ExplodedNode *RetainCountChecker::checkReturnWithRetEffect( + const ReturnStmt *S, CheckerContext &C, ExplodedNode *Pred, RetEffect RE, + RefVal X, SymbolRef Sym, ProgramStateRef state) const { // HACK: Ignore retain-count issues on values accessed through ivars, // because of cases like this: // [_contentView retain]; @@ -1104,7 +1103,7 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S, } else if (X.isReturnedNotOwned()) { if (RE.isOwned()) { if (X.getIvarAccessHistory() == - RefVal::IvarAccessHistory::AccessedDirectly) { + RefVal::IvarAccessHistory::AccessedDirectly) { // Assume the method was trying to transfer a +1 reference from a // strong ivar to the caller. state = setRefBinding(state, Sym, @@ -1114,8 +1113,8 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S, // owned object. state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned); - static CheckerProgramPointTag - ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned"); + static CheckerProgramPointTag ReturnNotOwnedTag( + this, "ReturnNotOwnedForOwned"); ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag); if (N) { @@ -1147,8 +1146,7 @@ void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S, } } -ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state, - SVal Cond, +ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state, SVal Cond, bool Assumption) const { // FIXME: We may add to the interface of evalAssume the list of symbols // whose assumptions have changed. For now we just iterate through the @@ -1203,14 +1201,9 @@ ProgramStateRef RetainCountChecker::checkRegionChanges( return state; } -ProgramStateRef -RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state, - ExplodedNode *Pred, - const ProgramPointTag *Tag, - CheckerContext &Ctx, - SymbolRef Sym, - RefVal V, - const ReturnStmt *S) const { +ProgramStateRef RetainCountChecker::handleAutoreleaseCounts( + ProgramStateRef state, ExplodedNode *Pred, const ProgramPointTag *Tag, + CheckerContext &Ctx, SymbolRef Sym, RefVal V, const ReturnStmt *S) const { unsigned ACnt = V.getAutoreleaseCount(); // No autorelease counts? Nothing to be done. @@ -1281,10 +1274,9 @@ RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state, return nullptr; } -ProgramStateRef -RetainCountChecker::handleSymbolDeath(ProgramStateRef state, - SymbolRef sid, RefVal V, - SmallVectorImpl &Leaked) const { +ProgramStateRef RetainCountChecker::handleSymbolDeath( + ProgramStateRef state, SymbolRef sid, RefVal V, + SmallVectorImpl &Leaked) const { bool hasLeak; // HACK: Ignore retain-count issues on values accessed through ivars, @@ -1309,11 +1301,9 @@ RetainCountChecker::handleSymbolDeath(ProgramStateRef state, return setRefBinding(state, sid, V ^ RefVal::ErrorLeak); } -ExplodedNode * -RetainCountChecker::processLeaks(ProgramStateRef state, - SmallVectorImpl &Leaked, - CheckerContext &Ctx, - ExplodedNode *Pred) const { +ExplodedNode *RetainCountChecker::processLeaks( + ProgramStateRef state, SmallVectorImpl &Leaked, + CheckerContext &Ctx, ExplodedNode *Pred) const { // Generate an intermediate node representing the leak point. ExplodedNode *N = Ctx.addTransition(state, Pred); const LangOptions &LOpts = Ctx.getASTContext().getLangOpts(); @@ -1384,8 +1374,8 @@ void RetainCountChecker::checkEndFunction(const ReturnStmt *RS, } for (auto &I : B) { - state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx, - I.first, I.second); + state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx, I.first, + I.second); if (!state) return; } @@ -1414,7 +1404,7 @@ void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper, SmallVector Leaked; // Update counts from autorelease pools - for (const auto &I: state->get()) { + for (const auto &I : state->get()) { SymbolRef Sym = I.first; if (SymReaper.isDead(Sym)) { static CheckerProgramPointTag Tag(this, "DeadSymbolAutorelease"); diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h index d4d7c4c74c56b..d9dd7e1f0f024 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h @@ -14,7 +14,6 @@ #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_H -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "RetainCountDiagnostics.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" @@ -23,9 +22,10 @@ #include "clang/Analysis/DomainSpecific/CocoaConventions.h" #include "clang/Analysis/PathDiagnostic.h" #include "clang/Analysis/RetainSummaryManager.h" +#include "clang/Analysis/SelectorExtras.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceManager.h" -#include "clang/Analysis/SelectorExtras.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -50,17 +50,17 @@ namespace retaincountchecker { class RefVal { public: enum Kind { - Owned = 0, // Owning reference. - NotOwned, // Reference is not owned by still valid (not freed). - Released, // Object has been released. - ReturnedOwned, // Returned object passes ownership to caller. + Owned = 0, // Owning reference. + NotOwned, // Reference is not owned by still valid (not freed). + Released, // Object has been released. + ReturnedOwned, // Returned object passes ownership to caller. ReturnedNotOwned, // Return object does not pass ownership to caller. ERROR_START, ErrorDeallocNotOwned, // -dealloc called on non-owned object. ErrorUseAfterRelease, // Object used after released. ErrorReleaseNotOwned, // Release of an object that was not owned. ERROR_LEAK_START, - ErrorLeak, // A memory leak due to excessive reference counts. + ErrorLeak, // A memory leak due to excessive reference counts. ErrorLeakReturned, // A memory leak due to the returning method not having // the correct naming conventions. ErrorOverAutorelease, @@ -108,9 +108,9 @@ class RefVal { RefVal(Kind k, ObjKind o, unsigned cnt, unsigned acnt, QualType t, IvarAccessHistory IvarAccess) - : Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast(k)), - RawObjectKind(static_cast(o)), - RawIvarAccessHistory(static_cast(IvarAccess)) { + : Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast(k)), + RawObjectKind(static_cast(o)), + RawIvarAccessHistory(static_cast(IvarAccess)) { assert(getKind() == k && "not enough bits for the kind"); assert(getObjKind() == o && "not enough bits for the object kind"); assert(getIvarAccessHistory() == IvarAccess && "not enough bits"); @@ -119,9 +119,7 @@ class RefVal { public: Kind getKind() const { return static_cast(RawKind); } - ObjKind getObjKind() const { - return static_cast(RawObjectKind); - } + ObjKind getObjKind() const { return static_cast(RawObjectKind); } unsigned getCount() const { return Cnt; } unsigned getAutoreleaseCount() const { return ACnt; } @@ -130,12 +128,8 @@ class RefVal { Cnt = 0; ACnt = 0; } - void setCount(unsigned i) { - Cnt = i; - } - void setAutoreleaseCount(unsigned i) { - ACnt = i; - } + void setCount(unsigned i) { Cnt = i; } + void setAutoreleaseCount(unsigned i) { ACnt = i; } QualType getType() const { return T; } @@ -148,21 +142,13 @@ class RefVal { return static_cast(RawIvarAccessHistory); } - bool isOwned() const { - return getKind() == Owned; - } + bool isOwned() const { return getKind() == Owned; } - bool isNotOwned() const { - return getKind() == NotOwned; - } + bool isNotOwned() const { return getKind() == NotOwned; } - bool isReturnedOwned() const { - return getKind() == ReturnedOwned; - } + bool isReturnedOwned() const { return getKind() == ReturnedOwned; } - bool isReturnedNotOwned() const { - return getKind() == ReturnedNotOwned; - } + bool isReturnedNotOwned() const { return getKind() == ReturnedNotOwned; } /// Create a state for an object whose lifetime is the responsibility of the /// current function, at least partially. @@ -191,13 +177,13 @@ class RefVal { } RefVal operator^(Kind k) const { - return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(), - getType(), getIvarAccessHistory()); + return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(), getType(), + getIvarAccessHistory()); } RefVal autorelease() const { - return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1, - getType(), getIvarAccessHistory()); + return RefVal(getKind(), getObjKind(), getCount(), + getAutoreleaseCount() + 1, getType(), getIvarAccessHistory()); } RefVal withIvarAccess() const { @@ -218,11 +204,11 @@ class RefVal { getIvarAccessHistory() == X.getIvarAccessHistory(); } - bool operator==(const RefVal& X) const { + bool operator==(const RefVal &X) const { return T == X.T && hasSameState(X) && getObjKind() == X.getObjKind(); } - void Profile(llvm::FoldingSetNodeID& ID) const { + void Profile(llvm::FoldingSetNodeID &ID) const { ID.Add(T); ID.AddInteger(RawKind); ID.AddInteger(Cnt); @@ -235,20 +221,13 @@ class RefVal { }; class RetainCountChecker - : public Checker< check::Bind, - check::DeadSymbols, - check::BeginFunction, - check::EndFunction, - check::PostStmt, - check::PostStmt, - check::PostStmt, - check::PostStmt, - check::PostStmt, - check::PostStmt, - check::PostCall, - check::RegionChanges, - eval::Assume, - eval::Call > { + : public Checker< + check::Bind, check::DeadSymbols, check::BeginFunction, + check::EndFunction, check::PostStmt, + check::PostStmt, check::PostStmt, + check::PostStmt, + check::PostStmt, check::PostStmt, + check::PostCall, check::RegionChanges, eval::Assume, eval::Call> { public: std::unique_ptr UseAfterRelease; @@ -287,8 +266,8 @@ class RetainCountChecker return getSummaryManager(C.getASTContext()); } - void printState(raw_ostream &Out, ProgramStateRef State, - const char *NL, const char *Sep) const override; + void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, + const char *Sep) const override; void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const; void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const; @@ -305,33 +284,32 @@ class RetainCountChecker void checkSummary(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const; - void processSummaryOfInlined(const RetainSummary &Summ, - const CallEvent &Call, + void processSummaryOfInlined(const RetainSummary &Summ, const CallEvent &Call, CheckerContext &C) const; bool evalCall(const CallEvent &Call, CheckerContext &C) const; ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, - bool Assumption) const; + bool Assumption) const; ProgramStateRef checkRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef ExplicitRegions, ArrayRef Regions, - const LocationContext* LCtx, - const CallEvent *Call) const; + const LocationContext *LCtx, const CallEvent *Call) const; - ExplodedNode* checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, - ExplodedNode *Pred, RetEffect RE, RefVal X, - SymbolRef Sym, ProgramStateRef state) const; + ExplodedNode *checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C, + ExplodedNode *Pred, RetEffect RE, + RefVal X, SymbolRef Sym, + ProgramStateRef state) const; void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; void checkBeginFunction(CheckerContext &C) const; void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; - ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym, - RefVal V, ArgEffect E, RefVal::Kind &hasErr, + ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym, RefVal V, + ArgEffect E, RefVal::Kind &hasErr, CheckerContext &C) const; const RefCountBug &errorKindToBugKind(RefVal::Kind ErrorKind, @@ -343,16 +321,16 @@ class RetainCountChecker void processObjCLiterals(CheckerContext &C, const Expr *Ex) const; - ProgramStateRef handleSymbolDeath(ProgramStateRef state, - SymbolRef sid, RefVal V, + ProgramStateRef handleSymbolDeath(ProgramStateRef state, SymbolRef sid, + RefVal V, SmallVectorImpl &Leaked) const; - ProgramStateRef - handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred, - const ProgramPointTag *Tag, CheckerContext &Ctx, - SymbolRef Sym, - RefVal V, - const ReturnStmt *S=nullptr) const; + ProgramStateRef handleAutoreleaseCounts(ProgramStateRef state, + ExplodedNode *Pred, + const ProgramPointTag *Tag, + CheckerContext &Ctx, SymbolRef Sym, + RefVal V, + const ReturnStmt *S = nullptr) const; ExplodedNode *processLeaks(ProgramStateRef state, SmallVectorImpl &Leaked, @@ -369,7 +347,7 @@ class RetainCountChecker /// Perform the necessary checks and state adjustments at the end of the /// function. /// \p S Return statement, may be null. - ExplodedNode * processReturn(const ReturnStmt *S, CheckerContext &C) const; + ExplodedNode *processReturn(const ReturnStmt *S, CheckerContext &C) const; }; //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp index c3acb73ba7175..26f2807a9afb4 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp @@ -53,7 +53,7 @@ StringRef RefCountBug::getDescription() const { case DeallocNotOwned: return "-dealloc sent to object that may be referenced elsewhere"; case FreeNotOwned: - return "'free' called on an object that may be referenced elsewhere"; + return "'free' called on an object that may be referenced elsewhere"; case OverAutorelease: return "Object autoreleased too many times"; case ReturnNotOwnedForOwned: @@ -92,8 +92,7 @@ static std::string getPrettyTypeName(QualType QT) { /// Write information about the type state change to @c os, /// return whether the note should be generated. static bool shouldGenerateNote(llvm::raw_string_ostream &os, - const RefVal *PrevT, - const RefVal &CurrV, + const RefVal *PrevT, const RefVal &CurrV, bool DeallocSent) { // Get the previous type state. RefVal PrevV = *PrevT; @@ -194,7 +193,6 @@ static std::optional findMetaClassAlloc(const Expr *Callee) { if (const auto *RD = dyn_cast(VD->getDeclContext())) return RD->getNameAsString(); - } } return std::nullopt; @@ -300,7 +298,6 @@ static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt, } else if (CurrSt->isNonNull(RV).isConstrainedTrue()) { os << " (assuming the call returns non-zero)"; } - } } } @@ -348,7 +345,6 @@ class RefLeakReportVisitor : public RefCountReportVisitor { } // end namespace ento } // end namespace clang - /// Find the first node with the parent stack frame. static const ExplodedNode *getCalleeNode(const ExplodedNode *Pred) { const StackFrameContext *SC = Pred->getStackFrame(); @@ -365,7 +361,6 @@ static const ExplodedNode *getCalleeNode(const ExplodedNode *Pred) { return N; } - /// Insert a diagnostic piece at function exit /// if a function parameter is annotated as "os_consumed", /// but it does not actually consume the reference. @@ -384,7 +379,7 @@ annotateConsumedSummaryMismatch(const ExplodedNode *N, std::string sbuf; llvm::raw_string_ostream os(sbuf); ArrayRef Parameters = Call->parameters(); - for (unsigned I=0; I < Call->getNumArgs() && I < Parameters.size(); ++I) { + for (unsigned I = 0; I < Call->getNumArgs() && I < Parameters.size(); ++I) { const ParmVarDecl *PVD = Parameters[I]; if (!PVD->hasAttr()) @@ -453,7 +448,7 @@ PathDiagnosticPieceRef RefCountReportVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) { - const auto &BT = static_cast(BR.getBugType()); + const auto &BT = static_cast(BR.getBugType()); bool IsFreeUnowned = BT.getBugType() == RefCountBug::FreeNotOwned || BT.getBugType() == RefCountBug::DeallocNotOwned; @@ -478,7 +473,7 @@ RefCountReportVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, ProgramStateRef CurrSt = N->getState(); const LocationContext *LCtx = N->getLocationContext(); - const RefVal* CurrT = getRefBinding(CurrSt, Sym); + const RefVal *CurrT = getRefBinding(CurrSt, Sym); if (!CurrT) return nullptr; @@ -558,7 +553,7 @@ RefCountReportVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, // was ever passed as an argument. unsigned i = 0; - for (auto AI=CE->arg_begin(), AE=CE->arg_end(); AI!=AE; ++AI, ++i) { + for (auto AI = CE->arg_begin(), AE = CE->arg_end(); AI != AE; ++AI, ++i) { // Retrieve the value of the argument. Is it the symbol // we are interested in? @@ -570,8 +565,8 @@ RefCountReportVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, } } else if (const ObjCMessageExpr *ME = dyn_cast(S)) { if (const Expr *receiver = ME->getInstanceReceiver()) { - if (CurrSt->getSValAsScalarOrLoc(receiver, LCtx) - .getAsLocSymbol() == Sym) { + if (CurrSt->getSValAsScalarOrLoc(receiver, LCtx).getAsLocSymbol() == + Sym) { // The symbol we are tracking is the receiver. DeallocSent = true; } @@ -587,7 +582,7 @@ RefCountReportVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, const Stmt *S = N->getLocation().castAs().getStmt(); PathDiagnosticLocation Pos(S, BRC.getSourceManager(), - N->getLocationContext()); + N->getLocationContext()); auto P = std::make_shared(Pos, os.str()); // Add the range by scanning the children of the statement for any bindings @@ -654,13 +649,12 @@ namespace { // the leak. The function can also return a location context, which should be // treated as interesting. struct AllocationInfo { - const ExplodedNode* N; + const ExplodedNode *N; const MemRegion *R; const LocationContext *InterestingMethodContext; - AllocationInfo(const ExplodedNode *InN, - const MemRegion *InR, - const LocationContext *InInterestingMethodContext) : - N(InN), R(InR), InterestingMethodContext(InInterestingMethodContext) {} + AllocationInfo(const ExplodedNode *InN, const MemRegion *InR, + const LocationContext *InInterestingMethodContext) + : N(InN), R(InR), InterestingMethodContext(InInterestingMethodContext) {} }; } // end anonymous namespace @@ -700,10 +694,10 @@ static AllocationInfo GetAllocationSite(ProgramStateManager &StateMgr, // AllocationNodeInCurrentContext, is the last node in the current or // parent context in which the symbol was tracked. // - // Note that the allocation site might be in the parent context. For example, - // the case where an allocation happens in a block that captures a reference - // to it and that reference is overwritten/dropped by another call to - // the block. + // Note that the allocation site might be in the parent context. For + // example, the case where an allocation happens in a block that captures a + // reference to it and that reference is overwritten/dropped by another call + // to the block. if (NContext == LeakContext || NContext->isParentOf(LeakContext)) AllocationNodeInCurrentOrParentContext = N; @@ -742,7 +736,7 @@ static AllocationInfo GetAllocationSite(ProgramStateManager &StateMgr, if (AllocationNodeInCurrentOrParentContext && AllocationNodeInCurrentOrParentContext->getLocationContext() != - LeakContext) + LeakContext) FirstBinding = nullptr; return AllocationInfo(AllocationNodeInCurrentOrParentContext, FirstBinding, diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h index d05900895c6a6..25d32dc4f71a5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h @@ -16,8 +16,8 @@ #include "clang/Analysis/PathDiagnostic.h" #include "clang/Analysis/RetainSummaryManager.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" namespace clang { @@ -53,12 +53,10 @@ class RefCountReport : public PathSensitiveBugReport { public: RefCountReport(const RefCountBug &D, const LangOptions &LOpts, - ExplodedNode *n, SymbolRef sym, - bool isLeak=false); + ExplodedNode *n, SymbolRef sym, bool isLeak = false); RefCountReport(const RefCountBug &D, const LangOptions &LOpts, - ExplodedNode *n, SymbolRef sym, - StringRef endText); + ExplodedNode *n, SymbolRef sym, StringRef endText); ArrayRef getRanges() const override { if (!isLeak) diff --git a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp index 09d82ebabd4c9..609a38f83ba55 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp @@ -24,16 +24,15 @@ using namespace clang; using namespace ento; namespace { -class ReturnPointerRangeChecker : - public Checker< check::PreStmt > { +class ReturnPointerRangeChecker : public Checker> { // FIXME: This bug correspond to CWE-466. Eventually we should have bug // types explicitly reference such exploit categories (when applicable). const BugType BT{this, "Buffer overflow"}; public: - void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const; + void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const; }; -} +} // namespace void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const { diff --git a/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp index efffbf2ee7559..35d2a26adf94c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp @@ -23,17 +23,18 @@ using namespace clang; using namespace ento; namespace { -class ReturnUndefChecker : public Checker< check::PreStmt > { +class ReturnUndefChecker : public Checker> { const BugType BT_Undef{this, "Garbage return value"}; const BugType BT_NullReference{this, "Returning null reference"}; void emitUndef(CheckerContext &C, const Expr *RetE) const; void checkReference(CheckerContext &C, const Expr *RetE, DefinedOrUnknownSVal RetVal) const; + public: void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const; }; -} +} // namespace void ReturnUndefChecker::checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const { diff --git a/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp index 2cf6c6ff47f1d..2f8c525bcf20e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp @@ -22,10 +22,10 @@ //===----------------------------------------------------------------------===// // -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -40,19 +40,17 @@ using namespace ast_matchers; namespace { -const char * RunLoopBind = "NSRunLoopM"; -const char * RunLoopRunBind = "RunLoopRunM"; -const char * OtherMsgBind = "OtherMessageSentM"; -const char * AutoreleasePoolBind = "AutoreleasePoolM"; -const char * OtherStmtAutoreleasePoolBind = "OtherAutoreleasePoolM"; +const char *RunLoopBind = "NSRunLoopM"; +const char *RunLoopRunBind = "RunLoopRunM"; +const char *OtherMsgBind = "OtherMessageSentM"; +const char *AutoreleasePoolBind = "AutoreleasePoolM"; +const char *OtherStmtAutoreleasePoolBind = "OtherAutoreleasePoolM"; class RunLoopAutoreleaseLeakChecker : public Checker { public: - void checkASTCodeBody(const Decl *D, - AnalysisManager &AM, + void checkASTCodeBody(const Decl *D, AnalysisManager &AM, BugReporter &BR) const; - }; } // end anonymous namespace @@ -64,7 +62,8 @@ class RunLoopAutoreleaseLeakChecker : public Checker { /// but useful enough in this case. static bool seenBefore(const Stmt *Parent, const Stmt *A, const Stmt *B) { for (const Stmt *C : Parent->children()) { - if (!C) continue; + if (!C) + continue; if (C == A) return true; @@ -77,9 +76,7 @@ static bool seenBefore(const Stmt *Parent, const Stmt *A, const Stmt *B) { return false; } -static void emitDiagnostics(BoundNodes &Match, - const Decl *D, - BugReporter &BR, +static void emitDiagnostics(BoundNodes &Match, const Decl *D, BugReporter &BR, AnalysisManager &AM, const RunLoopAutoreleaseLeakChecker *Checker) { @@ -109,42 +106,41 @@ static void emitDiagnostics(BoundNodes &Match, if (HasAutoreleasePool && (OAP != AP)) return; - PathDiagnosticLocation Location = PathDiagnosticLocation::createBegin( - ME, BR.getSourceManager(), ADC); + PathDiagnosticLocation Location = + PathDiagnosticLocation::createBegin(ME, BR.getSourceManager(), ADC); SourceRange Range = ME->getSourceRange(); - BR.EmitBasicReport(ADC->getDecl(), Checker, - /*Name=*/"Memory leak inside autorelease pool", - /*BugCategory=*/"Memory", - /*Name=*/ - (Twine("Temporary objects allocated in the") + - " autorelease pool " + - (HasAutoreleasePool ? "" : "of last resort ") + - "followed by the launch of " + - (RL ? "main run loop " : "xpc_main ") + - "may never get released; consider moving them to a " - "separate autorelease pool") - .str(), - Location, Range); + BR.EmitBasicReport( + ADC->getDecl(), Checker, + /*Name=*/"Memory leak inside autorelease pool", + /*BugCategory=*/"Memory", + /*Name=*/ + (Twine("Temporary objects allocated in the") + " autorelease pool " + + (HasAutoreleasePool ? "" : "of last resort ") + + "followed by the launch of " + (RL ? "main run loop " : "xpc_main ") + + "may never get released; consider moving them to a " + "separate autorelease pool") + .str(), + Location, Range); } static StatementMatcher getRunLoopRunM(StatementMatcher Extra = anything()) { StatementMatcher MainRunLoopM = objcMessageExpr(hasSelector("mainRunLoop"), - hasReceiverType(asString("NSRunLoop")), - Extra) + hasReceiverType(asString("NSRunLoop")), Extra) .bind(RunLoopBind); - StatementMatcher MainRunLoopRunM = objcMessageExpr(hasSelector("run"), - hasReceiver(MainRunLoopM), - Extra).bind(RunLoopRunBind); + StatementMatcher MainRunLoopRunM = + objcMessageExpr(hasSelector("run"), hasReceiver(MainRunLoopM), Extra) + .bind(RunLoopRunBind); StatementMatcher XPCRunM = callExpr(callee(functionDecl(hasName("xpc_main")))).bind(RunLoopRunBind); return anyOf(MainRunLoopRunM, XPCRunM); } -static StatementMatcher getOtherMessageSentM(StatementMatcher Extra = anything()) { +static StatementMatcher +getOtherMessageSentM(StatementMatcher Extra = anything()) { return objcMessageExpr(unless(anyOf(equalsBoundNode(RunLoopBind), equalsBoundNode(RunLoopRunBind))), Extra) @@ -156,12 +152,12 @@ checkTempObjectsInSamePool(const Decl *D, AnalysisManager &AM, BugReporter &BR, const RunLoopAutoreleaseLeakChecker *Chkr) { StatementMatcher RunLoopRunM = getRunLoopRunM(); StatementMatcher OtherMessageSentM = getOtherMessageSentM( - hasAncestor(autoreleasePoolStmt().bind(OtherStmtAutoreleasePoolBind))); + hasAncestor(autoreleasePoolStmt().bind(OtherStmtAutoreleasePoolBind))); StatementMatcher RunLoopInAutorelease = - autoreleasePoolStmt( - hasDescendant(RunLoopRunM), - hasDescendant(OtherMessageSentM)).bind(AutoreleasePoolBind); + autoreleasePoolStmt(hasDescendant(RunLoopRunM), + hasDescendant(OtherMessageSentM)) + .bind(AutoreleasePoolBind); DeclarationMatcher GroupM = decl(hasDescendant(RunLoopInAutorelease)); @@ -179,22 +175,18 @@ checkTempObjectsInNoPool(const Decl *D, AnalysisManager &AM, BugReporter &BR, StatementMatcher RunLoopRunM = getRunLoopRunM(NoPoolM); StatementMatcher OtherMessageSentM = getOtherMessageSentM(NoPoolM); - DeclarationMatcher GroupM = functionDecl( - isMain(), - hasDescendant(RunLoopRunM), - hasDescendant(OtherMessageSentM) - ); + DeclarationMatcher GroupM = functionDecl(isMain(), hasDescendant(RunLoopRunM), + hasDescendant(OtherMessageSentM)); auto Matches = match(GroupM, *D, AM.getASTContext()); for (BoundNodes Match : Matches) emitDiagnostics(Match, D, BR, AM, Chkr); - } void RunLoopAutoreleaseLeakChecker::checkASTCodeBody(const Decl *D, - AnalysisManager &AM, - BugReporter &BR) const { + AnalysisManager &AM, + BugReporter &BR) const { checkTempObjectsInSamePool(D, AM, BR, this); checkTempObjectsInNoPool(D, AM, BR, this); } @@ -203,6 +195,7 @@ void ento::registerRunLoopAutoreleaseLeakChecker(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterRunLoopAutoreleaseLeakChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterRunLoopAutoreleaseLeakChecker( + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/STLAlgorithmModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/STLAlgorithmModeling.cpp index 788f2875863c3..a1fb8491a8b29 100644 --- a/clang/lib/StaticAnalyzer/Checkers/STLAlgorithmModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/STLAlgorithmModeling.cpp @@ -1,4 +1,5 @@ -//===-- STLAlgorithmModeling.cpp -----------------------------------*- C++ -*--// +//===-- STLAlgorithmModeling.cpp -----------------------------------*- C++ +//-*--// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,32 +31,32 @@ class STLAlgorithmModeling : public Checker { void Find(CheckerContext &C, const CallExpr *CE, unsigned paramNum) const; using FnCheck = bool (STLAlgorithmModeling::*)(CheckerContext &, - const CallExpr *) const; + const CallExpr *) const; const CallDescriptionMap Callbacks = { - {{{"std", "find"}, 3}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find"}, 4}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_if"}, 3}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_if"}, 4}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_if_not"}, 3}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_if_not"}, 4}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_first_of"}, 4}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_first_of"}, 5}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_first_of"}, 6}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_end"}, 4}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_end"}, 5}, &STLAlgorithmModeling::evalFind}, - {{{"std", "find_end"}, 6}, &STLAlgorithmModeling::evalFind}, - {{{"std", "lower_bound"}, 3}, &STLAlgorithmModeling::evalFind}, - {{{"std", "lower_bound"}, 4}, &STLAlgorithmModeling::evalFind}, - {{{"std", "upper_bound"}, 3}, &STLAlgorithmModeling::evalFind}, - {{{"std", "upper_bound"}, 4}, &STLAlgorithmModeling::evalFind}, - {{{"std", "search"}, 3}, &STLAlgorithmModeling::evalFind}, - {{{"std", "search"}, 4}, &STLAlgorithmModeling::evalFind}, - {{{"std", "search"}, 5}, &STLAlgorithmModeling::evalFind}, - {{{"std", "search"}, 6}, &STLAlgorithmModeling::evalFind}, - {{{"std", "search_n"}, 4}, &STLAlgorithmModeling::evalFind}, - {{{"std", "search_n"}, 5}, &STLAlgorithmModeling::evalFind}, - {{{"std", "search_n"}, 6}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find"}, 3}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find"}, 4}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_if"}, 3}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_if"}, 4}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_if_not"}, 3}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_if_not"}, 4}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_first_of"}, 4}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_first_of"}, 5}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_first_of"}, 6}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_end"}, 4}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_end"}, 5}, &STLAlgorithmModeling::evalFind}, + {{{"std", "find_end"}, 6}, &STLAlgorithmModeling::evalFind}, + {{{"std", "lower_bound"}, 3}, &STLAlgorithmModeling::evalFind}, + {{{"std", "lower_bound"}, 4}, &STLAlgorithmModeling::evalFind}, + {{{"std", "upper_bound"}, 3}, &STLAlgorithmModeling::evalFind}, + {{{"std", "upper_bound"}, 4}, &STLAlgorithmModeling::evalFind}, + {{{"std", "search"}, 3}, &STLAlgorithmModeling::evalFind}, + {{{"std", "search"}, 4}, &STLAlgorithmModeling::evalFind}, + {{{"std", "search"}, 5}, &STLAlgorithmModeling::evalFind}, + {{{"std", "search"}, 6}, &STLAlgorithmModeling::evalFind}, + {{{"std", "search_n"}, 4}, &STLAlgorithmModeling::evalFind}, + {{{"std", "search_n"}, 5}, &STLAlgorithmModeling::evalFind}, + {{{"std", "search_n"}, 6}, &STLAlgorithmModeling::evalFind}, }; public: @@ -127,10 +128,9 @@ void STLAlgorithmModeling::Find(CheckerContext &C, const CallExpr *CE, const auto *NewPos = getIteratorPosition(StateFound, RetVal); assert(NewPos && "Failed to create new iterator position."); - SVal GreaterOrEqual = SVB.evalBinOp(StateFound, BO_GE, - nonloc::SymbolVal(NewPos->getOffset()), - nonloc::SymbolVal(Pos->getOffset()), - SVB.getConditionType()); + SVal GreaterOrEqual = SVB.evalBinOp( + StateFound, BO_GE, nonloc::SymbolVal(NewPos->getOffset()), + nonloc::SymbolVal(Pos->getOffset()), SVB.getConditionType()); assert(isa(GreaterOrEqual) && "Symbol comparison must be a `DefinedSVal`"); StateFound = StateFound->assume(GreaterOrEqual.castAs(), true); @@ -149,10 +149,9 @@ void STLAlgorithmModeling::Find(CheckerContext &C, const CallExpr *CE, const auto *NewPos = getIteratorPosition(StateFound, RetVal); assert(NewPos && "Failed to create new iterator position."); - SVal Less = SVB.evalBinOp(StateFound, BO_LT, - nonloc::SymbolVal(NewPos->getOffset()), - nonloc::SymbolVal(Pos->getOffset()), - SVB.getConditionType()); + SVal Less = SVB.evalBinOp( + StateFound, BO_LT, nonloc::SymbolVal(NewPos->getOffset()), + nonloc::SymbolVal(Pos->getOffset()), SVB.getConditionType()); assert(isa(Less) && "Symbol comparison must be a `DefinedSVal`"); StateFound = StateFound->assume(Less.castAs(), true); @@ -171,11 +170,10 @@ void STLAlgorithmModeling::Find(CheckerContext &C, const CallExpr *CE, void ento::registerSTLAlgorithmModeling(CheckerManager &Mgr) { auto *Checker = Mgr.registerChecker(); Checker->AggressiveStdFindModeling = - Mgr.getAnalyzerOptions().getCheckerBooleanOption(Checker, - "AggressiveStdFindModeling"); + Mgr.getAnalyzerOptions().getCheckerBooleanOption( + Checker, "AggressiveStdFindModeling"); } bool ento::shouldRegisterSTLAlgorithmModeling(const CheckerManager &mgr) { return true; } - diff --git a/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp index 7cbe271dfbf93..a1d1e48004e98 100644 --- a/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp @@ -1,4 +1,5 @@ -//===-- SimpleStreamChecker.cpp -----------------------------------------*- C++ -*--// +//===-- SimpleStreamChecker.cpp -----------------------------------------*- C++ +//-*--// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -31,7 +32,7 @@ typedef SmallVector SymbolVector; struct StreamState { private: enum Kind { Opened, Closed } K; - StreamState(Kind InK) : K(InK) { } + StreamState(Kind InK) : K(InK) {} public: bool isOpened() const { return K == Opened; } @@ -40,18 +41,13 @@ struct StreamState { static StreamState getOpened() { return StreamState(Opened); } static StreamState getClosed() { return StreamState(Closed); } - bool operator==(const StreamState &X) const { - return K == X.K; - } - void Profile(llvm::FoldingSetNodeID &ID) const { - ID.AddInteger(K); - } + bool operator==(const StreamState &X) const { return K == X.K; } + void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(K); } }; -class SimpleStreamChecker : public Checker { +class SimpleStreamChecker + : public Checker { const CallDescription OpenFn{{"fopen"}, 2}; const CallDescription CloseFn{{"fclose"}, 1}; @@ -60,8 +56,7 @@ class SimpleStreamChecker : public Checker LeakedStreams, CheckerContext &C, @@ -79,9 +74,9 @@ class SimpleStreamChecker : public Checker LeakedStreams, } } -bool SimpleStreamChecker::guaranteedNotToCloseFile(const CallEvent &Call) const{ +bool SimpleStreamChecker::guaranteedNotToCloseFile( + const CallEvent &Call) const { // If it's not in a system header, assume it might close a file. if (!Call.isInSystemHeader()) return false; @@ -218,11 +214,9 @@ bool SimpleStreamChecker::guaranteedNotToCloseFile(const CallEvent &Call) const{ // If the pointer we are tracking escaped, do not track the symbol as // we cannot reason about it anymore. -ProgramStateRef -SimpleStreamChecker::checkPointerEscape(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind) const { +ProgramStateRef SimpleStreamChecker::checkPointerEscape( + ProgramStateRef State, const InvalidatedSymbols &Escaped, + const CallEvent *Call, PointerEscapeKind Kind) const { // If we know that the call cannot close a file, there is nothing to do. if (Kind == PSK_DirectEscapeOnCall && guaranteedNotToCloseFile(*Call)) { return State; diff --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp index ea09c43cc5ce9..6eae9eb3f5ee0 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp @@ -125,7 +125,8 @@ bool StackAddrEscapeChecker::isNotInCurrentFrame(const MemRegion *R, bool StackAddrEscapeChecker::isSemaphoreCaptured(const BlockDecl &B) const { if (!dispatch_semaphore_tII) - dispatch_semaphore_tII = &B.getASTContext().Idents.get("dispatch_semaphore_t"); + dispatch_semaphore_tII = + &B.getASTContext().Idents.get("dispatch_semaphore_t"); for (const auto &C : B.captures()) { const auto *T = C.getVariable()->getType()->getAs(); if (T && T->getDecl()->getIdentifier() == dispatch_semaphore_tII) diff --git a/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp index acf4e833095b7..8ee77ea941fee 100644 --- a/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp @@ -28,10 +28,9 @@ class TaintTesterChecker : public Checker> { public: void checkPostStmt(const Expr *E, CheckerContext &C) const; }; -} +} // namespace -void TaintTesterChecker::checkPostStmt(const Expr *E, - CheckerContext &C) const { +void TaintTesterChecker::checkPostStmt(const Expr *E, CheckerContext &C) const { ProgramStateRef State = C.getState(); if (!State) return; diff --git a/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp index 667b19f8120ea..5f04bf5eb9fbf 100644 --- a/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp @@ -172,7 +172,7 @@ void TestAfterDivZeroChecker::reportBug(SVal Val, CheckerContext &C) const { N); R->addVisitor(std::make_unique(Val.getAsSymbol(), - C.getStackFrame())); + C.getStackFrame())); C.emitReport(std::move(R)); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp index 2f316bd3b20db..9b22ef61b9427 100644 --- a/clang/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp @@ -10,9 +10,9 @@ // as it builds the ExplodedGraph. // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/AST/StmtObjC.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" @@ -23,15 +23,15 @@ using namespace clang; using namespace ento; namespace { -class TraversalDumper : public Checker< check::BranchCondition, - check::BeginFunction, - check::EndFunction > { +class TraversalDumper + : public Checker { public: void checkBranchCondition(const Stmt *Condition, CheckerContext &C) const; void checkBeginFunction(CheckerContext &C) const; void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; }; -} +} // namespace void TraversalDumper::checkBranchCondition(const Stmt *Condition, CheckerContext &C) const { @@ -71,13 +71,12 @@ bool ento::shouldRegisterTraversalDumper(const CheckerManager &mgr) { //------------------------------------------------------------------------------ namespace { -class CallDumper : public Checker< check::PreCall, - check::PostCall > { +class CallDumper : public Checker { public: void checkPreCall(const CallEvent &Call, CheckerContext &C) const; void checkPostCall(const CallEvent &Call, CheckerContext &C) const; }; -} +} // namespace void CallDumper::checkPreCall(const CallEvent &Call, CheckerContext &C) const { unsigned Indentation = 0; @@ -116,6 +115,4 @@ void ento::registerCallDumper(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterCallDumper(const CheckerManager &mgr) { - return true; -} +bool ento::shouldRegisterCallDumper(const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp index e2f8bd541c967..932dc4f8f0d1a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp @@ -18,13 +18,13 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Analysis/SelectorExtras.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" using namespace clang; using namespace ento; @@ -42,10 +42,9 @@ REGISTER_MAP_WITH_PROGRAMSTATE(NullImplicationMap, SymbolRef, SymbolRef) namespace { -class TrustNonnullChecker : public Checker { +class TrustNonnullChecker + : public Checker { // Do not try to iterate over symbols with higher complexity. static unsigned constexpr ComplexityThreshold = 10; Selector ObjectForKeyedSubscriptSel; @@ -62,8 +61,7 @@ class TrustNonnullChecker : public CheckercomputeComplexity() > ComplexityThreshold) @@ -139,7 +137,6 @@ class TrustNonnullChecker : public Checker @@ -193,7 +190,7 @@ class TrustNonnullChecker : public CheckergetIdentifier()->getName() == ClassName) return true; @@ -203,7 +200,6 @@ class TrustNonnullChecker : public CheckerisNonNull(AntecedentV).isConstrainedTrue()) - || (!Negated && InputState->isNull(AntecedentV).isConstrainedTrue())) { + if ((Negated && InputState->isNonNull(AntecedentV).isConstrainedTrue()) || + (!Negated && InputState->isNull(AntecedentV).isConstrainedTrue())) { SVal ConsequentS = SVB.makeSymbolVal(*Consequent); State = InputState->assume(ConsequentS.castAs(), Negated); if (!State) @@ -245,7 +241,7 @@ class TrustNonnullChecker : public Checker(Mgr.getASTContext()); diff --git a/clang/lib/StaticAnalyzer/Checkers/TrustReturnsNonnullChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TrustReturnsNonnullChecker.cpp index d80559c6a9152..8840799dffa7f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/TrustReturnsNonnullChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/TrustReturnsNonnullChecker.cpp @@ -41,7 +41,7 @@ class TrustReturnsNonnullChecker : public Checker { /// \returns Whether the method declaration has the attribute returns_nonnull. bool isNonNullPtr(const CallEvent &Call) const { QualType ExprRetType = Call.getResultType(); - const Decl *CallDeclaration = Call.getDecl(); + const Decl *CallDeclaration = Call.getDecl(); if (!ExprRetType->isAnyPointerType() || !CallDeclaration) return false; diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp index 2839ef0b6d2e6..3b6024aee1f85 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/Attr.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -26,7 +26,7 @@ using namespace ento; namespace { class UndefCapturedBlockVarChecker - : public Checker< check::PostStmt > { + : public Checker> { const BugType BT{this, "uninitialized variable captured by block"}; public: @@ -48,9 +48,8 @@ static const DeclRefExpr *FindBlockDeclRefExpr(const Stmt *S, return nullptr; } -void -UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE, - CheckerContext &C) const { +void UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE, + CheckerContext &C) const { if (!BE->getBlockDecl()->hasCaptures()) return; @@ -95,6 +94,7 @@ void ento::registerUndefCapturedBlockVarChecker(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterUndefCapturedBlockVarChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterUndefCapturedBlockVarChecker( + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp index 4b845bb3ded23..10fc173508318 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp @@ -25,8 +25,7 @@ using namespace clang; using namespace ento; namespace { -class UndefResultChecker - : public Checker< check::PostStmt > { +class UndefResultChecker : public Checker> { const BugType BT{this, "Result of operation is garbage or undefined"}; @@ -65,7 +64,7 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B, // Do not report assignments of uninitialized values inside swap functions. // This should allow to swap partially uninitialized structs if (const FunctionDecl *EnclosingFunctionDecl = - dyn_cast(C.getStackFrame()->getDecl())) + dyn_cast(C.getStackFrame()->getDecl())) if (C.getCalleeName(EnclosingFunctionDecl) == "swap") return; @@ -82,8 +81,7 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B, if (C.getSVal(B->getLHS()).isUndef()) { Ex = B->getLHS()->IgnoreParenCasts(); isLeft = true; - } - else if (C.getSVal(B->getRHS()).isUndef()) { + } else if (C.getSVal(B->getRHS()).isUndef()) { Ex = B->getRHS()->IgnoreParenCasts(); isLeft = false; } @@ -104,8 +102,7 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B, if (Ex) { report->addRange(Ex->getSourceRange()); bugreporter::trackExpressionValue(N, Ex, *report); - } - else + } else bugreporter::trackExpressionValue(N, B, *report); C.emitReport(std::move(report)); diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp index baa07fa66764e..7f10b7325c7e0 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclCXX.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -23,7 +23,7 @@ using namespace ento; namespace { class UndefinedArraySubscriptChecker - : public Checker< check::PreStmt > { + : public Checker> { const BugType BT{this, "Array subscript is undefined"}; public: @@ -31,9 +31,8 @@ class UndefinedArraySubscriptChecker }; } // end anonymous namespace -void -UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A, - CheckerContext &C) const { +void UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A, + CheckerContext &C) const { const Expr *Index = A->getIdx(); if (!C.getSVal(Index).isUndef()) return; @@ -59,6 +58,7 @@ void ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterUndefinedArraySubscriptChecker(const CheckerManager &mgr) { +bool ento::shouldRegisterUndefinedArraySubscriptChecker( + const CheckerManager &mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp index ddc6cc9e8202c..ec471f4a1fbf7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp @@ -21,15 +21,14 @@ using namespace clang; using namespace ento; namespace { -class UndefinedAssignmentChecker - : public Checker { +class UndefinedAssignmentChecker : public Checker { const BugType BT{this, "Assigned value is garbage or undefined"}; public: void checkBind(SVal location, SVal val, const Stmt *S, CheckerContext &C) const; }; -} +} // namespace void UndefinedAssignmentChecker::checkBind(SVal location, SVal val, const Stmt *StoreE, @@ -40,7 +39,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val, // Do not report assignments of uninitialized values inside swap functions. // This should allow to swap partially uninitialized structs if (const FunctionDecl *EnclosingFunctionDecl = - dyn_cast(C.getStackFrame()->getDecl())) + dyn_cast(C.getStackFrame()->getDecl())) if (C.getCalleeName(EnclosingFunctionDecl) == "swap") return; diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h index e35778e6480c5..699d5236e4f91 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h +++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h @@ -322,9 +322,8 @@ class FindUninitializedFields { /// Returns true if T is a primitive type. An object of a primitive type only /// needs to be analyzed as much as checking whether their value is undefined. inline bool isPrimitiveType(const QualType &T) { - return T->isBuiltinType() || T->isEnumeralType() || - T->isFunctionType() || T->isAtomicType() || - T->isVectorType() || T->isScalarType(); + return T->isBuiltinType() || T->isEnumeralType() || T->isFunctionType() || + T->isAtomicType() || T->isVectorType() || T->isScalarType(); } inline bool isDereferencableType(const QualType &T) { diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp index 6e1222fedad3e..46983eed3337f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -17,10 +17,10 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "UninitializedObject.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Driver/DriverDiagnostic.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" @@ -544,10 +544,9 @@ static bool hasUnguardedAccess(const FieldDecl *FD, ProgramStateRef State) { auto NoReturnFuncM = callExpr(callee(functionDecl(isNoReturn()))); - auto GuardM = - stmt(anyOf(ifStmt(), switchStmt(), conditionalOperator(), AssertLikeM, - NoReturnFuncM)) - .bind("guard"); + auto GuardM = stmt(anyOf(ifStmt(), switchStmt(), conditionalOperator(), + AssertLikeM, NoReturnFuncM)) + .bind("guard"); for (const CXXMethodDecl *M : Parent->methods()) { const Stmt *MethodBody = getMethodBody(M); @@ -604,10 +603,10 @@ void ento::registerUninitializedObjectChecker(CheckerManager &Mgr) { UninitObjCheckerOptions &ChOpts = Chk->Opts; ChOpts.IsPedantic = AnOpts.getCheckerBooleanOption(Chk, "Pedantic"); - ChOpts.ShouldConvertNotesToWarnings = AnOpts.getCheckerBooleanOption( - Chk, "NotesAsWarnings"); - ChOpts.CheckPointeeInitialization = AnOpts.getCheckerBooleanOption( - Chk, "CheckPointeeInitialization"); + ChOpts.ShouldConvertNotesToWarnings = + AnOpts.getCheckerBooleanOption(Chk, "NotesAsWarnings"); + ChOpts.CheckPointeeInitialization = + AnOpts.getCheckerBooleanOption(Chk, "CheckPointeeInitialization"); ChOpts.IgnoredRecordsWithFieldPattern = std::string(AnOpts.getCheckerStringOption(Chk, "IgnoreRecordsWithField")); ChOpts.IgnoreGuardedFields = @@ -615,9 +614,11 @@ void ento::registerUninitializedObjectChecker(CheckerManager &Mgr) { std::string ErrorMsg; if (!llvm::Regex(ChOpts.IgnoredRecordsWithFieldPattern).isValid(ErrorMsg)) - Mgr.reportInvalidCheckerOptionValue(Chk, "IgnoreRecordsWithField", + Mgr.reportInvalidCheckerOptionValue( + Chk, "IgnoreRecordsWithField", "a valid regex, building failed with error message " - "\"" + ErrorMsg + "\""); + "\"" + + ErrorMsg + "\""); } bool ento::shouldRegisterUninitializedObjectChecker(const CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp index 19f1ca2dc824c..69a15a5bba320 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp @@ -58,14 +58,14 @@ class UnixAPIMisuseChecker void CheckOpenAt(CheckerContext &C, const CallExpr *CE) const; void CheckPthreadOnce(CheckerContext &C, const CallExpr *CE) const; - void CheckOpenVariant(CheckerContext &C, - const CallExpr *CE, OpenVariant Variant) const; + void CheckOpenVariant(CheckerContext &C, const CallExpr *CE, + OpenVariant Variant) const; void ReportOpenBug(CheckerContext &C, ProgramStateRef State, const char *Msg, SourceRange SR) const; }; -class UnixAPIPortabilityChecker : public Checker< check::PreStmt > { +class UnixAPIPortabilityChecker : public Checker> { public: void checkPreStmt(const CallExpr *CE, CheckerContext &C) const; @@ -82,14 +82,10 @@ class UnixAPIPortabilityChecker : public Checker< check::PreStmt > { void CheckAllocaWithAlignZero(CheckerContext &C, const CallExpr *CE) const; void CheckVallocZero(CheckerContext &C, const CallExpr *CE) const; - bool ReportZeroByteAllocation(CheckerContext &C, - ProgramStateRef falseState, - const Expr *arg, - const char *fn_name) const; - void BasicAllocationCheck(CheckerContext &C, - const CallExpr *CE, - const unsigned numArgs, - const unsigned sizeArg, + bool ReportZeroByteAllocation(CheckerContext &C, ProgramStateRef falseState, + const Expr *arg, const char *fn_name) const; + void BasicAllocationCheck(CheckerContext &C, const CallExpr *CE, + const unsigned numArgs, const unsigned sizeArg, const char *fn) const; }; @@ -139,8 +135,7 @@ void UnixAPIMisuseChecker::checkPreStmt(const CallExpr *CE, CheckPthreadOnce(C, CE); } void UnixAPIMisuseChecker::ReportOpenBug(CheckerContext &C, - ProgramStateRef State, - const char *Msg, + ProgramStateRef State, const char *Msg, SourceRange SR) const { ExplodedNode *N = C.generateErrorNode(State); if (!N) @@ -201,12 +196,10 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C, SmallString<256> SBuf; llvm::raw_svector_ostream OS(SBuf); OS << "The " << CreateModeArgIndex + 1 - << llvm::getOrdinalSuffix(CreateModeArgIndex + 1) - << " argument to '" << VariantName << "' is not an integer"; + << llvm::getOrdinalSuffix(CreateModeArgIndex + 1) << " argument to '" + << VariantName << "' is not an integer"; - ReportOpenBug(C, state, - SBuf.c_str(), - Arg->getSourceRange()); + ReportOpenBug(C, state, SBuf.c_str(), Arg->getSourceRange()); return; } } else if (CE->getNumArgs() > MaxArgCount) { @@ -215,8 +208,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C, OS << "Call to '" << VariantName << "' with more than " << MaxArgCount << " arguments"; - ReportOpenBug(C, state, - SBuf.c_str(), + ReportOpenBug(C, state, SBuf.c_str(), CE->getArg(MaxArgCount)->getSourceRange()); return; } @@ -237,9 +229,8 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C, NonLoc ocreateFlag = C.getSValBuilder() .makeIntVal(*Val_O_CREAT, oflagsEx->getType()) .castAs(); - SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And, - oflags, ocreateFlag, - oflagsEx->getType()); + SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN( + state, BO_And, oflags, ocreateFlag, oflagsEx->getType()); if (maskedFlagsUC.isUnknownOrUndef()) return; DefinedSVal maskedFlags = maskedFlagsUC.castAs(); @@ -260,9 +251,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C, << CreateModeArgIndex + 1 << llvm::getOrdinalSuffix(CreateModeArgIndex + 1) << " argument when the 'O_CREAT' flag is set"; - ReportOpenBug(C, trueState, - SBuf.c_str(), - oflagsEx->getSourceRange()); + ReportOpenBug(C, trueState, SBuf.c_str(), oflagsEx->getSourceRange()); } } @@ -271,7 +260,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C, //===----------------------------------------------------------------------===// void UnixAPIMisuseChecker::CheckPthreadOnce(CheckerContext &C, - const CallExpr *CE) const { + const CallExpr *CE) const { // This is similar to 'CheckDispatchOnce' in the MacOSXAPIChecker. // They can possibly be refactored. @@ -298,7 +287,7 @@ void UnixAPIMisuseChecker::CheckPthreadOnce(CheckerContext &C, else os << " stack allocated memory"; os << " for the \"control\" value. Using such transient memory for " - "the control value is potentially dangerous."; + "the control value is potentially dangerous."; if (isa(R) && isa(R->getMemorySpace())) os << " Perhaps you intended to declare the variable as 'static'?"; @@ -313,17 +302,16 @@ void UnixAPIMisuseChecker::CheckPthreadOnce(CheckerContext &C, // with allocation size 0 //===----------------------------------------------------------------------===// -// FIXME: Eventually these should be rolled into the MallocChecker, but right now -// they're more basic and valuable for widespread use. +// FIXME: Eventually these should be rolled into the MallocChecker, but right +// now they're more basic and valuable for widespread use. // Returns true if we try to do a zero byte allocation, false otherwise. // Fills in trueState and falseState. -static bool IsZeroByteAllocation(ProgramStateRef state, - const SVal argVal, +static bool IsZeroByteAllocation(ProgramStateRef state, const SVal argVal, ProgramStateRef *trueState, ProgramStateRef *falseState) { std::tie(*trueState, *falseState) = - state->assume(argVal.castAs()); + state->assume(argVal.castAs()); return (*falseState && !*trueState); } @@ -332,10 +320,8 @@ static bool IsZeroByteAllocation(ProgramStateRef state, // will perform a zero byte allocation. // Returns false if an error occurred, true otherwise. bool UnixAPIPortabilityChecker::ReportZeroByteAllocation( - CheckerContext &C, - ProgramStateRef falseState, - const Expr *arg, - const char *fn_name) const { + CheckerContext &C, ProgramStateRef falseState, const Expr *arg, + const char *fn_name) const { ExplodedNode *N = C.generateErrorNode(falseState); if (!N) return false; @@ -375,7 +361,7 @@ void UnixAPIPortabilityChecker::BasicAllocationCheck(CheckerContext &C, // Is the value perfectly constrained to zero? if (IsZeroByteAllocation(state, argVal, &trueState, &falseState)) { - (void) ReportZeroByteAllocation(C, falseState, arg, fn); + (void)ReportZeroByteAllocation(C, falseState, arg, fn); return; } // Assume the value is non-zero going forward. @@ -441,8 +427,7 @@ void UnixAPIPortabilityChecker::CheckAllocaZero(CheckerContext &C, } void UnixAPIPortabilityChecker::CheckAllocaWithAlignZero( - CheckerContext &C, - const CallExpr *CE) const { + CheckerContext &C, const CallExpr *CE) const { BasicAllocationCheck(C, CE, 2, 0, "__builtin_alloca_with_align"); } @@ -479,7 +464,7 @@ void UnixAPIPortabilityChecker::checkPreStmt(const CallExpr *CE, else if (FName == "reallocf") CheckReallocfZero(C, CE); - else if (FName == "alloca" || FName == "__builtin_alloca") + else if (FName == "alloca" || FName == "__builtin_alloca") CheckAllocaZero(C, CE); else if (FName == "__builtin_alloca_with_align") diff --git a/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp index d24a124f5ffee..85ed19265ab2e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp @@ -12,10 +12,10 @@ // A similar flow-sensitive only check exists in Analysis/ReachableCode.cpp //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ParentMap.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/SourceManager.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -34,6 +34,7 @@ class UnreachableCodeChecker : public Checker { public: void checkEndAnalysis(ExplodedGraph &G, BugReporter &B, ExprEngine &Eng) const; + private: typedef llvm::SmallSet CFGBlocksSet; @@ -44,10 +45,9 @@ class UnreachableCodeChecker : public Checker { static bool isInvalidPath(const CFGBlock *CB, const ParentMap &PM); static inline bool isEmptyCFGBlock(const CFGBlock *CB); }; -} +} // namespace -void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G, - BugReporter &B, +void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G, BugReporter &B, ExprEngine &Eng) const { CFGBlocksSet reachable, visited; @@ -126,8 +126,8 @@ void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G, // such as llvm_unreachable. if (!CB->empty()) { bool foundUnreachable = false; - for (CFGBlock::const_iterator ci = CB->begin(), ce = CB->end(); - ci != ce; ++ci) { + for (CFGBlock::const_iterator ci = CB->begin(), ce = CB->end(); ci != ce; + ++ci) { if (std::optional S = (*ci).getAs()) if (const CallExpr *CE = dyn_cast(S->getStmt())) { if (CE->getBuiltinCallee() == Builtin::BI__builtin_unreachable || @@ -159,8 +159,7 @@ void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G, SL = DL.asLocation(); if (SR.isInvalid() || !SL.isValid()) continue; - } - else + } else continue; // Check if the SourceLocation is in a system header @@ -229,9 +228,9 @@ bool UnreachableCodeChecker::isInvalidPath(const CFGBlock *CB, // Get the predecessor block's terminator condition const Stmt *cond = pred->getTerminatorCondition(); - //assert(cond && "CFGBlock's predecessor has a terminator condition"); - // The previous assertion is invalid in some cases (eg do/while). Leaving - // reporting of these situations on at the moment to help triage these cases. + // assert(cond && "CFGBlock's predecessor has a terminator condition"); + // The previous assertion is invalid in some cases (eg do/while). Leaving + // reporting of these situations on at the moment to help triage these cases. if (!cond) return false; @@ -243,9 +242,9 @@ bool UnreachableCodeChecker::isInvalidPath(const CFGBlock *CB, // Returns true if the given CFGBlock is empty bool UnreachableCodeChecker::isEmptyCFGBlock(const CFGBlock *CB) { - return CB->getLabel() == nullptr // No labels - && CB->size() == 0 // No statements - && !CB->getTerminatorStmt(); // No terminator + return CB->getLabel() == nullptr // No labels + && CB->size() == 0 // No statements + && !CB->getTerminatorStmt(); // No terminator } void ento::registerUnreachableCodeChecker(CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp index 2d1b873abf73f..4e0af00b7554b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -404,9 +404,7 @@ void ento::registerValistBase(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterValistBase(const CheckerManager &mgr) { - return true; -} +bool ento::shouldRegisterValistBase(const CheckerManager &mgr) { return true; } #define REGISTER_CHECKER(name) \ void ento::register##name##Checker(CheckerManager &mgr) { \ @@ -416,7 +414,7 @@ bool ento::shouldRegisterValistBase(const CheckerManager &mgr) { mgr.getCurrentCheckerName(); \ } \ \ - bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) { \ + bool ento::shouldRegister##name##Checker(const CheckerManager &mgr) { \ return true; \ } diff --git a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp index cb73ac68edd1e..3a0a247a1464e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp @@ -24,17 +24,17 @@ // //===----------------------------------------------------------------------===// +#include "clang/AST/ParentMap.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/AST/ParentMap.h" #include using namespace clang; @@ -99,18 +99,8 @@ bool VforkChecker::isCallExplicitelyAllowed(const IdentifierInfo *II, CheckerContext &C) const { if (VforkAllowlist.empty()) { // According to manpage. - const char *ids[] = { - "_Exit", - "_exit", - "execl", - "execle", - "execlp", - "execv", - "execve", - "execvp", - "execvpe", - nullptr - }; + const char *ids[] = {"_Exit", "_exit", "execl", "execle", "execlp", + "execv", "execve", "execvp", "execvpe", nullptr}; ASTContext &AC = C.getASTContext(); for (const char **id = ids; *id; ++id) @@ -165,9 +155,8 @@ void VforkChecker::checkPostCall(const CallEvent &Call, // Get assigned memory region. MemRegionManager &M = C.getStoreManager().getRegionManager(); const MemRegion *LhsDeclReg = - LhsDecl - ? M.getVarRegion(LhsDecl, C.getLocationContext()) - : (const MemRegion *)VFORK_RESULT_NONE; + LhsDecl ? M.getVarRegion(LhsDecl, C.getLocationContext()) + : (const MemRegion *)VFORK_RESULT_NONE; // Parent branch gets nonzero return value (according to manpage). ProgramStateRef ParentState, ChildState; @@ -195,7 +184,7 @@ void VforkChecker::checkBind(SVal L, SVal V, const Stmt *S, return; const MemRegion *VforkLhs = - static_cast(State->get()); + static_cast(State->get()); const MemRegion *MR = L.getAsRegion(); // Child is allowed to modify only vfork's lhs. diff --git a/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp index 33a9a07f9d32d..7ac02c725ba88 100644 --- a/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp @@ -174,8 +174,7 @@ void VirtualCallChecker::registerCtorDtorCallInState(bool IsBeginFunction, // Enter a constructor, set the corresponding memregion be true. if (isa(MD)) { - auto ThiSVal = - State->getSVal(SVB.getCXXThis(MD, LCtx->getStackFrame())); + auto ThiSVal = State->getSVal(SVB.getCXXThis(MD, LCtx->getStackFrame())); const MemRegion *Reg = ThiSVal.getAsRegion(); if (IsBeginFunction) State = State->set(Reg, ObjectState::CtorCalled); @@ -188,8 +187,7 @@ void VirtualCallChecker::registerCtorDtorCallInState(bool IsBeginFunction, // Enter a Destructor, set the corresponding memregion be true. if (isa(MD)) { - auto ThiSVal = - State->getSVal(SVB.getCXXThis(MD, LCtx->getStackFrame())); + auto ThiSVal = State->getSVal(SVB.getCXXThis(MD, LCtx->getStackFrame())); const MemRegion *Reg = ThiSVal.getAsRegion(); if (IsBeginFunction) State = State->set(Reg, ObjectState::DtorCalled); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp index c753ed84a700c..71f61f6839a0c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoUncountedMembersChecker.cpp @@ -77,9 +77,9 @@ class NoUncountedMemberChecker if (auto *MemberCXXRD = MemberType->getPointeeCXXRecordDecl()) { // If we don't see the definition we just don't know. if (MemberCXXRD->hasDefinition()) { - std::optional isRCAble = isRefCountable(MemberCXXRD); - if (isRCAble && *isRCAble) - reportBug(Member, MemberType, MemberCXXRD, RD); + std::optional isRCAble = isRefCountable(MemberCXXRD); + if (isRCAble && *isRCAble) + reportBug(Member, MemberType, MemberCXXRD, RD); } } } @@ -152,7 +152,6 @@ void ento::registerNoUncountedMemberChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } -bool ento::shouldRegisterNoUncountedMemberChecker( - const CheckerManager &Mgr) { +bool ento::shouldRegisterNoUncountedMemberChecker(const CheckerManager &Mgr) { return true; } diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index defd83ec8e179..43d6e099a56bb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -53,8 +53,7 @@ hasPublicMethodInBase(const CXXBaseSpecifier *Base, const char *NameToMatch) { return hasPublicMethodInBaseClass(R, NameToMatch) ? R : nullptr; } -std::optional isRefCountable(const CXXRecordDecl* R) -{ +std::optional isRefCountable(const CXXRecordDecl *R) { assert(R); R = R->getDefinition(); @@ -143,8 +142,7 @@ bool isReturnValueRefCounted(const clang::FunctionDecl *F) { return false; } -std::optional isUncounted(const CXXRecordDecl* Class) -{ +std::optional isUncounted(const CXXRecordDecl *Class) { // Keep isRefCounted first as it's cheaper. if (isRefCounted(Class)) return false; @@ -156,8 +154,7 @@ std::optional isUncounted(const CXXRecordDecl* Class) return (*IsRefCountable); } -std::optional isUncountedPtr(const Type* T) -{ +std::optional isUncountedPtr(const Type *T) { assert(T); if (T->isPointerType() || T->isReferenceType()) { @@ -168,8 +165,7 @@ std::optional isUncountedPtr(const Type* T) return false; } -std::optional isGetterOfRefCounted(const CXXMethodDecl* M) -{ +std::optional isGetterOfRefCounted(const CXXMethodDecl *M) { assert(M); if (isa(M)) { diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h index e07cd31395747..3e71a162d3f29 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h @@ -35,18 +35,18 @@ hasPublicMethodInBase(const CXXBaseSpecifier *Base, const char *NameToMatch); /// \returns true if \p Class is ref-countable, false if not, std::nullopt if /// inconclusive. -std::optional isRefCountable(const clang::CXXRecordDecl* Class); +std::optional isRefCountable(const clang::CXXRecordDecl *Class); /// \returns true if \p Class is ref-counted, false if not. bool isRefCounted(const clang::CXXRecordDecl *Class); /// \returns true if \p Class is ref-countable AND not ref-counted, false if /// not, std::nullopt if inconclusive. -std::optional isUncounted(const clang::CXXRecordDecl* Class); +std::optional isUncounted(const clang::CXXRecordDecl *Class); /// \returns true if \p T is either a raw pointer or reference to an uncounted /// class, false if not, std::nullopt if inconclusive. -std::optional isUncountedPtr(const clang::Type* T); +std::optional isUncountedPtr(const clang::Type *T); /// \returns true if \p F creates ref-countable object from uncounted parameter, /// false if not. @@ -56,7 +56,7 @@ bool isCtorOfRefCounted(const clang::FunctionDecl *F); bool isReturnValueRefCounted(const clang::FunctionDecl *F); /// \returns true if \p M is getter of a ref-counted class, false if not. -std::optional isGetterOfRefCounted(const clang::CXXMethodDecl* Method); +std::optional isGetterOfRefCounted(const clang::CXXMethodDecl *Method); /// \returns true if \p F is a conversion between ref-countable or ref-counted /// pointer types. diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp index 8b41a949fd673..d9bc1cadf25fd 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp @@ -28,14 +28,13 @@ namespace { class UncountedCallArgsChecker : public Checker> { BugType Bug{this, - "Uncounted call argument for a raw pointer/reference parameter", - "WebKit coding guidelines"}; + "Uncounted call argument for a raw pointer/reference parameter", + "WebKit coding guidelines"}; mutable BugReporter *BR; TrivialFunctionAnalysis TFA; public: - void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR, BugReporter &BRArg) const { BR = &BRArg; @@ -70,7 +69,8 @@ class UncountedCallArgsChecker if (auto *F = CE->getDirectCallee()) { // Skip the first argument for overloaded member operators (e. g. lambda // or std::function call operator). - unsigned ArgIdx = isa(CE) && isa_and_nonnull(F); + unsigned ArgIdx = + isa(CE) && isa_and_nonnull(F); if (auto *MemberCallExpr = dyn_cast(CE)) { if (auto *MD = MemberCallExpr->getMethodDecl()) { diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp index a226a01ec0a57..54e3615618ea8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp @@ -60,10 +60,10 @@ class UncountedLambdaCapturesChecker if (C.capturesVariable()) { ValueDecl *CapturedVar = C.getCapturedVar(); if (auto *CapturedVarType = CapturedVar->getType().getTypePtrOrNull()) { - std::optional IsUncountedPtr = isUncountedPtr(CapturedVarType); - if (IsUncountedPtr && *IsUncountedPtr) { - reportBug(C, CapturedVar, CapturedVarType); - } + std::optional IsUncountedPtr = isUncountedPtr(CapturedVarType); + if (IsUncountedPtr && *IsUncountedPtr) { + reportBug(C, CapturedVar, CapturedVarType); + } } } } diff --git a/clang/lib/StaticAnalyzer/Core/APSIntType.cpp b/clang/lib/StaticAnalyzer/Core/APSIntType.cpp index 1185cdaa044a5..02c57b7b1ec64 100644 --- a/clang/lib/StaticAnalyzer/Core/APSIntType.cpp +++ b/clang/lib/StaticAnalyzer/Core/APSIntType.cpp @@ -16,8 +16,8 @@ APSIntType::testInRange(const llvm::APSInt &Value, bool AllowSignConversions) const { // Negative numbers cannot be losslessly converted to unsigned type. - if (IsUnsigned && !AllowSignConversions && - Value.isSigned() && Value.isNegative()) + if (IsUnsigned && !AllowSignConversions && Value.isSigned() && + Value.isNegative()) return RTR_Below; unsigned MinBits; diff --git a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp index f9750db7b5017..42aa80b08ece9 100644 --- a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp @@ -11,7 +11,7 @@ using namespace clang; using namespace ento; -void AnalysisManager::anchor() { } +void AnalysisManager::anchor() {} AnalysisManager::AnalysisManager(ASTContext &ASTCtx, Preprocessor &PP, const PathDiagnosticConsumers &PDC, @@ -23,25 +23,20 @@ AnalysisManager::AnalysisManager(ASTContext &ASTCtx, Preprocessor &PP, : AnaCtxMgr( ASTCtx, Options.UnoptimizedCFG, Options.ShouldIncludeImplicitDtorsInCFG, - /*addInitializers=*/true, - Options.ShouldIncludeTemporaryDtorsInCFG, + /*addInitializers=*/true, Options.ShouldIncludeTemporaryDtorsInCFG, Options.ShouldIncludeLifetimeInCFG, // Adding LoopExit elements to the CFG is a requirement for loop // unrolling. - Options.ShouldIncludeLoopExitInCFG || - Options.ShouldUnrollLoops, - Options.ShouldIncludeScopesInCFG, - Options.ShouldSynthesizeBodies, + Options.ShouldIncludeLoopExitInCFG || Options.ShouldUnrollLoops, + Options.ShouldIncludeScopesInCFG, Options.ShouldSynthesizeBodies, Options.ShouldConditionalizeStaticInitializers, /*addCXXNewAllocator=*/true, Options.ShouldIncludeRichConstructorsInCFG, Options.ShouldElideConstructors, - /*addVirtualBaseBranches=*/true, - injector), - Ctx(ASTCtx), PP(PP), LangOpts(ASTCtx.getLangOpts()), - PathConsumers(PDC), CreateStoreMgr(storemgr), - CreateConstraintMgr(constraintmgr), CheckerMgr(checkerMgr), - options(Options) { + /*addVirtualBaseBranches=*/true, injector), + Ctx(ASTCtx), PP(PP), LangOpts(ASTCtx.getLangOpts()), PathConsumers(PDC), + CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), + CheckerMgr(checkerMgr), options(Options) { AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd(); AnaCtxMgr.getCFGBuildOptions().OmitImplicitValueInitializers = true; AnaCtxMgr.getCFGBuildOptions().AddCXXDefaultInitExprInAggregates = diff --git a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index 86ef4a5686650..1c61a957234b7 100644 --- a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -14,8 +14,8 @@ #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" @@ -32,8 +32,7 @@ using namespace ento; using namespace llvm; void AnalyzerOptions::printFormattedEntry( - llvm::raw_ostream &Out, - std::pair EntryDescPair, + llvm::raw_ostream &Out, std::pair EntryDescPair, size_t InitialPad, size_t EntryWidth, size_t MinLineWidth) { llvm::formatted_raw_ostream FOut(Out); @@ -62,8 +61,7 @@ void AnalyzerOptions::printFormattedEntry( } } -ExplorationStrategyKind -AnalyzerOptions::getExplorationStrategy() const { +ExplorationStrategyKind AnalyzerOptions::getExplorationStrategy() const { auto K = llvm::StringSwitch>( ExplorationStrategy) @@ -105,9 +103,8 @@ IPAKind AnalyzerOptions::getIPAMode() const { return *K; } -bool -AnalyzerOptions::mayInlineCXXMemberFunction( - CXXInlineableMemberKind Param) const { +bool AnalyzerOptions::mayInlineCXXMemberFunction( + CXXInlineableMemberKind Param) const { if (getIPAMode() < IPAK_Inlining) return false; @@ -154,8 +151,8 @@ StringRef AnalyzerOptions::getCheckerStringOption(StringRef CheckerName, StringRef AnalyzerOptions::getCheckerStringOption(const ento::CheckerBase *C, StringRef OptionName, bool SearchInParents) const { - return getCheckerStringOption( - C->getTagDescription(), OptionName, SearchInParents); + return getCheckerStringOption(C->getTagDescription(), OptionName, + SearchInParents); } bool AnalyzerOptions::getCheckerBooleanOption(StringRef CheckerName, @@ -178,17 +175,17 @@ bool AnalyzerOptions::getCheckerBooleanOption(StringRef CheckerName, bool AnalyzerOptions::getCheckerBooleanOption(const ento::CheckerBase *C, StringRef OptionName, bool SearchInParents) const { - return getCheckerBooleanOption( - C->getTagDescription(), OptionName, SearchInParents); + return getCheckerBooleanOption(C->getTagDescription(), OptionName, + SearchInParents); } int AnalyzerOptions::getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName, bool SearchInParents) const { int Ret = 0; - bool HasFailed = getCheckerStringOption(CheckerName, OptionName, - SearchInParents) - .getAsInteger(0, Ret); + bool HasFailed = + getCheckerStringOption(CheckerName, OptionName, SearchInParents) + .getAsInteger(0, Ret); assert(!HasFailed && "This option should be numeric, and should've been validated by " "CheckerRegistry!"); @@ -199,6 +196,6 @@ int AnalyzerOptions::getCheckerIntegerOption(StringRef CheckerName, int AnalyzerOptions::getCheckerIntegerOption(const ento::CheckerBase *C, StringRef OptionName, bool SearchInParents) const { - return getCheckerIntegerOption( - C->getTagDescription(), OptionName, SearchInParents); + return getCheckerIntegerOption(C->getTagDescription(), OptionName, + SearchInParents); } diff --git a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp index 5c10e757244d7..17bd5cebd1eed 100644 --- a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp +++ b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp @@ -29,13 +29,13 @@ using namespace clang; using namespace ento; -void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T, +void CompoundValData::Profile(llvm::FoldingSetNodeID &ID, QualType T, llvm::ImmutableList L) { T.Profile(ID); ID.AddPointer(L.getInternalPointer()); } -void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID, +void LazyCompoundValData::Profile(llvm::FoldingSetNodeID &ID, const StoreRef &store, const TypedValueRegion *region) { ID.AddPointer(store.getStore()); @@ -54,15 +54,15 @@ using SValPair = std::pair; namespace llvm { -template<> struct FoldingSetTrait { - static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) { +template <> struct FoldingSetTrait { + static inline void Profile(const SValData &X, llvm::FoldingSetNodeID &ID) { X.first.Profile(ID); - ID.AddPointer( (void*) X.second); + ID.AddPointer((void *)X.second); } }; -template<> struct FoldingSetTrait { - static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) { +template <> struct FoldingSetTrait { + static inline void Profile(const SValPair &X, llvm::FoldingSetNodeID &ID) { X.first.Profile(ID); X.second.Profile(ID); } @@ -83,18 +83,18 @@ BasicValueFactory::~BasicValueFactory() { for (const auto &I : APSIntSet) I.getValue().~APSInt(); - delete (PersistentSValsTy*) PersistentSVals; - delete (PersistentSValPairsTy*) PersistentSValPairs; + delete (PersistentSValsTy *)PersistentSVals; + delete (PersistentSValPairsTy *)PersistentSValPairs; } -const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) { +const llvm::APSInt &BasicValueFactory::getValue(const llvm::APSInt &X) { llvm::FoldingSetNodeID ID; void *InsertPos; using FoldNodeTy = llvm::FoldingSetNodeWrapper; X.Profile(ID); - FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos); + FoldNodeTy *P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos); if (!P) { P = new (BPAlloc) FoldNodeTy(X); @@ -104,31 +104,31 @@ const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) { return *P; } -const llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X, +const llvm::APSInt &BasicValueFactory::getValue(const llvm::APInt &X, bool isUnsigned) { llvm::APSInt V(X, isUnsigned); return getValue(V); } -const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth, - bool isUnsigned) { +const llvm::APSInt &BasicValueFactory::getValue(uint64_t X, unsigned BitWidth, + bool isUnsigned) { llvm::APSInt V(BitWidth, isUnsigned); V = X; return getValue(V); } -const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) { +const llvm::APSInt &BasicValueFactory::getValue(uint64_t X, QualType T) { return getValue(getAPSIntType(T).getValue(X)); } -const CompoundValData* +const CompoundValData * BasicValueFactory::getCompoundValData(QualType T, llvm::ImmutableList Vals) { llvm::FoldingSetNodeID ID; CompoundValData::Profile(ID, T, Vals); void *InsertPos; - CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos); + CompoundValData *D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos); if (!D) { D = new (BPAlloc) CompoundValData(T, Vals); @@ -138,7 +138,7 @@ BasicValueFactory::getCompoundValData(QualType T, return D; } -const LazyCompoundValData* +const LazyCompoundValData * BasicValueFactory::getLazyCompoundValData(const StoreRef &store, const TypedValueRegion *region) { llvm::FoldingSetNodeID ID; @@ -146,7 +146,7 @@ BasicValueFactory::getLazyCompoundValData(const StoreRef &store, void *InsertPos; LazyCompoundValData *D = - LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos); + LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos); if (!D) { D = new (BPAlloc) LazyCompoundValData(store, region); @@ -242,108 +242,109 @@ const PointerToMemberData *BasicValueFactory::accumCXXBase( return getPointerToMemberData(ND, BaseSpecList); } -const llvm::APSInt* -BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op, - const llvm::APSInt& V1, const llvm::APSInt& V2) { +const llvm::APSInt *BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op, + const llvm::APSInt &V1, + const llvm::APSInt &V2) { switch (Op) { - default: - llvm_unreachable("Invalid Opcode."); + default: + llvm_unreachable("Invalid Opcode."); - case BO_Mul: - return &getValue( V1 * V2 ); + case BO_Mul: + return &getValue(V1 * V2); - case BO_Div: - if (V2 == 0) // Avoid division by zero - return nullptr; - return &getValue( V1 / V2 ); + case BO_Div: + if (V2 == 0) // Avoid division by zero + return nullptr; + return &getValue(V1 / V2); - case BO_Rem: - if (V2 == 0) // Avoid division by zero - return nullptr; - return &getValue( V1 % V2 ); + case BO_Rem: + if (V2 == 0) // Avoid division by zero + return nullptr; + return &getValue(V1 % V2); - case BO_Add: - return &getValue( V1 + V2 ); + case BO_Add: + return &getValue(V1 + V2); - case BO_Sub: - return &getValue( V1 - V2 ); + case BO_Sub: + return &getValue(V1 - V2); - case BO_Shl: { - // FIXME: This logic should probably go higher up, where we can - // test these conditions symbolically. + case BO_Shl: { + // FIXME: This logic should probably go higher up, where we can + // test these conditions symbolically. - if (V2.isNegative() || V2.getBitWidth() > 64) - return nullptr; + if (V2.isNegative() || V2.getBitWidth() > 64) + return nullptr; - uint64_t Amt = V2.getZExtValue(); + uint64_t Amt = V2.getZExtValue(); - if (Amt >= V1.getBitWidth()) - return nullptr; + if (Amt >= V1.getBitWidth()) + return nullptr; - return &getValue( V1.operator<<( (unsigned) Amt )); - } + return &getValue(V1.operator<<((unsigned)Amt)); + } - case BO_Shr: { - // FIXME: This logic should probably go higher up, where we can - // test these conditions symbolically. + case BO_Shr: { + // FIXME: This logic should probably go higher up, where we can + // test these conditions symbolically. - if (V2.isNegative() || V2.getBitWidth() > 64) - return nullptr; + if (V2.isNegative() || V2.getBitWidth() > 64) + return nullptr; - uint64_t Amt = V2.getZExtValue(); + uint64_t Amt = V2.getZExtValue(); - if (Amt >= V1.getBitWidth()) - return nullptr; + if (Amt >= V1.getBitWidth()) + return nullptr; - return &getValue( V1.operator>>( (unsigned) Amt )); - } + return &getValue(V1.operator>>((unsigned)Amt)); + } - case BO_LT: - return &getTruthValue( V1 < V2 ); + case BO_LT: + return &getTruthValue(V1 < V2); - case BO_GT: - return &getTruthValue( V1 > V2 ); + case BO_GT: + return &getTruthValue(V1 > V2); - case BO_LE: - return &getTruthValue( V1 <= V2 ); + case BO_LE: + return &getTruthValue(V1 <= V2); - case BO_GE: - return &getTruthValue( V1 >= V2 ); + case BO_GE: + return &getTruthValue(V1 >= V2); - case BO_EQ: - return &getTruthValue( V1 == V2 ); + case BO_EQ: + return &getTruthValue(V1 == V2); - case BO_NE: - return &getTruthValue( V1 != V2 ); + case BO_NE: + return &getTruthValue(V1 != V2); - // Note: LAnd, LOr, Comma are handled specially by higher-level logic. + // Note: LAnd, LOr, Comma are handled specially by higher-level logic. - case BO_And: - return &getValue( V1 & V2 ); + case BO_And: + return &getValue(V1 & V2); - case BO_Or: - return &getValue( V1 | V2 ); + case BO_Or: + return &getValue(V1 | V2); - case BO_Xor: - return &getValue( V1 ^ V2 ); + case BO_Xor: + return &getValue(V1 ^ V2); } } -const std::pair& -BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) { +const std::pair & +BasicValueFactory::getPersistentSValWithData(const SVal &V, uintptr_t Data) { // Lazily create the folding set. - if (!PersistentSVals) PersistentSVals = new PersistentSValsTy(); + if (!PersistentSVals) + PersistentSVals = new PersistentSValsTy(); llvm::FoldingSetNodeID ID; void *InsertPos; V.Profile(ID); - ID.AddPointer((void*) Data); + ID.AddPointer((void *)Data); - PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals); + PersistentSValsTy &Map = *((PersistentSValsTy *)PersistentSVals); using FoldNodeTy = llvm::FoldingSetNodeWrapper; - FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos); + FoldNodeTy *P = Map.FindNodeOrInsertPos(ID, InsertPos); if (!P) { P = new (BPAlloc) FoldNodeTy(std::make_pair(V, Data)); @@ -353,21 +354,22 @@ BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) { return P->getValue(); } -const std::pair& -BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) { +const std::pair & +BasicValueFactory::getPersistentSValPair(const SVal &V1, const SVal &V2) { // Lazily create the folding set. - if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy(); + if (!PersistentSValPairs) + PersistentSValPairs = new PersistentSValPairsTy(); llvm::FoldingSetNodeID ID; void *InsertPos; V1.Profile(ID); V2.Profile(ID); - PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs); + PersistentSValPairsTy &Map = *((PersistentSValPairsTy *)PersistentSValPairs); using FoldNodeTy = llvm::FoldingSetNodeWrapper; - FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos); + FoldNodeTy *P = Map.FindNodeOrInsertPos(ID, InsertPos); if (!P) { P = new (BPAlloc) FoldNodeTy(std::make_pair(V1, V2)); @@ -377,6 +379,6 @@ BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) { return P->getValue(); } -const SVal* BasicValueFactory::getPersistentSVal(SVal X) { +const SVal *BasicValueFactory::getPersistentSVal(SVal X) { return &getPersistentSValWithData(X, 0).first; } diff --git a/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp b/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp index e7ac6f1cfa001..04d6063104f6d 100644 --- a/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BlockCounter.cpp @@ -26,7 +26,7 @@ class CountKey { public: CountKey(const StackFrameContext *CS, unsigned ID) - : CallSite(CS), BlockID(ID) {} + : CallSite(CS), BlockID(ID) {} bool operator==(const CountKey &RHS) const { return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID); @@ -42,43 +42,41 @@ class CountKey { } }; -} +} // namespace typedef llvm::ImmutableMap CountMap; static inline CountMap GetMap(void *D) { - return CountMap(static_cast(D)); + return CountMap(static_cast(D)); } -static inline CountMap::Factory& GetFactory(void *F) { - return *static_cast(F); +static inline CountMap::Factory &GetFactory(void *F) { + return *static_cast(F); } unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite, - unsigned BlockID) const { + unsigned BlockID) const { CountMap M = GetMap(Data); - CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID)); + CountMap::data_type *T = M.lookup(CountKey(CallSite, BlockID)); return T ? *T : 0; } -BlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) { +BlockCounter::Factory::Factory(llvm::BumpPtrAllocator &Alloc) { F = new CountMap::Factory(Alloc); } BlockCounter::Factory::~Factory() { - delete static_cast(F); + delete static_cast(F); } -BlockCounter -BlockCounter::Factory::IncrementCount(BlockCounter BC, - const StackFrameContext *CallSite, - unsigned BlockID) { - return BlockCounter(GetFactory(F).add(GetMap(BC.Data), - CountKey(CallSite, BlockID), - BC.getNumVisited(CallSite, BlockID)+1).getRoot()); +BlockCounter BlockCounter::Factory::IncrementCount( + BlockCounter BC, const StackFrameContext *CallSite, unsigned BlockID) { + return BlockCounter(GetFactory(F) + .add(GetMap(BC.Data), CountKey(CallSite, BlockID), + BC.getNumVisited(CallSite, BlockID) + 1) + .getRoot()); } -BlockCounter -BlockCounter::Factory::GetEmptyCounter() { +BlockCounter BlockCounter::Factory::GetEmptyCounter() { return BlockCounter(GetFactory(F).getEmptyMap().getRoot()); } diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 3617fdd778e3c..5fe7d6f0dbc7c 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -285,7 +285,7 @@ class PathDiagnosticBuilder : public BugReporterContext { StackHintGenerator::~StackHintGenerator() = default; -std::string StackHintGeneratorForSymbol::getMessage(const ExplodedNode *N){ +std::string StackHintGeneratorForSymbol::getMessage(const ExplodedNode *N) { if (!N) return getMessageForSymbolNotFound(); @@ -337,7 +337,8 @@ std::string StackHintGeneratorForSymbol::getMessageForArg(const Expr *ArgE, ++ArgIndex; return (llvm::Twine(Msg) + " via " + std::to_string(ArgIndex) + - llvm::getOrdinalSuffix(ArgIndex) + " parameter").str(); + llvm::getOrdinalSuffix(ArgIndex) + " parameter") + .str(); } //===----------------------------------------------------------------------===// @@ -384,35 +385,34 @@ static void removeRedundantMsgs(PathPieces &path) { path.pop_front(); switch (piece->getKind()) { - case PathDiagnosticPiece::Call: - removeRedundantMsgs(cast(*piece).path); - break; - case PathDiagnosticPiece::Macro: - removeRedundantMsgs(cast(*piece).subPieces); + case PathDiagnosticPiece::Call: + removeRedundantMsgs(cast(*piece).path); + break; + case PathDiagnosticPiece::Macro: + removeRedundantMsgs(cast(*piece).subPieces); + break; + case PathDiagnosticPiece::Event: { + if (i == N - 1) break; - case PathDiagnosticPiece::Event: { - if (i == N-1) - break; - if (auto *nextEvent = - dyn_cast(path.front().get())) { - auto *event = cast(piece.get()); - // Check to see if we should keep one of the two pieces. If we - // come up with a preference, record which piece to keep, and consume - // another piece from the path. - if (auto *pieceToKeep = - eventsDescribeSameCondition(event, nextEvent)) { - piece = std::move(pieceToKeep == event ? piece : path.front()); - path.pop_front(); - ++i; - } + if (auto *nextEvent = + dyn_cast(path.front().get())) { + auto *event = cast(piece.get()); + // Check to see if we should keep one of the two pieces. If we + // come up with a preference, record which piece to keep, and consume + // another piece from the path. + if (auto *pieceToKeep = eventsDescribeSameCondition(event, nextEvent)) { + piece = std::move(pieceToKeep == event ? piece : path.front()); + path.pop_front(); + ++i; } - break; } - case PathDiagnosticPiece::ControlFlow: - case PathDiagnosticPiece::Note: - case PathDiagnosticPiece::PopUp: - break; + break; + } + case PathDiagnosticPiece::ControlFlow: + case PathDiagnosticPiece::Note: + case PathDiagnosticPiece::PopUp: + break; } path.push_back(std::move(piece)); } @@ -428,43 +428,43 @@ static bool removeUnneededCalls(const PathDiagnosticConstruct &C, bool containsSomethingInteresting = IsInteresting; const unsigned N = pieces.size(); - for (unsigned i = 0 ; i < N ; ++i) { + for (unsigned i = 0; i < N; ++i) { // Remove the front piece from the path. If it is still something we // want to keep once we are done, we will push it back on the end. auto piece = std::move(pieces.front()); pieces.pop_front(); switch (piece->getKind()) { - case PathDiagnosticPiece::Call: { - auto &call = cast(*piece); - // Check if the location context is interesting. - if (!removeUnneededCalls( - C, call.path, R, - R->isInteresting(C.getLocationContextFor(&call.path)))) - continue; + case PathDiagnosticPiece::Call: { + auto &call = cast(*piece); + // Check if the location context is interesting. + if (!removeUnneededCalls( + C, call.path, R, + R->isInteresting(C.getLocationContextFor(&call.path)))) + continue; - containsSomethingInteresting = true; - break; - } - case PathDiagnosticPiece::Macro: { - auto ¯o = cast(*piece); - if (!removeUnneededCalls(C, macro.subPieces, R, IsInteresting)) - continue; - containsSomethingInteresting = true; - break; - } - case PathDiagnosticPiece::Event: { - auto &event = cast(*piece); + containsSomethingInteresting = true; + break; + } + case PathDiagnosticPiece::Macro: { + auto ¯o = cast(*piece); + if (!removeUnneededCalls(C, macro.subPieces, R, IsInteresting)) + continue; + containsSomethingInteresting = true; + break; + } + case PathDiagnosticPiece::Event: { + auto &event = cast(*piece); - // We never throw away an event, but we do throw it away wholesale - // as part of a path if we throw the entire path away. - containsSomethingInteresting |= !event.isPrunable(); - break; - } - case PathDiagnosticPiece::ControlFlow: - case PathDiagnosticPiece::Note: - case PathDiagnosticPiece::PopUp: - break; + // We never throw away an event, but we do throw it away wholesale + // as part of a path if we throw the entire path away. + containsSomethingInteresting |= !event.isPrunable(); + break; + } + case PathDiagnosticPiece::ControlFlow: + case PathDiagnosticPiece::Note: + case PathDiagnosticPiece::PopUp: + break; } pieces.push_back(std::move(piece)); @@ -597,8 +597,7 @@ PathDiagnosticLocation PathDiagnosticBuilder::ExecutionContinues( if (Loc.asStmt()) os << "Execution continues on line " - << getSourceManager().getExpansionLineNumber(Loc.asLocation()) - << '.'; + << getSourceManager().getExpansionLineNumber(Loc.asLocation()) << '.'; else { os << "Execution jumps to the end of the "; const Decl *D = C.getCurrLocationContext()->getDecl(); @@ -648,55 +647,55 @@ getEnclosingStmtLocation(const Stmt *S, const LocationContext *LC, while (const Stmt *Parent = getEnclosingParent(S, LC->getParentMap())) { switch (Parent->getStmtClass()) { - case Stmt::BinaryOperatorClass: { - const auto *B = cast(Parent); - if (B->isLogicalOp()) - return PathDiagnosticLocation(allowNestedContexts ? B : S, SMgr, LC); - break; - } - case Stmt::CompoundStmtClass: - case Stmt::StmtExprClass: + case Stmt::BinaryOperatorClass: { + const auto *B = cast(Parent); + if (B->isLogicalOp()) + return PathDiagnosticLocation(allowNestedContexts ? B : S, SMgr, LC); + break; + } + case Stmt::CompoundStmtClass: + case Stmt::StmtExprClass: + return PathDiagnosticLocation(S, SMgr, LC); + case Stmt::ChooseExprClass: + // Similar to '?' if we are referring to condition, just have the edge + // point to the entire choose expression. + if (allowNestedContexts || cast(Parent)->getCond() == S) + return PathDiagnosticLocation(Parent, SMgr, LC); + else return PathDiagnosticLocation(S, SMgr, LC); - case Stmt::ChooseExprClass: - // Similar to '?' if we are referring to condition, just have the edge - // point to the entire choose expression. - if (allowNestedContexts || cast(Parent)->getCond() == S) - return PathDiagnosticLocation(Parent, SMgr, LC); - else - return PathDiagnosticLocation(S, SMgr, LC); - case Stmt::BinaryConditionalOperatorClass: - case Stmt::ConditionalOperatorClass: - // For '?', if we are referring to condition, just have the edge point - // to the entire '?' expression. - if (allowNestedContexts || - cast(Parent)->getCond() == S) - return PathDiagnosticLocation(Parent, SMgr, LC); - else - return PathDiagnosticLocation(S, SMgr, LC); - case Stmt::CXXForRangeStmtClass: - if (cast(Parent)->getBody() == S) - return PathDiagnosticLocation(S, SMgr, LC); - break; - case Stmt::DoStmtClass: - return PathDiagnosticLocation(S, SMgr, LC); - case Stmt::ForStmtClass: - if (cast(Parent)->getBody() == S) - return PathDiagnosticLocation(S, SMgr, LC); - break; - case Stmt::IfStmtClass: - if (cast(Parent)->getCond() != S) - return PathDiagnosticLocation(S, SMgr, LC); - break; - case Stmt::ObjCForCollectionStmtClass: - if (cast(Parent)->getBody() == S) - return PathDiagnosticLocation(S, SMgr, LC); - break; - case Stmt::WhileStmtClass: - if (cast(Parent)->getCond() != S) - return PathDiagnosticLocation(S, SMgr, LC); - break; - default: - break; + case Stmt::BinaryConditionalOperatorClass: + case Stmt::ConditionalOperatorClass: + // For '?', if we are referring to condition, just have the edge point + // to the entire '?' expression. + if (allowNestedContexts || + cast(Parent)->getCond() == S) + return PathDiagnosticLocation(Parent, SMgr, LC); + else + return PathDiagnosticLocation(S, SMgr, LC); + case Stmt::CXXForRangeStmtClass: + if (cast(Parent)->getBody() == S) + return PathDiagnosticLocation(S, SMgr, LC); + break; + case Stmt::DoStmtClass: + return PathDiagnosticLocation(S, SMgr, LC); + case Stmt::ForStmtClass: + if (cast(Parent)->getBody() == S) + return PathDiagnosticLocation(S, SMgr, LC); + break; + case Stmt::IfStmtClass: + if (cast(Parent)->getCond() != S) + return PathDiagnosticLocation(S, SMgr, LC); + break; + case Stmt::ObjCForCollectionStmtClass: + if (cast(Parent)->getBody() == S) + return PathDiagnosticLocation(S, SMgr, LC); + break; + case Stmt::WhileStmtClass: + if (cast(Parent)->getCond() != S) + return PathDiagnosticLocation(S, SMgr, LC); + break; + default: + break; } S = Parent; @@ -738,7 +737,7 @@ void PathDiagnosticBuilder::updateStackPiecesWithMessage( } static void CompactMacroExpandedPieces(PathPieces &path, - const SourceManager& SM); + const SourceManager &SM); PathDiagnosticPieceRef PathDiagnosticBuilder::generateDiagForSwitchOP( const PathDiagnosticConstruct &C, const CFGBlock *Dst, @@ -756,12 +755,12 @@ PathDiagnosticPieceRef PathDiagnosticBuilder::generateDiagForSwitchOP( switch (S->getStmtClass()) { default: os << "No cases match in the switch statement. " - "Control jumps to line " - << End.asLocation().getExpansionLineNumber(); + "Control jumps to line " + << End.asLocation().getExpansionLineNumber(); break; case Stmt::DefaultStmtClass: os << "Control jumps to the 'default' case at line " - << End.asLocation().getExpansionLineNumber(); + << End.asLocation().getExpansionLineNumber(); break; case Stmt::CaseStmtClass: { @@ -794,8 +793,7 @@ PathDiagnosticPieceRef PathDiagnosticBuilder::generateDiagForSwitchOP( os << "'Default' branch taken. "; End = ExecutionContinues(os, C); } - return std::make_shared(Start, End, - os.str()); + return std::make_shared(Start, End, os.str()); } PathDiagnosticPieceRef PathDiagnosticBuilder::generateDiagForGotoOP( @@ -822,14 +820,12 @@ PathDiagnosticPieceRef PathDiagnosticBuilder::generateDiagForBinaryOP( PathDiagnosticLocation Start, End; if (B->getOpcode() == BO_LAnd) { - os << "&&" - << "' is "; + os << "&&" << "' is "; if (*(Src->succ_begin() + 1) == Dst) { os << "false"; End = PathDiagnosticLocation(B->getLHS(), SM, C.getCurrLocationContext()); - Start = - PathDiagnosticLocation::createOperatorLoc(B, SM); + Start = PathDiagnosticLocation::createOperatorLoc(B, SM); } else { os << "true"; Start = @@ -838,8 +834,7 @@ PathDiagnosticPieceRef PathDiagnosticBuilder::generateDiagForBinaryOP( } } else { assert(B->getOpcode() == BO_LOr); - os << "||" - << "' is "; + os << "||" << "' is "; if (*(Src->succ_begin() + 1) == Dst) { os << "false"; @@ -849,12 +844,10 @@ PathDiagnosticPieceRef PathDiagnosticBuilder::generateDiagForBinaryOP( } else { os << "true"; End = PathDiagnosticLocation(B->getLHS(), SM, C.getCurrLocationContext()); - Start = - PathDiagnosticLocation::createOperatorLoc(B, SM); + Start = PathDiagnosticLocation::createOperatorLoc(B, SM); } } - return std::make_shared(Start, End, - os.str()); + return std::make_shared(Start, End, os.str()); } void PathDiagnosticBuilder::generateMinimalDiagForBlockEdge( @@ -1003,21 +996,21 @@ void PathDiagnosticBuilder::generateMinimalDiagForBlockEdge( static bool isLoop(const Stmt *Term) { switch (Term->getStmtClass()) { - case Stmt::ForStmtClass: - case Stmt::WhileStmtClass: - case Stmt::ObjCForCollectionStmtClass: - case Stmt::CXXForRangeStmtClass: - return true; - default: - // Note that we intentionally do not include do..while here. - return false; + case Stmt::ForStmtClass: + case Stmt::WhileStmtClass: + case Stmt::ObjCForCollectionStmtClass: + case Stmt::CXXForRangeStmtClass: + return true; + default: + // Note that we intentionally do not include do..while here. + return false; } } static bool isJumpToFalseBranch(const BlockEdge *BE) { const CFGBlock *Src = BE->getSrc(); assert(Src->succ_size() == 2); - return (*(Src->succ_begin()+1) == BE->getDst()); + return (*(Src->succ_begin() + 1) == BE->getDst()); } static bool isContainedByStmt(const ParentMap &PM, const Stmt *S, @@ -1047,39 +1040,38 @@ static const Stmt *getStmtBeforeCond(const ParentMap &PM, const Stmt *Term, static bool isInLoopBody(const ParentMap &PM, const Stmt *S, const Stmt *Term) { const Stmt *LoopBody = nullptr; switch (Term->getStmtClass()) { - case Stmt::CXXForRangeStmtClass: { - const auto *FR = cast(Term); - if (isContainedByStmt(PM, FR->getInc(), S)) - return true; - if (isContainedByStmt(PM, FR->getLoopVarStmt(), S)) - return true; - LoopBody = FR->getBody(); - break; - } - case Stmt::ForStmtClass: { - const auto *FS = cast(Term); - if (isContainedByStmt(PM, FS->getInc(), S)) - return true; - LoopBody = FS->getBody(); - break; - } - case Stmt::ObjCForCollectionStmtClass: { - const auto *FC = cast(Term); - LoopBody = FC->getBody(); - break; - } - case Stmt::WhileStmtClass: - LoopBody = cast(Term)->getBody(); - break; - default: - return false; + case Stmt::CXXForRangeStmtClass: { + const auto *FR = cast(Term); + if (isContainedByStmt(PM, FR->getInc(), S)) + return true; + if (isContainedByStmt(PM, FR->getLoopVarStmt(), S)) + return true; + LoopBody = FR->getBody(); + break; + } + case Stmt::ForStmtClass: { + const auto *FS = cast(Term); + if (isContainedByStmt(PM, FS->getInc(), S)) + return true; + LoopBody = FS->getBody(); + break; + } + case Stmt::ObjCForCollectionStmtClass: { + const auto *FC = cast(Term); + LoopBody = FC->getBody(); + break; + } + case Stmt::WhileStmtClass: + LoopBody = cast(Term)->getBody(); + break; + default: + return false; } return isContainedByStmt(PM, LoopBody, S); } /// Adds a sanitized control-flow diagnostic edge to a path. -static void addEdgeToPath(PathPieces &path, - PathDiagnosticLocation &PrevLoc, +static void addEdgeToPath(PathPieces &path, PathDiagnosticLocation &PrevLoc, PathDiagnosticLocation NewLoc) { if (!NewLoc.isValid()) return; @@ -1364,42 +1356,41 @@ static const Stmt *getStmtParent(const Stmt *S, const ParentMap &PM) { static bool isConditionForTerminator(const Stmt *S, const Stmt *Cond) { switch (S->getStmtClass()) { - case Stmt::BinaryOperatorClass: { - const auto *BO = cast(S); - if (!BO->isLogicalOp()) - return false; - return BO->getLHS() == Cond || BO->getRHS() == Cond; - } - case Stmt::IfStmtClass: - return cast(S)->getCond() == Cond; - case Stmt::ForStmtClass: - return cast(S)->getCond() == Cond; - case Stmt::WhileStmtClass: - return cast(S)->getCond() == Cond; - case Stmt::DoStmtClass: - return cast(S)->getCond() == Cond; - case Stmt::ChooseExprClass: - return cast(S)->getCond() == Cond; - case Stmt::IndirectGotoStmtClass: - return cast(S)->getTarget() == Cond; - case Stmt::SwitchStmtClass: - return cast(S)->getCond() == Cond; - case Stmt::BinaryConditionalOperatorClass: - return cast(S)->getCond() == Cond; - case Stmt::ConditionalOperatorClass: { - const auto *CO = cast(S); - return CO->getCond() == Cond || - CO->getLHS() == Cond || - CO->getRHS() == Cond; - } - case Stmt::ObjCForCollectionStmtClass: - return cast(S)->getElement() == Cond; - case Stmt::CXXForRangeStmtClass: { - const auto *FRS = cast(S); - return FRS->getCond() == Cond || FRS->getRangeInit() == Cond; - } - default: + case Stmt::BinaryOperatorClass: { + const auto *BO = cast(S); + if (!BO->isLogicalOp()) return false; + return BO->getLHS() == Cond || BO->getRHS() == Cond; + } + case Stmt::IfStmtClass: + return cast(S)->getCond() == Cond; + case Stmt::ForStmtClass: + return cast(S)->getCond() == Cond; + case Stmt::WhileStmtClass: + return cast(S)->getCond() == Cond; + case Stmt::DoStmtClass: + return cast(S)->getCond() == Cond; + case Stmt::ChooseExprClass: + return cast(S)->getCond() == Cond; + case Stmt::IndirectGotoStmtClass: + return cast(S)->getTarget() == Cond; + case Stmt::SwitchStmtClass: + return cast(S)->getCond() == Cond; + case Stmt::BinaryConditionalOperatorClass: + return cast(S)->getCond() == Cond; + case Stmt::ConditionalOperatorClass: { + const auto *CO = cast(S); + return CO->getCond() == Cond || CO->getLHS() == Cond || + CO->getRHS() == Cond; + } + case Stmt::ObjCForCollectionStmtClass: + return cast(S)->getElement() == Cond; + case Stmt::CXXForRangeStmtClass: { + const auto *FRS = cast(S); + return FRS->getCond() == Cond || FRS->getRangeInit() == Cond; + } + default: + return false; } } @@ -1508,12 +1499,13 @@ static void simplifySimpleBranches(PathPieces &pieces) { continue; const Stmt *s1Start = PieceI->getStartLocation().getStmtOrNull(); - const Stmt *s1End = PieceI->getEndLocation().getStmtOrNull(); + const Stmt *s1End = PieceI->getEndLocation().getStmtOrNull(); if (!s1Start || !s1End) continue; - PathPieces::iterator NextI = I; ++NextI; + PathPieces::iterator NextI = I; + ++NextI; if (NextI == E) break; @@ -1542,7 +1534,7 @@ static void simplifySimpleBranches(PathPieces &pieces) { continue; const Stmt *s2Start = PieceNextI->getStartLocation().getStmtOrNull(); - const Stmt *s2End = PieceNextI->getEndLocation().getStmtOrNull(); + const Stmt *s2End = PieceNextI->getEndLocation().getStmtOrNull(); if (!s2Start || !s2End || s1End != s2Start) continue; @@ -1621,7 +1613,7 @@ static std::optional getLengthOnSingleLine(const SourceManager &SM, /// - if the whole statement is large enough that having subexpression arrows /// might be helpful. static void removeContextCycles(PathPieces &Path, const SourceManager &SM) { - for (PathPieces::iterator I = Path.begin(), E = Path.end(); I != E; ) { + for (PathPieces::iterator I = Path.begin(), E = Path.end(); I != E;) { // Pattern match the current piece and its successor. const auto *PieceI = dyn_cast(I->get()); @@ -1631,9 +1623,10 @@ static void removeContextCycles(PathPieces &Path, const SourceManager &SM) { } const Stmt *s1Start = PieceI->getStartLocation().getStmtOrNull(); - const Stmt *s1End = PieceI->getEndLocation().getStmtOrNull(); + const Stmt *s1End = PieceI->getEndLocation().getStmtOrNull(); - PathPieces::iterator NextI = I; ++NextI; + PathPieces::iterator NextI = I; + ++NextI; if (NextI == E) break; @@ -1655,7 +1648,7 @@ static void removeContextCycles(PathPieces &Path, const SourceManager &SM) { } const Stmt *s2Start = PieceNextI->getStartLocation().getStmtOrNull(); - const Stmt *s2End = PieceNextI->getEndLocation().getStmtOrNull(); + const Stmt *s2End = PieceNextI->getEndLocation().getStmtOrNull(); if (s1Start && s2Start && s1Start == s2End && s2Start == s1End) { const size_t MAX_SHORT_LINE_LENGTH = 80; @@ -1699,7 +1692,7 @@ static void removePunyEdges(PathPieces &path, const SourceManager &SM, continue; const Stmt *start = PieceI->getStartLocation().getStmtOrNull(); - const Stmt *end = PieceI->getEndLocation().getStmtOrNull(); + const Stmt *end = PieceI->getEndLocation().getStmtOrNull(); if (!start || !end) continue; @@ -1745,7 +1738,8 @@ static void removeIdenticalEvents(PathPieces &path) { if (!PieceI) continue; - PathPieces::iterator NextI = I; ++NextI; + PathPieces::iterator NextI = I; + ++NextI; if (NextI == E) return; @@ -1769,7 +1763,7 @@ static bool optimizeEdges(const PathDiagnosticConstruct &C, PathPieces &path, const ParentMap &PM = LC->getParentMap(); const SourceManager &SM = C.getSourceManager(); - for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ) { + for (PathPieces::iterator I = path.begin(), E = path.end(); I != E;) { // Optimize subpaths. if (auto *CallI = dyn_cast(I->get())) { // Record the fact that a call has been optimized so we only do the @@ -1792,15 +1786,17 @@ static bool optimizeEdges(const PathDiagnosticConstruct &C, PathPieces &path, } const Stmt *s1Start = PieceI->getStartLocation().getStmtOrNull(); - const Stmt *s1End = PieceI->getEndLocation().getStmtOrNull(); + const Stmt *s1End = PieceI->getEndLocation().getStmtOrNull(); const Stmt *level1 = getStmtParent(s1Start, PM); const Stmt *level2 = getStmtParent(s1End, PM); - PathPieces::iterator NextI = I; ++NextI; + PathPieces::iterator NextI = I; + ++NextI; if (NextI == E) break; - const auto *PieceNextI = dyn_cast(NextI->get()); + const auto *PieceNextI = + dyn_cast(NextI->get()); if (!PieceNextI) { ++I; @@ -1808,7 +1804,7 @@ static bool optimizeEdges(const PathDiagnosticConstruct &C, PathPieces &path, } const Stmt *s2Start = PieceNextI->getStartLocation().getStmtOrNull(); - const Stmt *s2End = PieceNextI->getEndLocation().getStmtOrNull(); + const Stmt *s2End = PieceNextI->getEndLocation().getStmtOrNull(); const Stmt *level3 = getStmtParent(s2Start, PM); const Stmt *level4 = getStmtParent(s2End, PM); @@ -1867,8 +1863,7 @@ static bool optimizeEdges(const PathDiagnosticConstruct &C, PathPieces &path, // // This can eliminate edges where we dive into a subexpression // and then pop back out, etc. - else if (s1Start && s2End && - lexicalContains(PM, s2Start, s2End) && + else if (s1Start && s2End && lexicalContains(PM, s2Start, s2End) && !lexicalContains(PM, s1End, s1Start)) { removeEdge = true; } @@ -1880,8 +1875,7 @@ static bool optimizeEdges(const PathDiagnosticConstruct &C, PathPieces &path, // A.1 -> B // // These edges just look ugly and don't usually add anything. - else if (s1Start && s2End && - lexicalContains(PM, s1Start, s1End)) { + else if (s1Start && s2End && lexicalContains(PM, s1Start, s1End)) { SourceRange EdgeRange(PieceI->getEndLocation().asLocation(), PieceI->getStartLocation().asLocation()); if (!getLengthOnSingleLine(SM, EdgeRange)) @@ -2051,7 +2045,6 @@ PathDiagnosticBuilder::generate(const PathDiagnosticConsumer *PDC) const { PathDiagnosticLocation::createBegin(D, SM)); } - // Finally, prune the diagnostic path of uninteresting stuff. if (!Construct.PD->path.empty()) { if (R->shouldPrunePath() && Opts.ShouldPrunePaths) { @@ -2168,9 +2161,7 @@ void PathSensitiveBugReport::addVisitor( Callbacks.push_back(std::move(visitor)); } -void PathSensitiveBugReport::clearVisitors() { - Callbacks.clear(); -} +void PathSensitiveBugReport::clearVisitors() { Callbacks.clear(); } const Decl *PathSensitiveBugReport::getDeclWithIssue() const { const ExplodedNode *N = getErrorNode(); @@ -2181,7 +2172,7 @@ const Decl *PathSensitiveBugReport::getDeclWithIssue() const { return LC->getStackFrame()->getDecl(); } -void BasicBugReport::Profile(llvm::FoldingSetNodeID& hash) const { +void BasicBugReport::Profile(llvm::FoldingSetNodeID &hash) const { hash.AddInteger(static_cast(getKind())); hash.AddPointer(&BT); hash.AddString(Description); @@ -2235,17 +2226,17 @@ static void insertToInterestingnessMap( // and we wouldn't like to downplay their importance. switch (TKind) { - case bugreporter::TrackingKind::Thorough: - Result.first->getSecond() = bugreporter::TrackingKind::Thorough; - return; - case bugreporter::TrackingKind::Condition: - return; - } + case bugreporter::TrackingKind::Thorough: + Result.first->getSecond() = bugreporter::TrackingKind::Thorough; + return; + case bugreporter::TrackingKind::Condition: + return; + } - llvm_unreachable( - "BugReport::markInteresting currently can only handle 2 different " - "tracking kinds! Please define what tracking kind should this entitiy" - "have, if it was already marked as interesting with a different kind!"); + llvm_unreachable( + "BugReport::markInteresting currently can only handle 2 different " + "tracking kinds! Please define what tracking kind should this entitiy" + "have, if it was already marked as interesting with a different kind!"); } void PathSensitiveBugReport::markInteresting(SymbolRef sym, @@ -2319,11 +2310,11 @@ PathSensitiveBugReport::getInterestingnessKind(SVal V) const { // If either is marked with throrough tracking, return that, we wouldn't like // to downplay a note's importance by 'only' mentioning it as a condition. - switch(*RKind) { - case bugreporter::TrackingKind::Thorough: - return RKind; - case bugreporter::TrackingKind::Condition: - return SKind; + switch (*RKind) { + case bugreporter::TrackingKind::Thorough: + return RKind; + case bugreporter::TrackingKind::Condition: + return SKind; } llvm_unreachable( @@ -2372,7 +2363,7 @@ bool PathSensitiveBugReport::isInteresting(const MemRegion *R) const { return getInterestingnessKind(R).has_value(); } -bool PathSensitiveBugReport::isInteresting(const LocationContext *LC) const { +bool PathSensitiveBugReport::isInteresting(const LocationContext *LC) const { if (!LC) return false; return InterestingLocationContexts.count(LC); @@ -2396,28 +2387,26 @@ const Stmt *PathSensitiveBugReport::getStmt() const { return S; } -ArrayRef -PathSensitiveBugReport::getRanges() const { +ArrayRef PathSensitiveBugReport::getRanges() const { // If no custom ranges, add the range of the statement corresponding to // the error node. if (Ranges.empty() && isa_and_nonnull(getStmt())) - return ErrorNodeRange; + return ErrorNodeRange; return Ranges; } -PathDiagnosticLocation -PathSensitiveBugReport::getLocation() const { +PathDiagnosticLocation PathSensitiveBugReport::getLocation() const { assert(ErrorNode && "Cannot create a location with a null node."); const Stmt *S = ErrorNode->getStmtForDiagnostics(); - ProgramPoint P = ErrorNode->getLocation(); + ProgramPoint P = ErrorNode->getLocation(); const LocationContext *LC = P.getLocationContext(); SourceManager &SM = ErrorNode->getState()->getStateManager().getContext().getSourceManager(); if (!S) { // If this is an implicit call, return the implicit call point location. - if (std::optional PIE = P.getAs()) + if (std::optional PIE = P.getAs()) return PathDiagnosticLocation(PIE->getLocation(), SM); if (auto FE = P.getAs()) { if (const ReturnStmt *RS = FE->getStmt()) @@ -2518,8 +2507,9 @@ class BugPathGetter { /// Assign each node with its distance from the root. PriorityMapTy PriorityMap; - /// Since the getErrorNode() or BugReport refers to the original ExplodedGraph, - /// we need to pair it to the error node of the constructed trimmed graph. + /// Since the getErrorNode() or BugReport refers to the original + /// ExplodedGraph, we need to pair it to the error node of the constructed + /// trimmed graph. using ReportNewNodePair = std::pair; SmallVector ReportNodes; @@ -2527,8 +2517,7 @@ class BugPathGetter { BugPathInfo CurrentBugPath; /// A helper class for sorting ExplodedNodes by priority. - template - class PriorityCompare { + template class PriorityCompare { const PriorityMapTy &PriorityMap; public: @@ -2544,8 +2533,7 @@ class BugPathGetter { if (RI == E) return !Descending; - return Descending ? LI->second > RI->second - : LI->second < RI->second; + return Descending ? LI->second > RI->second : LI->second < RI->second; } bool operator()(const ReportNewNodePair &LHS, @@ -2645,9 +2633,9 @@ BugPathInfo *BugPathGetter::getNextBugPath() { while (true) { // Create the equivalent node in the new graph with the same state // and location. - ExplodedNode *NewN = GNew->createUncachedNode( - OrigN->getLocation(), OrigN->getState(), - OrigN->getID(), OrigN->isSink()); + ExplodedNode *NewN = + GNew->createUncachedNode(OrigN->getLocation(), OrigN->getState(), + OrigN->getID(), OrigN->isSink()); // Link up the new node with the previous node. if (Succ) @@ -2677,7 +2665,7 @@ BugPathInfo *BugPathGetter::getNextBugPath() { /// CompactMacroExpandedPieces - This function postprocesses a PathDiagnostic /// object and collapses PathDiagosticPieces that are expanded by macros. static void CompactMacroExpandedPieces(PathPieces &path, - const SourceManager& SM) { + const SourceManager &SM) { using MacroStackTy = std::vector< std::pair, SourceLocation>>; @@ -2686,8 +2674,8 @@ static void CompactMacroExpandedPieces(PathPieces &path, MacroStackTy MacroStack; PiecesTy Pieces; - for (PathPieces::const_iterator I = path.begin(), E = path.end(); - I != E; ++I) { + for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E; + ++I) { const auto &piece = *I; // Recursively compact calls. @@ -2700,9 +2688,8 @@ static void CompactMacroExpandedPieces(PathPieces &path, // Determine the instantiation location, which is the location we group // related PathDiagnosticPieces. - SourceLocation InstantiationLoc = Loc.isMacroID() ? - SM.getExpansionLoc(Loc) : - SourceLocation(); + SourceLocation InstantiationLoc = + Loc.isMacroID() ? SM.getExpansionLoc(Loc) : SourceLocation(); if (Loc.isFileID()) { MacroStack.clear(); @@ -2722,9 +2709,9 @@ static void CompactMacroExpandedPieces(PathPieces &path, // or are part of an old one? std::shared_ptr MacroGroup; - SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ? - SM.getExpansionLoc(Loc) : - SourceLocation(); + SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() + ? SM.getExpansionLoc(Loc) + : SourceLocation(); // Walk the entire macro stack. while (!MacroStack.empty()) { @@ -2917,7 +2904,7 @@ void BugReporter::emitReport(std::unique_ptr R) { // Lookup the equivance class. If there isn't one, create it. void *InsertPos; - BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos); + BugReportEquivClass *EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos); if (!EQ) { EQ = new BugReportEquivClass(std::move(R)); @@ -2971,7 +2958,7 @@ BugReport *PathSensitiveBugReporter::findReportInEquivalenceClass( // post-dominated by a sink, simply add all the nodes in the equivalence class // to 'Nodes'. Any of the reports will serve as a "representative" report. assert(EQ.getReports().size() > 0); - const BugType& BT = EQ.getReports()[0]->getBugType(); + const BugType &BT = EQ.getReports()[0]->getBugType(); if (!BT.isSuppressOnSink()) { BugReport *R = EQ.getReports()[0].get(); for (auto &J : EQ.getReports()) { @@ -2991,7 +2978,7 @@ BugReport *PathSensitiveBugReporter::findReportInEquivalenceClass( // stack for very long paths. BugReport *exampleReport = nullptr; - for (const auto &I: EQ.getReports()) { + for (const auto &I : EQ.getReports()) { auto *R = dyn_cast(I.get()); if (!R) continue; @@ -2999,7 +2986,7 @@ BugReport *PathSensitiveBugReporter::findReportInEquivalenceClass( const ExplodedNode *errorNode = R->getErrorNode(); if (errorNode->isSink()) { llvm_unreachable( - "BugType::isSuppressSink() should not be 'true' for sink end nodes"); + "BugType::isSuppressSink() should not be 'true' for sink end nodes"); } // No successors? By definition this nodes isn't post-dominated by a sink. if (errorNode->succ_empty()) { @@ -3069,8 +3056,8 @@ BugReport *PathSensitiveBugReporter::findReportInEquivalenceClass( return exampleReport; } -void BugReporter::FlushReport(BugReportEquivClass& EQ) { - SmallVector bugReports; +void BugReporter::FlushReport(BugReportEquivClass &EQ) { + SmallVector bugReports; BugReport *report = findReportInEquivalenceClass(EQ, bugReports); if (!report) return; @@ -3082,7 +3069,7 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { return; } - ArrayRef Consumers = getPathDiagnosticConsumers(); + ArrayRef Consumers = getPathDiagnosticConsumers(); std::unique_ptr Diagnostics = generateDiagnosticForConsumerMap(report, Consumers, bugReports); @@ -3095,7 +3082,7 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { if (PD->path.empty()) { PathDiagnosticLocation L = report->getLocation(); auto piece = std::make_unique( - L, report->getDescription()); + L, report->getDescription()); for (SourceRange Range : report->getRanges()) piece->addRange(Range); PD->setEndOfPath(std::move(piece)); @@ -3108,8 +3095,8 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { for (const auto &I : llvm::reverse(report->getNotes())) { PathDiagnosticNotePiece *Piece = I.get(); auto ConvertedPiece = std::make_shared( - Piece->getLocation(), Piece->getString()); - for (const auto &R: Piece->getRanges()) + Piece->getLocation(), Piece->getString()); + for (const auto &R : Piece->getRanges()) ConvertedPiece->addRange(R); Pieces.push_front(std::move(ConvertedPiece)); @@ -3129,11 +3116,12 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { /// Insert all lines participating in the function signature \p Signature /// into \p ExecutedLines. -static void populateExecutedLinesWithFunctionSignature( - const Decl *Signature, const SourceManager &SM, - FilesToLineNumsMap &ExecutedLines) { +static void +populateExecutedLinesWithFunctionSignature(const Decl *Signature, + const SourceManager &SM, + FilesToLineNumsMap &ExecutedLines) { SourceRange SignatureSourceRange; - const Stmt* Body = Signature->getBody(); + const Stmt *Body = Signature->getBody(); if (const auto FD = dyn_cast(Signature)) { SignatureSourceRange = FD->getSourceRange(); } else if (const auto OD = dyn_cast(Signature)) { @@ -3142,8 +3130,8 @@ static void populateExecutedLinesWithFunctionSignature( return; } SourceLocation Start = SignatureSourceRange.getBegin(); - SourceLocation End = Body ? Body->getSourceRange().getBegin() - : SignatureSourceRange.getEnd(); + SourceLocation End = + Body ? Body->getSourceRange().getBegin() : SignatureSourceRange.getEnd(); if (!Start.isValid() || !End.isValid()) return; unsigned StartLine = SM.getExpansionLineNumber(Start); @@ -3154,9 +3142,9 @@ static void populateExecutedLinesWithFunctionSignature( ExecutedLines[FID].insert(Line); } -static void populateExecutedLinesWithStmt( - const Stmt *S, const SourceManager &SM, - FilesToLineNumsMap &ExecutedLines) { +static void populateExecutedLinesWithStmt(const Stmt *S, + const SourceManager &SM, + FilesToLineNumsMap &ExecutedLines) { SourceLocation Loc = S->getSourceRange().getBegin(); if (!Loc.isValid()) return; @@ -3179,7 +3167,7 @@ findExecutedLines(const SourceManager &SM, const ExplodedNode *N) { populateExecutedLinesWithFunctionSignature(D, SM, *ExecutedLines); } else if (auto CE = N->getLocationAs()) { // Inlined function: show signature. - const Decl* D = CE->getCalleeContext()->getDecl(); + const Decl *D = CE->getCalleeContext()->getDecl(); populateExecutedLinesWithFunctionSignature(D, SM, *ExecutedLines); } else if (const Stmt *S = N->getStmtForDiagnostics()) { populateExecutedLinesWithStmt(S, SM, *ExecutedLines); @@ -3258,7 +3246,7 @@ static void resetDiagnosticLocationToMainFile(PathDiagnostic &PD) { CP = getFirstStackedCallToHeaderFile(CP, SMgr); if (CP) { // Mark the piece. - CP->setAsLastInMainSourceFile(); + CP->setAsLastInMainSourceFile(); // Update the path diagnostic message. const auto *ND = dyn_cast(CP->getCallee()); @@ -3278,8 +3266,6 @@ static void resetDiagnosticLocationToMainFile(PathDiagnostic &PD) { } } - - std::unique_ptr PathSensitiveBugReporter::generateDiagnosticForConsumerMap( BugReport *exampleReport, ArrayRef consumers, @@ -3301,8 +3287,8 @@ PathSensitiveBugReporter::generateDiagnosticForConsumerMap( ArrayRef convertedArrayOfReports( reinterpret_cast(&*bugReports.begin()), reinterpret_cast(&*bugReports.end())); - std::unique_ptr Out = generatePathDiagnostics( - consumers, convertedArrayOfReports); + std::unique_ptr Out = + generatePathDiagnostics(consumers, convertedArrayOfReports); if (Out->empty()) return Out; @@ -3330,9 +3316,9 @@ void BugReporter::EmitBasicReport(const Decl *DeclWithIssue, } void BugReporter::EmitBasicReport(const Decl *DeclWithIssue, - CheckerNameRef CheckName, - StringRef name, StringRef category, - StringRef str, PathDiagnosticLocation Loc, + CheckerNameRef CheckName, StringRef name, + StringRef category, StringRef str, + PathDiagnosticLocation Loc, ArrayRef Ranges, ArrayRef Fixits) { // 'BT' is owned by BugReporter. @@ -3349,8 +3335,8 @@ void BugReporter::EmitBasicReport(const Decl *DeclWithIssue, BugType *BugReporter::getBugTypeForName(CheckerNameRef CheckName, StringRef name, StringRef category) { SmallString<136> fullDesc; - llvm::raw_svector_ostream(fullDesc) << CheckName.getName() << ":" << name - << ":" << category; + llvm::raw_svector_ostream(fullDesc) + << CheckName.getName() << ":" << name << ":" << category; std::unique_ptr &BT = StrBugTypes[fullDesc]; if (!BT) BT = std::make_unique(CheckName, name, category); diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 2f9965036b9ef..77a9e0fec2803 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -227,8 +227,8 @@ static bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal, return false; return LLCV->getRegion() == RLCV->getRegion() && - LLCV->getStore() == LeftNode->getState()->getStore() && - RLCV->getStore() == RightNode->getState()->getStore(); + LLCV->getStore() == LeftNode->getState()->getStore() && + RLCV->getStore() == RightNode->getState()->getStore(); } static std::optional getSValForVar(const Expr *CondVarExpr, @@ -289,18 +289,15 @@ static bool isInterestingExpr(const Expr *E, const ExplodedNode *N, } /// \return name of the macro inside the location \p Loc. -static StringRef getMacroName(SourceLocation Loc, - BugReporterContext &BRC) { - return Lexer::getImmediateMacroName( - Loc, - BRC.getSourceManager(), - BRC.getASTContext().getLangOpts()); +static StringRef getMacroName(SourceLocation Loc, BugReporterContext &BRC) { + return Lexer::getImmediateMacroName(Loc, BRC.getSourceManager(), + BRC.getASTContext().getLangOpts()); } /// \return Whether given spelling location corresponds to an expansion /// of a function-like macro. static bool isFunctionMacroExpansion(SourceLocation Loc, - const SourceManager &SM) { + const SourceManager &SM) { if (!Loc.isMacroID()) return false; while (SM.isMacroArgExpansion(Loc)) @@ -346,9 +343,9 @@ static bool wasRegionOfInterestModifiedAt(const SubRegion *RegionOfInterest, // Implementation of BugReporterVisitor. //===----------------------------------------------------------------------===// -PathDiagnosticPieceRef BugReporterVisitor::getEndPath(BugReporterContext &, - const ExplodedNode *, - PathSensitiveBugReport &) { +PathDiagnosticPieceRef +BugReporterVisitor::getEndPath(BugReporterContext &, const ExplodedNode *, + PathSensitiveBugReport &) { return nullptr; } @@ -931,10 +928,11 @@ class MacroNullReturnSuppressionVisitor final : public BugReporterVisitor { return nullptr; } - static void addMacroVisitorIfNecessary( - const ExplodedNode *N, const MemRegion *R, - bool EnableNullFPSuppression, PathSensitiveBugReport &BR, - const SVal V) { + static void addMacroVisitorIfNecessary(const ExplodedNode *N, + const MemRegion *R, + bool EnableNullFPSuppression, + PathSensitiveBugReport &BR, + const SVal V) { AnalyzerOptions &Options = N->getState()->getAnalysisManager().options; if (EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths && isa(V)) @@ -942,7 +940,7 @@ class MacroNullReturnSuppressionVisitor final : public BugReporterVisitor { V); } - void* getTag() const { + void *getTag() const { static int Tag = 0; return static_cast(&Tag); } @@ -991,15 +989,11 @@ namespace { /// interesting value comes from an inlined function call. class ReturnVisitor : public TrackingBugReporterVisitor { const StackFrameContext *CalleeSFC; - enum { - Initial, - MaybeUnsuppress, - Satisfied - } Mode = Initial; + enum { Initial, MaybeUnsuppress, Satisfied } Mode = Initial; bool EnableNullFPSuppression; bool ShouldInvalidate = true; - AnalyzerOptions& Options; + AnalyzerOptions &Options; bugreporter::TrackingKind TKind; public: @@ -1304,7 +1298,8 @@ static bool isObjCPointer(const ValueDecl *D) { return D->getType()->isObjCObjectPointerType(); } -/// Show diagnostics for initializing or declaring a region \p R with a bad value. +/// Show diagnostics for initializing or declaring a region \p R with a bad +/// value. static void showBRDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI) { const bool HasPrefix = SI.Dest->canPrintPretty(); @@ -1658,14 +1653,15 @@ PathDiagnosticPieceRef StoreSiteFinder::VisitNode(const ExplodedNode *Succ, ProgramStateManager &StateMgr = BRC.getStateManager(); CallEventManager &CallMgr = StateMgr.getCallEventManager(); - CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(), - Succ->getState()); + CallEventRef<> Call = + CallMgr.getCaller(CE->getCalleeContext(), Succ->getState()); InitE = Call->getArgExpr(Param->getFunctionScopeIndex()); } else { // Handle Objective-C 'self'. assert(isa(VR->getDecl())); InitE = cast(CE->getCalleeContext()->getCallSite()) - ->getInstanceReceiver()->IgnoreParenCasts(); + ->getInstanceReceiver() + ->IgnoreParenCasts(); } IsParam = true; } @@ -1867,7 +1863,7 @@ PathDiagnosticPieceRef TrackConstraintBRVisitor::VisitNode( return nullptr; PathDiagnosticLocation L = - PathDiagnosticLocation::create(P, BRC.getSourceManager()); + PathDiagnosticLocation::create(P, BRC.getSourceManager()); if (!L.isValid()) return nullptr; @@ -1883,8 +1879,8 @@ PathDiagnosticPieceRef TrackConstraintBRVisitor::VisitNode( // Implementation of SuppressInlineDefensiveChecksVisitor. //===----------------------------------------------------------------------===// -SuppressInlineDefensiveChecksVisitor:: -SuppressInlineDefensiveChecksVisitor(DefinedSVal Value, const ExplodedNode *N) +SuppressInlineDefensiveChecksVisitor::SuppressInlineDefensiveChecksVisitor( + DefinedSVal Value, const ExplodedNode *N) : V(Value) { // Check if the visitor is disabled. AnalyzerOptions &Options = N->getState()->getAnalysisManager().options; @@ -2014,8 +2010,7 @@ class TrackControlDependencyCondBRVisitor final } // end of anonymous namespace static std::shared_ptr -constructDebugPieceForTrackedCondition(const Expr *Cond, - const ExplodedNode *N, +constructDebugPieceForTrackedCondition(const Expr *Cond, const ExplodedNode *N, BugReporterContext &BRC) { if (BRC.getAnalyzerOptions().AnalysisDiagOpt == PD_NONE || @@ -2027,9 +2022,9 @@ constructDebugPieceForTrackedCondition(const Expr *Cond, BRC.getSourceManager(), BRC.getASTContext().getLangOpts())); return std::make_shared( - PathDiagnosticLocation::createBegin( - Cond, BRC.getSourceManager(), N->getLocationContext()), - (Twine() + "Tracking condition '" + ConditionText + "'").str()); + PathDiagnosticLocation::createBegin(Cond, BRC.getSourceManager(), + N->getLocationContext()), + (Twine() + "Tracking condition '" + ConditionText + "'").str()); } static bool isAssertlikeBlock(const CFGBlock *B, ASTContext &Context) { @@ -2143,7 +2138,8 @@ static const Expr *peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N) { if (const auto *OVE = dyn_cast(Ex)) return peelOffOuterExpr(OVE->getSourceExpr(), N); if (const auto *POE = dyn_cast(Ex)) { - const auto *PropRef = dyn_cast(POE->getSyntacticForm()); + const auto *PropRef = + dyn_cast(POE->getSyntacticForm()); if (PropRef && PropRef->isMessagingGetter()) { const Expr *GetterMessageSend = POE->getSemanticExpr(POE->getNumSemanticExprs() - 1); @@ -2201,7 +2197,7 @@ static const Expr *peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N) { /// Find the ExplodedNode where the lvalue (the value of 'Ex') /// was computed. -static const ExplodedNode* findNodeForExpression(const ExplodedNode *N, +static const ExplodedNode *findNodeForExpression(const ExplodedNode *N, const Expr *Inner) { while (N) { if (N->getStmtForDiagnostics() == Inner) @@ -2736,8 +2732,7 @@ NilReceiverBRVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, OS << "'"; ME->getSelector().print(OS); OS << "' not called"; - } - else { + } else { OS << "No method is called"; } OS << " because the receiver is nil"; @@ -2750,7 +2745,7 @@ NilReceiverBRVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, /*EnableNullFPSuppression*/ false}); // Issue a message saying that the method was skipped. PathDiagnosticLocation L(Receiver, BRC.getSourceManager(), - N->getLocationContext()); + N->getLocationContext()); return std::make_shared(L, OS.str()); } @@ -2895,32 +2890,32 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond, BugReporterContext &BRC, while (true) { CondTmp = CondTmp->IgnoreParenCasts(); switch (CondTmp->getStmtClass()) { - default: - break; - case Stmt::BinaryOperatorClass: - if (auto P = VisitTrueTest(Cond, cast(CondTmp), - BRC, R, N, TookTrueTmp, IsAssuming)) - return P; - break; - case Stmt::DeclRefExprClass: - if (auto P = VisitTrueTest(Cond, cast(CondTmp), - BRC, R, N, TookTrueTmp, IsAssuming)) - return P; - break; - case Stmt::MemberExprClass: - if (auto P = VisitTrueTest(Cond, cast(CondTmp), - BRC, R, N, TookTrueTmp, IsAssuming)) - return P; - break; - case Stmt::UnaryOperatorClass: { - const auto *UO = cast(CondTmp); - if (UO->getOpcode() == UO_LNot) { - TookTrueTmp = !TookTrueTmp; - CondTmp = UO->getSubExpr(); - continue; - } - break; + default: + break; + case Stmt::BinaryOperatorClass: + if (auto P = VisitTrueTest(Cond, cast(CondTmp), BRC, R, N, + TookTrueTmp, IsAssuming)) + return P; + break; + case Stmt::DeclRefExprClass: + if (auto P = VisitTrueTest(Cond, cast(CondTmp), BRC, R, N, + TookTrueTmp, IsAssuming)) + return P; + break; + case Stmt::MemberExprClass: + if (auto P = VisitTrueTest(Cond, cast(CondTmp), BRC, R, N, + TookTrueTmp, IsAssuming)) + return P; + break; + case Stmt::UnaryOperatorClass: { + const auto *UO = cast(CondTmp); + if (UO->getOpcode() == UO_LNot) { + TookTrueTmp = !TookTrueTmp; + CondTmp = UO->getSubExpr(); + continue; } + break; + } } break; } @@ -2973,8 +2968,9 @@ bool ConditionBRVisitor::patternMatch(const Expr *Ex, const Expr *ParentEx, Out << '\''; const LocationContext *LCtx = N->getLocationContext(); const ProgramState *state = N->getState().get(); - if (const MemRegion *R = state->getLValue(cast(DR->getDecl()), - LCtx).getAsRegion()) { + if (const MemRegion *R = + state->getLValue(cast(DR->getDecl()), LCtx) + .getAsRegion()) { if (report.isInteresting(R)) prunable = false; else { @@ -2998,8 +2994,7 @@ bool ConditionBRVisitor::patternMatch(const Expr *Ex, const Expr *ParentEx, Out << "null"; return false; } - } - else if (OriginalTy->isObjCObjectPointerType()) { + } else if (OriginalTy->isObjCObjectPointerType()) { if (IL->getValue() == 0) { Out << "nil"; return false; @@ -3077,35 +3072,56 @@ PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest( // Do we need to invert the opcode? if (shouldInvert) switch (Op) { - default: break; - case BO_LT: Op = BO_GT; break; - case BO_GT: Op = BO_LT; break; - case BO_LE: Op = BO_GE; break; - case BO_GE: Op = BO_LE; break; + default: + break; + case BO_LT: + Op = BO_GT; + break; + case BO_GT: + Op = BO_LT; + break; + case BO_LE: + Op = BO_GE; + break; + case BO_GE: + Op = BO_LE; + break; } if (!TookTrue) switch (Op) { - case BO_EQ: Op = BO_NE; break; - case BO_NE: Op = BO_EQ; break; - case BO_LT: Op = BO_GE; break; - case BO_GT: Op = BO_LE; break; - case BO_LE: Op = BO_GT; break; - case BO_GE: Op = BO_LT; break; - default: - return nullptr; - } - - switch (Op) { case BO_EQ: - Out << "equal to "; + Op = BO_NE; break; case BO_NE: - Out << "not equal to "; + Op = BO_EQ; break; - default: - Out << BinaryOperator::getOpcodeStr(Op) << ' '; + case BO_LT: + Op = BO_GE; + break; + case BO_GT: + Op = BO_LE; + break; + case BO_LE: + Op = BO_GT; break; + case BO_GE: + Op = BO_LT; + break; + default: + return nullptr; + } + + switch (Op) { + case BO_EQ: + Out << "equal to "; + break; + case BO_NE: + Out << "not equal to "; + break; + default: + Out << BinaryOperator::getOpcodeStr(Op) << ' '; + break; } Out << (shouldInvert ? LhsString : RhsString); @@ -3405,7 +3421,7 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, ++Idx; // Are we tracking the argument or its subregion? - if ( !ArgReg || !R->isSubRegionOf(ArgReg->StripCasts())) + if (!ArgReg || !R->isSubRegionOf(ArgReg->StripCasts())) continue; // Check the function parameter type. diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index 0ac1d91b79beb..2229c12474140 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -78,8 +78,7 @@ QualType CallEvent::getResultType() const { static bool isCallback(QualType T) { // If a parameter is a block or a callback, assume it can modify pointer. - if (T->isBlockPointerType() || - T->isFunctionPointerType() || + if (T->isBlockPointerType() || T->isFunctionPointerType() || T->isObjCSelType()) return true; @@ -190,16 +189,16 @@ CallEvent::getCalleeStackFrame(unsigned BlockCount) const { return ADC->getManager()->getStackFrame(ADC, LCtx, E, B, BlockCount, Idx); } -const ParamVarRegion -*CallEvent::getParameterLocation(unsigned Index, unsigned BlockCount) const { +const ParamVarRegion * +CallEvent::getParameterLocation(unsigned Index, unsigned BlockCount) const { const StackFrameContext *SFC = getCalleeStackFrame(BlockCount); // We cannot construct a VarRegion without a stack frame. if (!SFC) return nullptr; const ParamVarRegion *PVR = - State->getStateManager().getRegionManager().getParamVarRegion( - getOriginExpr(), Index, SFC); + State->getStateManager().getRegionManager().getParamVarRegion( + getOriginExpr(), Index, SFC); return PVR; } @@ -254,9 +253,10 @@ ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount, // below for efficiency. if (PreserveArgs.count(Idx)) if (const MemRegion *MR = getArgSVal(Idx).getAsRegion()) - ETraits.setTrait(MR->getBaseRegion(), - RegionAndSymbolInvalidationTraits::TK_PreserveContents); - // TODO: Factor this out + handle the lower level const pointers. + ETraits.setTrait( + MR->getBaseRegion(), + RegionAndSymbolInvalidationTraits::TK_PreserveContents); + // TODO: Factor this out + handle the lower level const pointers. ValuesToInvalidate.push_back(getArgSVal(Idx)); @@ -462,14 +462,15 @@ static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx, CallEvent::BindingsTy &Bindings, SValBuilder &SVB, const CallEvent &Call, - ArrayRef parameters) { + ArrayRef parameters) { MemRegionManager &MRMgr = SVB.getRegionManager(); // If the function has fewer parameters than the call has arguments, we simply // do not bind any values to them. unsigned NumArgs = Call.getNumArgs(); unsigned Idx = 0; - ArrayRef::iterator I = parameters.begin(), E = parameters.end(); + ArrayRef::iterator I = parameters.begin(), + E = parameters.end(); for (; I != E && Idx < NumArgs; ++I, ++Idx) { assert(*I && "Formal parameter has no decl?"); @@ -550,7 +551,7 @@ std::optional CallEvent::getReturnValueUnderConstruction() const { return RetVal; } -ArrayRef AnyFunctionCall::parameters() const { +ArrayRef AnyFunctionCall::parameters() const { const FunctionDecl *D = getDecl(); if (!D) return std::nullopt; @@ -565,10 +566,10 @@ RuntimeDefinition AnyFunctionCall::getRuntimeDefinition() const { // Note that the AnalysisDeclContext will have the FunctionDecl with // the definition (if one exists). AnalysisDeclContext *AD = - getLocationContext()->getAnalysisDeclContext()-> - getManager()->getContext(FD); + getLocationContext()->getAnalysisDeclContext()->getManager()->getContext( + FD); bool IsAutosynthesized; - Stmt* Body = AD->getBody(IsAutosynthesized); + Stmt *Body = AD->getBody(IsAutosynthesized); LLVM_DEBUG({ if (IsAutosynthesized) llvm::dbgs() << "Using autosynthesized body for " << FD->getName() @@ -582,7 +583,7 @@ RuntimeDefinition AnyFunctionCall::getRuntimeDefinition() const { AnalyzerOptions &Opts = Engine.getAnalysisManager().options; if (Body) { - const Decl* Decl = AD->getDecl(); + const Decl *Decl = AD->getDecl(); if (Opts.IsNaiveCTUEnabled && CTUCtx.isImportedAsNew(Decl)) { // A newly created definition, but we had error(s) during the import. if (CTUCtx.hasError(Decl)) @@ -612,8 +613,7 @@ RuntimeDefinition AnyFunctionCall::getRuntimeDefinition() const { } void AnyFunctionCall::getInitialStackFrameContents( - const StackFrameContext *CalleeCtx, - BindingsTy &Bindings) const { + const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const { const auto *D = cast(CalleeCtx->getDecl()); SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, @@ -670,11 +670,11 @@ bool AnyFunctionCall::argumentsMayEscape() const { // - Many CF containers allow objects to escape through custom // allocators/deallocators upon container construction. (PR12101) if (FName.starts_with("CF") || FName.starts_with("CG")) { - return StrInStrNoCase(FName, "InsertValue") != StringRef::npos || - StrInStrNoCase(FName, "AddValue") != StringRef::npos || - StrInStrNoCase(FName, "SetValue") != StringRef::npos || - StrInStrNoCase(FName, "WithData") != StringRef::npos || - StrInStrNoCase(FName, "AppendValue") != StringRef::npos || + return StrInStrNoCase(FName, "InsertValue") != StringRef::npos || + StrInStrNoCase(FName, "AddValue") != StringRef::npos || + StrInStrNoCase(FName, "SetValue") != StringRef::npos || + StrInStrNoCase(FName, "WithData") != StringRef::npos || + StrInStrNoCase(FName, "AppendValue") != StringRef::npos || StrInStrNoCase(FName, "SetAttribute") != StringRef::npos; } @@ -813,8 +813,7 @@ RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const { } void CXXInstanceCall::getInitialStackFrameContents( - const StackFrameContext *CalleeCtx, - BindingsTy &Bindings) const { + const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const { AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings); // Handle the binding of 'this' in the new stack frame. @@ -880,15 +879,15 @@ const BlockDataRegion *BlockCall::getBlockRegion() const { return dyn_cast_or_null(DataReg); } -ArrayRef BlockCall::parameters() const { +ArrayRef BlockCall::parameters() const { const BlockDecl *D = getDecl(); if (!D) return std::nullopt; return D->parameters(); } -void BlockCall::getExtraInvalidatedValues(ValueList &Values, - RegionAndSymbolInvalidationTraits *ETraits) const { +void BlockCall::getExtraInvalidatedValues( + ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const { // FIXME: This also needs to invalidate captured globals. if (const MemRegion *R = getBlockRegion()) Values.push_back(loc::MemRegionVal(R)); @@ -897,7 +896,7 @@ void BlockCall::getExtraInvalidatedValues(ValueList &Values, void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const { SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); - ArrayRef Params; + ArrayRef Params; if (isConversionFromLambda()) { auto *LambdaOperatorDecl = cast(CalleeCtx->getDecl()); Params = LambdaOperatorDecl->parameters(); @@ -913,8 +912,7 @@ void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx, Params = cast(CalleeCtx->getDecl())->parameters(); } - addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, - Params); + addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, Params); } SVal AnyCXXConstructorCall::getCXXThisVal() const { @@ -923,8 +921,8 @@ SVal AnyCXXConstructorCall::getCXXThisVal() const { return UnknownVal(); } -void AnyCXXConstructorCall::getExtraInvalidatedValues(ValueList &Values, - RegionAndSymbolInvalidationTraits *ETraits) const { +void AnyCXXConstructorCall::getExtraInvalidatedValues( + ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const { SVal V = getCXXThisVal(); if (SymbolRef Sym = V.getAsSymbol(true)) ETraits->setTrait(Sym, @@ -933,8 +931,7 @@ void AnyCXXConstructorCall::getExtraInvalidatedValues(ValueList &Values, } void AnyCXXConstructorCall::getInitialStackFrameContents( - const StackFrameContext *CalleeCtx, - BindingsTy &Bindings) const { + const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const { AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings); SVal ThisVal = getCXXThisVal(); @@ -969,7 +966,7 @@ RuntimeDefinition CXXDestructorCall::getRuntimeDefinition() const { return CXXInstanceCall::getRuntimeDefinition(); } -ArrayRef ObjCMethodCall::parameters() const { +ArrayRef ObjCMethodCall::parameters() const { const ObjCMethodDecl *D = getDecl(); if (!D) return std::nullopt; @@ -987,11 +984,10 @@ void ObjCMethodCall::getExtraInvalidatedValues( SVal IvarLVal = getState()->getLValue(PropIvar, getReceiverSVal()); if (const MemRegion *IvarRegion = IvarLVal.getAsRegion()) { ETraits->setTrait( - IvarRegion, - RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); - ETraits->setTrait( - IvarRegion, - RegionAndSymbolInvalidationTraits::TK_SuppressEscape); + IvarRegion, + RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); + ETraits->setTrait(IvarRegion, + RegionAndSymbolInvalidationTraits::TK_SuppressEscape); Values.push_back(IvarLVal); } return; @@ -1020,7 +1016,7 @@ SVal ObjCMethodCall::getReceiverSVal() const { bool ObjCMethodCall::isReceiverSelfOrSuper() const { if (getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance || getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperClass) - return true; + return true; if (!isInstanceMessage()) return false; @@ -1087,15 +1083,15 @@ ObjCMessageKind ObjCMethodCall::getMessageKind() const { } if (K != OCM_Message) { - const_cast(this)->Data - = ObjCMessageDataTy(POE, K).getOpaqueValue(); + const_cast(this)->Data = + ObjCMessageDataTy(POE, K).getOpaqueValue(); assert(getMessageKind() == K); return K; } } - const_cast(this)->Data - = ObjCMessageDataTy(nullptr, 1).getOpaqueValue(); + const_cast(this)->Data = + ObjCMessageDataTy(nullptr, 1).getOpaqueValue(); assert(getMessageKind() == OCM_Message); return OCM_Message; } @@ -1129,7 +1125,7 @@ const ObjCPropertyDecl *ObjCMethodCall::getAccessedProperty() const { } bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, - Selector Sel) const { + Selector Sel) const { assert(IDecl); AnalysisManager &AMgr = getState()->getStateManager().getOwningEngine().getAnalysisManager(); @@ -1383,8 +1379,7 @@ bool ObjCMethodCall::argumentsMayEscape() const { } void ObjCMethodCall::getInitialStackFrameContents( - const StackFrameContext *CalleeCtx, - BindingsTy &Bindings) const { + const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const { const auto *D = cast(CalleeCtx->getDecl()); SValBuilder &SVB = getState()->getStateManager().getSValBuilder(); addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this, @@ -1421,9 +1416,8 @@ CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State, return create(CE, State, LCtx, ElemRef); } -CallEventRef<> -CallEventManager::getCaller(const StackFrameContext *CalleeCtx, - ProgramStateRef State) { +CallEventRef<> CallEventManager::getCaller(const StackFrameContext *CalleeCtx, + ProgramStateRef State) { const LocationContext *ParentCtx = CalleeCtx->getParent(); const LocationContext *CallerCtx = ParentCtx->getStackFrame(); CFGBlock::ConstCFGElementRef ElemRef = {CalleeCtx->getCallSiteBlock(), diff --git a/clang/lib/StaticAnalyzer/Core/Checker.cpp b/clang/lib/StaticAnalyzer/Core/Checker.cpp index bc1c8964b3ee4..f45f31cded621 100644 --- a/clang/lib/StaticAnalyzer/Core/Checker.cpp +++ b/clang/lib/StaticAnalyzer/Core/Checker.cpp @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" using namespace clang; using namespace ento; @@ -26,13 +26,13 @@ CheckerNameRef CheckerBase::getCheckerName() const { return Name; } CheckerProgramPointTag::CheckerProgramPointTag(StringRef CheckerName, StringRef Msg) - : SimpleProgramPointTag(CheckerName, Msg) {} + : SimpleProgramPointTag(CheckerName, Msg) {} CheckerProgramPointTag::CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg) : SimpleProgramPointTag(Checker->getCheckerName().getName(), Msg) {} -raw_ostream& clang::ento::operator<<(raw_ostream &Out, +raw_ostream &clang::ento::operator<<(raw_ostream &Out, const CheckerBase &Checker) { Out << Checker.getCheckerName().getName(); return Out; diff --git a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp index d6d4cec9dd3d4..e4a904cde0484 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp @@ -117,8 +117,7 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, StringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) { if (Loc.isMacroID()) - return Lexer::getImmediateMacroName(Loc, getSourceManager(), - getLangOpts()); + return Lexer::getImmediateMacroName(Loc, getSourceManager(), getLangOpts()); SmallString<16> buf; return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts()); } diff --git a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp index 6fc16223ea828..5812af5285bb4 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -35,7 +35,7 @@ using namespace clang; using namespace ento; bool CheckerManager::hasPathSensitiveCheckers() const { - const auto IfAnyAreNonEmpty = [](const auto &... Callbacks) -> bool { + const auto IfAnyAreNonEmpty = [](const auto &...Callbacks) -> bool { return (!Callbacks.empty() || ...); }; return IfAnyAreNonEmpty( @@ -71,7 +71,7 @@ void CheckerManager::reportInvalidCheckerOptionValue( // Functions for running checkers for AST traversing.. //===----------------------------------------------------------------------===// -void CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, +void CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager &mgr, BugReporter &BR) { assert(D); @@ -93,7 +93,7 @@ void CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, checker(D, mgr, BR); } -void CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, +void CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR) { assert(D && D->hasBody()); @@ -106,15 +106,14 @@ void CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, //===----------------------------------------------------------------------===// template -static void expandGraphWithCheckers(CHECK_CTX checkCtx, - ExplodedNodeSet &Dst, +static void expandGraphWithCheckers(CHECK_CTX checkCtx, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src) { const NodeBuilderContext &BldrCtx = checkCtx.Eng.getBuilderContext(); if (Src.empty()) return; - typename CHECK_CTX::CheckersTy::const_iterator - I = checkCtx.checkers_begin(), E = checkCtx.checkers_end(); + typename CHECK_CTX::CheckersTy::const_iterator I = checkCtx.checkers_begin(), + E = checkCtx.checkers_end(); if (I == E) { Dst.insert(Src); return; @@ -125,7 +124,7 @@ static void expandGraphWithCheckers(CHECK_CTX checkCtx, for (; I != E; ++I) { ExplodedNodeSet *CurrSet = nullptr; - if (I+1 == E) + if (I + 1 == E) CurrSet = &Dst; else { CurrSet = (PrevSet == &Tmp1) ? &Tmp2 : &Tmp1; @@ -147,90 +146,87 @@ static void expandGraphWithCheckers(CHECK_CTX checkCtx, namespace { - struct CheckStmtContext { - using CheckersTy = SmallVectorImpl; +struct CheckStmtContext { + using CheckersTy = SmallVectorImpl; - bool IsPreVisit; - const CheckersTy &Checkers; - const Stmt *S; - ExprEngine &Eng; - bool WasInlined; - - CheckStmtContext(bool isPreVisit, const CheckersTy &checkers, - const Stmt *s, ExprEngine &eng, bool wasInlined = false) - : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng), - WasInlined(wasInlined) {} - - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - - void runChecker(CheckerManager::CheckStmtFunc checkFn, - NodeBuilder &Bldr, ExplodedNode *Pred) { - // FIXME: Remove respondsToCallback from CheckerContext; - ProgramPoint::Kind K = IsPreVisit ? ProgramPoint::PreStmtKind : - ProgramPoint::PostStmtKind; - const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, - Pred->getLocationContext(), checkFn.Checker); - CheckerContext C(Bldr, Eng, Pred, L, WasInlined); - checkFn(S, C); - } - }; + bool IsPreVisit; + const CheckersTy &Checkers; + const Stmt *S; + ExprEngine &Eng; + bool WasInlined; + + CheckStmtContext(bool isPreVisit, const CheckersTy &checkers, const Stmt *s, + ExprEngine &eng, bool wasInlined = false) + : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng), + WasInlined(wasInlined) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + + void runChecker(CheckerManager::CheckStmtFunc checkFn, NodeBuilder &Bldr, + ExplodedNode *Pred) { + // FIXME: Remove respondsToCallback from CheckerContext; + ProgramPoint::Kind K = + IsPreVisit ? ProgramPoint::PreStmtKind : ProgramPoint::PostStmtKind; + const ProgramPoint &L = ProgramPoint::getProgramPoint( + S, K, Pred->getLocationContext(), checkFn.Checker); + CheckerContext C(Bldr, Eng, Pred, L, WasInlined); + checkFn(S, C); + } +}; } // namespace /// Run checkers for visiting Stmts. -void CheckerManager::runCheckersForStmt(bool isPreVisit, - ExplodedNodeSet &Dst, +void CheckerManager::runCheckersForStmt(bool isPreVisit, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, - const Stmt *S, - ExprEngine &Eng, + const Stmt *S, ExprEngine &Eng, bool WasInlined) { - CheckStmtContext C(isPreVisit, getCachedStmtCheckersFor(S, isPreVisit), - S, Eng, WasInlined); + CheckStmtContext C(isPreVisit, getCachedStmtCheckersFor(S, isPreVisit), S, + Eng, WasInlined); expandGraphWithCheckers(C, Dst, Src); } namespace { - struct CheckObjCMessageContext { - using CheckersTy = std::vector; - - ObjCMessageVisitKind Kind; - bool WasInlined; - const CheckersTy &Checkers; - const ObjCMethodCall &Msg; - ExprEngine &Eng; - - CheckObjCMessageContext(ObjCMessageVisitKind visitKind, - const CheckersTy &checkers, - const ObjCMethodCall &msg, ExprEngine &eng, - bool wasInlined) - : Kind(visitKind), WasInlined(wasInlined), Checkers(checkers), Msg(msg), - Eng(eng) {} - - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - - void runChecker(CheckerManager::CheckObjCMessageFunc checkFn, - NodeBuilder &Bldr, ExplodedNode *Pred) { - bool IsPreVisit; - - switch (Kind) { - case ObjCMessageVisitKind::Pre: - IsPreVisit = true; - break; - case ObjCMessageVisitKind::MessageNil: - case ObjCMessageVisitKind::Post: - IsPreVisit = false; - break; - } +struct CheckObjCMessageContext { + using CheckersTy = std::vector; - const ProgramPoint &L = Msg.getProgramPoint(IsPreVisit,checkFn.Checker); - CheckerContext C(Bldr, Eng, Pred, L, WasInlined); + ObjCMessageVisitKind Kind; + bool WasInlined; + const CheckersTy &Checkers; + const ObjCMethodCall &Msg; + ExprEngine &Eng; - checkFn(*Msg.cloneWithState(Pred->getState()), C); + CheckObjCMessageContext(ObjCMessageVisitKind visitKind, + const CheckersTy &checkers, const ObjCMethodCall &msg, + ExprEngine &eng, bool wasInlined) + : Kind(visitKind), WasInlined(wasInlined), Checkers(checkers), Msg(msg), + Eng(eng) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + + void runChecker(CheckerManager::CheckObjCMessageFunc checkFn, + NodeBuilder &Bldr, ExplodedNode *Pred) { + bool IsPreVisit; + + switch (Kind) { + case ObjCMessageVisitKind::Pre: + IsPreVisit = true; + break; + case ObjCMessageVisitKind::MessageNil: + case ObjCMessageVisitKind::Post: + IsPreVisit = false; + break; } - }; + + const ProgramPoint &L = Msg.getProgramPoint(IsPreVisit, checkFn.Checker); + CheckerContext C(Bldr, Eng, Pred, L, WasInlined); + + checkFn(*Msg.cloneWithState(Pred->getState()), C); + } +}; } // namespace @@ -262,33 +258,32 @@ CheckerManager::getObjCMessageCheckers(ObjCMessageVisitKind Kind) const { namespace { - // FIXME: This has all the same signatures as CheckObjCMessageContext. - // Is there a way we can merge the two? - struct CheckCallContext { - using CheckersTy = std::vector; +// FIXME: This has all the same signatures as CheckObjCMessageContext. +// Is there a way we can merge the two? +struct CheckCallContext { + using CheckersTy = std::vector; - bool IsPreVisit, WasInlined; - const CheckersTy &Checkers; - const CallEvent &Call; - ExprEngine &Eng; + bool IsPreVisit, WasInlined; + const CheckersTy &Checkers; + const CallEvent &Call; + ExprEngine &Eng; - CheckCallContext(bool isPreVisit, const CheckersTy &checkers, - const CallEvent &call, ExprEngine &eng, - bool wasInlined) - : IsPreVisit(isPreVisit), WasInlined(wasInlined), Checkers(checkers), - Call(call), Eng(eng) {} + CheckCallContext(bool isPreVisit, const CheckersTy &checkers, + const CallEvent &call, ExprEngine &eng, bool wasInlined) + : IsPreVisit(isPreVisit), WasInlined(wasInlined), Checkers(checkers), + Call(call), Eng(eng) {} - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - void runChecker(CheckerManager::CheckCallFunc checkFn, - NodeBuilder &Bldr, ExplodedNode *Pred) { - const ProgramPoint &L = Call.getProgramPoint(IsPreVisit,checkFn.Checker); - CheckerContext C(Bldr, Eng, Pred, L, WasInlined); + void runChecker(CheckerManager::CheckCallFunc checkFn, NodeBuilder &Bldr, + ExplodedNode *Pred) { + const ProgramPoint &L = Call.getProgramPoint(IsPreVisit, checkFn.Checker); + CheckerContext C(Bldr, Eng, Pred, L, WasInlined); - checkFn(*Call.cloneWithState(Pred->getState()), C); - } - }; + checkFn(*Call.cloneWithState(Pred->getState()), C); + } +}; } // namespace @@ -297,101 +292,91 @@ void CheckerManager::runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, - ExprEngine &Eng, - bool WasInlined) { + ExprEngine &Eng, bool WasInlined) { CheckCallContext C(isPreVisit, - isPreVisit ? PreCallCheckers - : PostCallCheckers, - Call, Eng, WasInlined); + isPreVisit ? PreCallCheckers : PostCallCheckers, Call, Eng, + WasInlined); expandGraphWithCheckers(C, Dst, Src); } namespace { - struct CheckLocationContext { - using CheckersTy = std::vector; - - const CheckersTy &Checkers; - SVal Loc; - bool IsLoad; - const Stmt *NodeEx; /* Will become a CFGStmt */ - const Stmt *BoundEx; - ExprEngine &Eng; - - CheckLocationContext(const CheckersTy &checkers, - SVal loc, bool isLoad, const Stmt *NodeEx, - const Stmt *BoundEx, - ExprEngine &eng) - : Checkers(checkers), Loc(loc), IsLoad(isLoad), NodeEx(NodeEx), - BoundEx(BoundEx), Eng(eng) {} - - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - - void runChecker(CheckerManager::CheckLocationFunc checkFn, - NodeBuilder &Bldr, ExplodedNode *Pred) { - ProgramPoint::Kind K = IsLoad ? ProgramPoint::PreLoadKind : - ProgramPoint::PreStoreKind; - const ProgramPoint &L = - ProgramPoint::getProgramPoint(NodeEx, K, - Pred->getLocationContext(), - checkFn.Checker); - CheckerContext C(Bldr, Eng, Pred, L); - checkFn(Loc, IsLoad, BoundEx, C); - } - }; +struct CheckLocationContext { + using CheckersTy = std::vector; + + const CheckersTy &Checkers; + SVal Loc; + bool IsLoad; + const Stmt *NodeEx; /* Will become a CFGStmt */ + const Stmt *BoundEx; + ExprEngine &Eng; + + CheckLocationContext(const CheckersTy &checkers, SVal loc, bool isLoad, + const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &eng) + : Checkers(checkers), Loc(loc), IsLoad(isLoad), NodeEx(NodeEx), + BoundEx(BoundEx), Eng(eng) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + + void runChecker(CheckerManager::CheckLocationFunc checkFn, NodeBuilder &Bldr, + ExplodedNode *Pred) { + ProgramPoint::Kind K = + IsLoad ? ProgramPoint::PreLoadKind : ProgramPoint::PreStoreKind; + const ProgramPoint &L = ProgramPoint::getProgramPoint( + NodeEx, K, Pred->getLocationContext(), checkFn.Checker); + CheckerContext C(Bldr, Eng, Pred, L); + checkFn(Loc, IsLoad, BoundEx, C); + } +}; } // namespace /// Run checkers for load/store of a location. -void CheckerManager::runCheckersForLocation(ExplodedNodeSet &Dst, - const ExplodedNodeSet &Src, - SVal location, bool isLoad, - const Stmt *NodeEx, - const Stmt *BoundEx, - ExprEngine &Eng) { - CheckLocationContext C(LocationCheckers, location, isLoad, NodeEx, - BoundEx, Eng); +void CheckerManager::runCheckersForLocation( + ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, + bool isLoad, const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &Eng) { + CheckLocationContext C(LocationCheckers, location, isLoad, NodeEx, BoundEx, + Eng); expandGraphWithCheckers(C, Dst, Src); } namespace { - struct CheckBindContext { - using CheckersTy = std::vector; +struct CheckBindContext { + using CheckersTy = std::vector; - const CheckersTy &Checkers; - SVal Loc; - SVal Val; - const Stmt *S; - ExprEngine &Eng; - const ProgramPoint &PP; + const CheckersTy &Checkers; + SVal Loc; + SVal Val; + const Stmt *S; + ExprEngine &Eng; + const ProgramPoint &PP; - CheckBindContext(const CheckersTy &checkers, - SVal loc, SVal val, const Stmt *s, ExprEngine &eng, - const ProgramPoint &pp) - : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng), PP(pp) {} + CheckBindContext(const CheckersTy &checkers, SVal loc, SVal val, + const Stmt *s, ExprEngine &eng, const ProgramPoint &pp) + : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng), PP(pp) {} - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - void runChecker(CheckerManager::CheckBindFunc checkFn, - NodeBuilder &Bldr, ExplodedNode *Pred) { - const ProgramPoint &L = PP.withTag(checkFn.Checker); - CheckerContext C(Bldr, Eng, Pred, L); + void runChecker(CheckerManager::CheckBindFunc checkFn, NodeBuilder &Bldr, + ExplodedNode *Pred) { + const ProgramPoint &L = PP.withTag(checkFn.Checker); + CheckerContext C(Bldr, Eng, Pred, L); - checkFn(Loc, Val, S, C); - } - }; + checkFn(Loc, Val, S, C); + } +}; } // namespace /// Run checkers for binding of a value to a location. void CheckerManager::runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, - SVal location, SVal val, - const Stmt *S, ExprEngine &Eng, + SVal location, SVal val, const Stmt *S, + ExprEngine &Eng, const ProgramPoint &PP) { CheckBindContext C(BindCheckers, location, val, S, Eng, PP); expandGraphWithCheckers(C, Dst, Src); @@ -463,28 +448,28 @@ void CheckerManager::runCheckersForEndFunction(NodeBuilderContext &BC, namespace { - struct CheckBranchConditionContext { - using CheckersTy = std::vector; +struct CheckBranchConditionContext { + using CheckersTy = std::vector; - const CheckersTy &Checkers; - const Stmt *Condition; - ExprEngine &Eng; + const CheckersTy &Checkers; + const Stmt *Condition; + ExprEngine &Eng; - CheckBranchConditionContext(const CheckersTy &checkers, - const Stmt *Cond, ExprEngine &eng) - : Checkers(checkers), Condition(Cond), Eng(eng) {} + CheckBranchConditionContext(const CheckersTy &checkers, const Stmt *Cond, + ExprEngine &eng) + : Checkers(checkers), Condition(Cond), Eng(eng) {} - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - void runChecker(CheckerManager::CheckBranchConditionFunc checkFn, - NodeBuilder &Bldr, ExplodedNode *Pred) { - ProgramPoint L = PostCondition(Condition, Pred->getLocationContext(), - checkFn.Checker); - CheckerContext C(Bldr, Eng, Pred, L); - checkFn(Condition, C); - } - }; + void runChecker(CheckerManager::CheckBranchConditionFunc checkFn, + NodeBuilder &Bldr, ExplodedNode *Pred) { + ProgramPoint L = + PostCondition(Condition, Pred->getLocationContext(), checkFn.Checker); + CheckerContext C(Bldr, Eng, Pred, L); + checkFn(Condition, C); + } +}; } // namespace @@ -501,31 +486,30 @@ void CheckerManager::runCheckersForBranchCondition(const Stmt *Condition, namespace { - struct CheckNewAllocatorContext { - using CheckersTy = std::vector; - - const CheckersTy &Checkers; - const CXXAllocatorCall &Call; - bool WasInlined; - ExprEngine &Eng; - - CheckNewAllocatorContext(const CheckersTy &Checkers, - const CXXAllocatorCall &Call, bool WasInlined, - ExprEngine &Eng) - : Checkers(Checkers), Call(Call), WasInlined(WasInlined), Eng(Eng) {} - - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - - void runChecker(CheckerManager::CheckNewAllocatorFunc checkFn, - NodeBuilder &Bldr, ExplodedNode *Pred) { - ProgramPoint L = - PostAllocatorCall(Call.getOriginExpr(), Pred->getLocationContext()); - CheckerContext C(Bldr, Eng, Pred, L, WasInlined); - checkFn(cast(*Call.cloneWithState(Pred->getState())), - C); - } - }; +struct CheckNewAllocatorContext { + using CheckersTy = std::vector; + + const CheckersTy &Checkers; + const CXXAllocatorCall &Call; + bool WasInlined; + ExprEngine &Eng; + + CheckNewAllocatorContext(const CheckersTy &Checkers, + const CXXAllocatorCall &Call, bool WasInlined, + ExprEngine &Eng) + : Checkers(Checkers), Call(Call), WasInlined(WasInlined), Eng(Eng) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + + void runChecker(CheckerManager::CheckNewAllocatorFunc checkFn, + NodeBuilder &Bldr, ExplodedNode *Pred) { + ProgramPoint L = + PostAllocatorCall(Call.getOriginExpr(), Pred->getLocationContext()); + CheckerContext C(Bldr, Eng, Pred, L, WasInlined); + checkFn(cast(*Call.cloneWithState(Pred->getState())), C); + } +}; } // namespace @@ -549,35 +533,34 @@ void CheckerManager::runCheckersForLiveSymbols(ProgramStateRef state, namespace { - struct CheckDeadSymbolsContext { - using CheckersTy = std::vector; - - const CheckersTy &Checkers; - SymbolReaper &SR; - const Stmt *S; - ExprEngine &Eng; - ProgramPoint::Kind ProgarmPointKind; - - CheckDeadSymbolsContext(const CheckersTy &checkers, SymbolReaper &sr, - const Stmt *s, ExprEngine &eng, - ProgramPoint::Kind K) - : Checkers(checkers), SR(sr), S(s), Eng(eng), ProgarmPointKind(K) {} - - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - - void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn, - NodeBuilder &Bldr, ExplodedNode *Pred) { - const ProgramPoint &L = ProgramPoint::getProgramPoint(S, ProgarmPointKind, - Pred->getLocationContext(), checkFn.Checker); - CheckerContext C(Bldr, Eng, Pred, L); - - // Note, do not pass the statement to the checkers without letting them - // differentiate if we ran remove dead bindings before or after the - // statement. - checkFn(SR, C); - } - }; +struct CheckDeadSymbolsContext { + using CheckersTy = std::vector; + + const CheckersTy &Checkers; + SymbolReaper &SR; + const Stmt *S; + ExprEngine &Eng; + ProgramPoint::Kind ProgarmPointKind; + + CheckDeadSymbolsContext(const CheckersTy &checkers, SymbolReaper &sr, + const Stmt *s, ExprEngine &eng, ProgramPoint::Kind K) + : Checkers(checkers), SR(sr), S(s), Eng(eng), ProgarmPointKind(K) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + + void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn, + NodeBuilder &Bldr, ExplodedNode *Pred) { + const ProgramPoint &L = ProgramPoint::getProgramPoint( + S, ProgarmPointKind, Pred->getLocationContext(), checkFn.Checker); + CheckerContext C(Bldr, Eng, Pred, L); + + // Note, do not pass the statement to the checkers without letting them + // differentiate if we ran remove dead bindings before or after the + // statement. + checkFn(SR, C); + } +}; } // namespace @@ -585,21 +568,18 @@ namespace { void CheckerManager::runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, - const Stmt *S, - ExprEngine &Eng, + const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K) { CheckDeadSymbolsContext C(DeadSymbolsCheckers, SymReaper, S, Eng, K); expandGraphWithCheckers(C, Dst, Src); } /// Run checkers for region changes. -ProgramStateRef -CheckerManager::runCheckersForRegionChanges(ProgramStateRef state, - const InvalidatedSymbols *invalidated, - ArrayRef ExplicitRegions, - ArrayRef Regions, - const LocationContext *LCtx, - const CallEvent *Call) { +ProgramStateRef CheckerManager::runCheckersForRegionChanges( + ProgramStateRef state, const InvalidatedSymbols *invalidated, + ArrayRef ExplicitRegions, + ArrayRef Regions, const LocationContext *LCtx, + const CallEvent *Call) { for (const auto &RegionChangesChecker : RegionChangesCheckers) { // If any checker declares the state infeasible (or if it starts that way), // bail out. @@ -612,15 +592,12 @@ CheckerManager::runCheckersForRegionChanges(ProgramStateRef state, } /// Run checkers to process symbol escape event. -ProgramStateRef -CheckerManager::runCheckersForPointerEscape(ProgramStateRef State, - const InvalidatedSymbols &Escaped, - const CallEvent *Call, - PointerEscapeKind Kind, - RegionAndSymbolInvalidationTraits *ETraits) { - assert((Call != nullptr || - (Kind != PSK_DirectEscapeOnCall && - Kind != PSK_IndirectEscapeOnCall)) && +ProgramStateRef CheckerManager::runCheckersForPointerEscape( + ProgramStateRef State, const InvalidatedSymbols &Escaped, + const CallEvent *Call, PointerEscapeKind Kind, + RegionAndSymbolInvalidationTraits *ETraits) { + assert((Call != nullptr || (Kind != PSK_DirectEscapeOnCall && + Kind != PSK_IndirectEscapeOnCall)) && "Call must not be NULL when escaping on call"); for (const auto &PointerEscapeChecker : PointerEscapeCheckers) { // If any checker declares the state infeasible (or if it starts that @@ -633,9 +610,9 @@ CheckerManager::runCheckersForPointerEscape(ProgramStateRef State, } /// Run checkers for handling assumptions on symbolic values. -ProgramStateRef -CheckerManager::runCheckersForEvalAssume(ProgramStateRef state, - SVal Cond, bool Assumption) { +ProgramStateRef CheckerManager::runCheckersForEvalAssume(ProgramStateRef state, + SVal Cond, + bool Assumption) { for (const auto &EvalAssumeChecker : EvalAssumeCheckers) { // If any checker declares the state infeasible (or if it starts that way), // bail out. @@ -710,9 +687,7 @@ void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst, /// Run checkers for the entire Translation Unit. void CheckerManager::runCheckersOnEndOfTranslationUnit( - const TranslationUnitDecl *TU, - AnalysisManager &mgr, - BugReporter &BR) { + const TranslationUnitDecl *TU, AnalysisManager &mgr, BugReporter &BR) { for (const auto &EndOfTranslationUnitChecker : EndOfTranslationUnitCheckers) EndOfTranslationUnitChecker(TU, mgr, BR); } @@ -732,8 +707,8 @@ void CheckerManager::runCheckersForPrintStateJson(raw_ostream &Out, // Create the new-line in JSON with enough space. SmallString<128> NewLine; llvm::raw_svector_ostream NLOut(NewLine); - NLOut << "\", " << NL; // Inject the ending and a new line - Indent(NLOut, InnerSpace, IsDot) << "\""; // then begin the next message. + NLOut << "\", " << NL; // Inject the ending and a new line + Indent(NLOut, InnerSpace, IsDot) << "\""; // then begin the next message. ++Space; bool HasMessage = false; @@ -792,7 +767,7 @@ void CheckerManager::runCheckersForPrintStateJson(raw_ostream &Out, void CheckerManager::_registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn) { - DeclCheckerInfo info = { checkfn, isForDeclFn }; + DeclCheckerInfo info = {checkfn, isForDeclFn}; DeclCheckers.push_back(info); } @@ -806,13 +781,13 @@ void CheckerManager::_registerForBody(CheckDeclFunc checkfn) { void CheckerManager::_registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn) { - StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/true }; + StmtCheckerInfo info = {checkfn, isForStmtFn, /*IsPreVisit*/ true}; StmtCheckers.push_back(info); } void CheckerManager::_registerForPostStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn) { - StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/false }; + StmtCheckerInfo info = {checkfn, isForStmtFn, /*IsPreVisit*/ false}; StmtCheckers.push_back(info); } @@ -856,7 +831,7 @@ void CheckerManager::_registerForEndFunction(CheckEndFunctionFunc checkfn) { } void CheckerManager::_registerForBranchCondition( - CheckBranchConditionFunc checkfn) { + CheckBranchConditionFunc checkfn) { BranchConditionCheckers.push_back(checkfn); } @@ -876,12 +851,12 @@ void CheckerManager::_registerForRegionChanges(CheckRegionChangesFunc checkfn) { RegionChangesCheckers.push_back(checkfn); } -void CheckerManager::_registerForPointerEscape(CheckPointerEscapeFunc checkfn){ +void CheckerManager::_registerForPointerEscape(CheckPointerEscapeFunc checkfn) { PointerEscapeCheckers.push_back(checkfn); } void CheckerManager::_registerForConstPointerEscape( - CheckPointerEscapeFunc checkfn) { + CheckPointerEscapeFunc checkfn) { PointerEscapeCheckers.push_back(checkfn); } @@ -894,7 +869,7 @@ void CheckerManager::_registerForEvalCall(EvalCallFunc checkfn) { } void CheckerManager::_registerForEndOfTranslationUnit( - CheckEndOfTranslationUnit checkfn) { + CheckEndOfTranslationUnit checkfn) { EndOfTranslationUnitCheckers.push_back(checkfn); } diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index d3499e7a917d3..8ca1d1fa7a911 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -41,14 +41,12 @@ using namespace ento; #define DEBUG_TYPE "CoreEngine" -STATISTIC(NumSteps, - "The # of steps executed."); +STATISTIC(NumSteps, "The # of steps executed."); STATISTIC(NumSTUSteps, "The # of STU steps executed."); STATISTIC(NumCTUSteps, "The # of CTU steps executed."); STATISTIC(NumReachedMaxSteps, - "The # of times we reached the max number of steps."); -STATISTIC(NumPathsExplored, - "The # of paths explored by the analyzer."); + "The # of times we reached the max number of steps."); +STATISTIC(NumPathsExplored, "The # of paths explored by the analyzer."); //===----------------------------------------------------------------------===// // Core analysis engine. @@ -56,18 +54,18 @@ STATISTIC(NumPathsExplored, static std::unique_ptr generateWorkList(AnalyzerOptions &Opts) { switch (Opts.getExplorationStrategy()) { - case ExplorationStrategyKind::DFS: - return WorkList::makeDFS(); - case ExplorationStrategyKind::BFS: - return WorkList::makeBFS(); - case ExplorationStrategyKind::BFSBlockDFSContents: - return WorkList::makeBFSBlockDFSContents(); - case ExplorationStrategyKind::UnexploredFirst: - return WorkList::makeUnexploredFirst(); - case ExplorationStrategyKind::UnexploredFirstQueue: - return WorkList::makeUnexploredFirstPriorityQueue(); - case ExplorationStrategyKind::UnexploredFirstLocationQueue: - return WorkList::makeUnexploredFirstPriorityLocationQueue(); + case ExplorationStrategyKind::DFS: + return WorkList::makeDFS(); + case ExplorationStrategyKind::BFS: + return WorkList::makeBFS(); + case ExplorationStrategyKind::BFSBlockDFSContents: + return WorkList::makeBFSBlockDFSContents(); + case ExplorationStrategyKind::UnexploredFirst: + return WorkList::makeUnexploredFirst(); + case ExplorationStrategyKind::UnexploredFirstQueue: + return WorkList::makeUnexploredFirstPriorityQueue(); + case ExplorationStrategyKind::UnexploredFirstLocationQueue: + return WorkList::makeUnexploredFirstPriorityLocationQueue(); } llvm_unreachable("Unknown AnalyzerOptions::ExplorationStrategyKind"); } @@ -97,8 +95,7 @@ bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned MaxSteps, assert(Entry->succ_size() == 1 && "Entry block must have 1 successor."); // Mark the entry block as visited. - FunctionSummaries->markVisitedBasicBlock(Entry->getBlockID(), - L->getDecl(), + FunctionSummaries->markVisitedBasicBlock(Entry->getBlockID(), L->getDecl(), L->getCFG()->getNumBlockIDs()); // Get the solitary successor. @@ -132,7 +129,7 @@ bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned MaxSteps, // Cap our pre-reservation in the event that the user specifies // a very large number of maximum steps. const unsigned PreReservationCap = 4000000; - if(!UnlimitedSteps) + if (!UnlimitedSteps) G.reserve(std::min(MaxSteps, PreReservationCap)); auto ProcessWList = [this, UnlimitedSteps](unsigned MaxSteps) { @@ -179,46 +176,43 @@ bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned MaxSteps, return WList->hasWork(); } -void CoreEngine::dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc, - const WorkListUnit& WU) { +void CoreEngine::dispatchWorkItem(ExplodedNode *Pred, ProgramPoint Loc, + const WorkListUnit &WU) { // Dispatch on the location type. switch (Loc.getKind()) { - case ProgramPoint::BlockEdgeKind: - HandleBlockEdge(Loc.castAs(), Pred); - break; - - case ProgramPoint::BlockEntranceKind: - HandleBlockEntrance(Loc.castAs(), Pred); - break; - - case ProgramPoint::BlockExitKind: - assert(false && "BlockExit location never occur in forward analysis."); - break; - - case ProgramPoint::CallEnterKind: - HandleCallEnter(Loc.castAs(), Pred); - break; - - case ProgramPoint::CallExitBeginKind: - ExprEng.processCallExit(Pred); - break; - - case ProgramPoint::EpsilonKind: { - assert(Pred->hasSinglePred() && - "Assume epsilon has exactly one predecessor by construction"); - ExplodedNode *PNode = Pred->getFirstPred(); - dispatchWorkItem(Pred, PNode->getLocation(), WU); - break; - } - default: - assert(Loc.getAs() || - Loc.getAs() || - Loc.getAs() || - Loc.getAs() || - Loc.getAs() || - Loc.getAs()); - HandlePostStmt(WU.getBlock(), WU.getIndex(), Pred); - break; + case ProgramPoint::BlockEdgeKind: + HandleBlockEdge(Loc.castAs(), Pred); + break; + + case ProgramPoint::BlockEntranceKind: + HandleBlockEntrance(Loc.castAs(), Pred); + break; + + case ProgramPoint::BlockExitKind: + assert(false && "BlockExit location never occur in forward analysis."); + break; + + case ProgramPoint::CallEnterKind: + HandleCallEnter(Loc.castAs(), Pred); + break; + + case ProgramPoint::CallExitBeginKind: + ExprEng.processCallExit(Pred); + break; + + case ProgramPoint::EpsilonKind: { + assert(Pred->hasSinglePred() && + "Assume epsilon has exactly one predecessor by construction"); + ExplodedNode *PNode = Pred->getFirstPred(); + dispatchWorkItem(Pred, PNode->getLocation(), WU); + break; + } + default: + assert(Loc.getAs() || Loc.getAs() || + Loc.getAs() || Loc.getAs() || + Loc.getAs() || Loc.getAs()); + HandlePostStmt(WU.getBlock(), WU.getIndex(), Pred); + break; } } @@ -240,8 +234,7 @@ void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { // Mark this block as visited. const LocationContext *LC = Pred->getLocationContext(); - FunctionSummaries->markVisitedBasicBlock(Blk->getBlockID(), - LC->getDecl(), + FunctionSummaries->markVisitedBasicBlock(Blk->getBlockID(), LC->getDecl(), LC->getCFG()->getNumBlockIDs()); // Display a prunable path note to the user if it's a virtual bases branch @@ -304,13 +297,13 @@ void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) { } void CoreEngine::HandleBlockEntrance(const BlockEntrance &L, - ExplodedNode *Pred) { + ExplodedNode *Pred) { // Increment the block counter. const LocationContext *LC = Pred->getLocationContext(); unsigned BlockId = L.getBlock()->getBlockID(); BlockCounter Counter = WList->getBlockCounter(); - Counter = BCounterFactory.IncrementCount(Counter, LC->getStackFrame(), - BlockId); + Counter = + BCounterFactory.IncrementCount(Counter, LC->getStackFrame(), BlockId); setBlockCounter(Counter); // Process the entrance of the block. @@ -321,115 +314,116 @@ void CoreEngine::HandleBlockEntrance(const BlockEntrance &L, HandleBlockExit(L.getBlock(), Pred); } -void CoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode *Pred) { +void CoreEngine::HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred) { if (const Stmt *Term = B->getTerminatorStmt()) { switch (Term->getStmtClass()) { - default: - llvm_unreachable("Analysis for this terminator not implemented."); - - case Stmt::CXXBindTemporaryExprClass: - HandleCleanupTemporaryBranch( - cast(Term), B, Pred); - return; - - // Model static initializers. - case Stmt::DeclStmtClass: - HandleStaticInit(cast(Term), B, Pred); - return; - - case Stmt::BinaryOperatorClass: // '&&' and '||' - HandleBranch(cast(Term)->getLHS(), Term, B, Pred); - return; - - case Stmt::BinaryConditionalOperatorClass: - case Stmt::ConditionalOperatorClass: - HandleBranch(cast(Term)->getCond(), - Term, B, Pred); - return; - - // FIXME: Use constant-folding in CFG construction to simplify this - // case. - - case Stmt::ChooseExprClass: - HandleBranch(cast(Term)->getCond(), Term, B, Pred); - return; - - case Stmt::CXXTryStmtClass: - // Generate a node for each of the successors. - // Our logic for EH analysis can certainly be improved. - for (CFGBlock::const_succ_iterator it = B->succ_begin(), - et = B->succ_end(); it != et; ++it) { - if (const CFGBlock *succ = *it) { - generateNode(BlockEdge(B, succ, Pred->getLocationContext()), - Pred->State, Pred); - } + default: + llvm_unreachable("Analysis for this terminator not implemented."); + + case Stmt::CXXBindTemporaryExprClass: + HandleCleanupTemporaryBranch(cast(Term), B, Pred); + return; + + // Model static initializers. + case Stmt::DeclStmtClass: + HandleStaticInit(cast(Term), B, Pred); + return; + + case Stmt::BinaryOperatorClass: // '&&' and '||' + HandleBranch(cast(Term)->getLHS(), Term, B, Pred); + return; + + case Stmt::BinaryConditionalOperatorClass: + case Stmt::ConditionalOperatorClass: + HandleBranch(cast(Term)->getCond(), Term, B, + Pred); + return; + + // FIXME: Use constant-folding in CFG construction to simplify this + // case. + + case Stmt::ChooseExprClass: + HandleBranch(cast(Term)->getCond(), Term, B, Pred); + return; + + case Stmt::CXXTryStmtClass: + // Generate a node for each of the successors. + // Our logic for EH analysis can certainly be improved. + for (CFGBlock::const_succ_iterator it = B->succ_begin(), + et = B->succ_end(); + it != et; ++it) { + if (const CFGBlock *succ = *it) { + generateNode(BlockEdge(B, succ, Pred->getLocationContext()), + Pred->State, Pred); } - return; + } + return; - case Stmt::DoStmtClass: - HandleBranch(cast(Term)->getCond(), Term, B, Pred); - return; + case Stmt::DoStmtClass: + HandleBranch(cast(Term)->getCond(), Term, B, Pred); + return; - case Stmt::CXXForRangeStmtClass: - HandleBranch(cast(Term)->getCond(), Term, B, Pred); - return; + case Stmt::CXXForRangeStmtClass: + HandleBranch(cast(Term)->getCond(), Term, B, Pred); + return; - case Stmt::ForStmtClass: - HandleBranch(cast(Term)->getCond(), Term, B, Pred); - return; + case Stmt::ForStmtClass: + HandleBranch(cast(Term)->getCond(), Term, B, Pred); + return; - case Stmt::SEHLeaveStmtClass: - case Stmt::ContinueStmtClass: - case Stmt::BreakStmtClass: - case Stmt::GotoStmtClass: - break; + case Stmt::SEHLeaveStmtClass: + case Stmt::ContinueStmtClass: + case Stmt::BreakStmtClass: + case Stmt::GotoStmtClass: + break; - case Stmt::IfStmtClass: - HandleBranch(cast(Term)->getCond(), Term, B, Pred); - return; + case Stmt::IfStmtClass: + HandleBranch(cast(Term)->getCond(), Term, B, Pred); + return; - case Stmt::IndirectGotoStmtClass: { - // Only 1 successor: the indirect goto dispatch block. - assert(B->succ_size() == 1); + case Stmt::IndirectGotoStmtClass: { + // Only 1 successor: the indirect goto dispatch block. + assert(B->succ_size() == 1); - IndirectGotoNodeBuilder - builder(Pred, B, cast(Term)->getTarget(), - *(B->succ_begin()), this); + IndirectGotoNodeBuilder builder(Pred, B, + cast(Term)->getTarget(), + *(B->succ_begin()), this); - ExprEng.processIndirectGoto(builder); - return; - } + ExprEng.processIndirectGoto(builder); + return; + } - case Stmt::ObjCForCollectionStmtClass: - // In the case of ObjCForCollectionStmt, it appears twice in a CFG: - // - // (1) inside a basic block, which represents the binding of the - // 'element' variable to a value. - // (2) in a terminator, which represents the branch. - // - // For (1), ExprEngine will bind a value (i.e., 0 or 1) indicating - // whether or not collection contains any more elements. We cannot - // just test to see if the element is nil because a container can - // contain nil elements. - HandleBranch(Term, Term, B, Pred); - return; - - case Stmt::SwitchStmtClass: { - SwitchNodeBuilder builder(Pred, B, cast(Term)->getCond(), - this); - - ExprEng.processSwitch(builder); - return; - } + case Stmt::ObjCForCollectionStmtClass: + // In the case of ObjCForCollectionStmt, it appears twice in a CFG: + // + // (1) inside a basic block, which represents the binding of the + // 'element' variable to a value. + // (2) in a terminator, which represents the branch. + // + // For (1), ExprEngine will bind a value (i.e., 0 or 1) indicating + // whether or not collection contains any more elements. We cannot + // just test to see if the element is nil because a container can + // contain nil elements. + HandleBranch(Term, Term, B, Pred); + return; - case Stmt::WhileStmtClass: - HandleBranch(cast(Term)->getCond(), Term, B, Pred); - return; + case Stmt::SwitchStmtClass: { + SwitchNodeBuilder builder(Pred, B, cast(Term)->getCond(), + this); - case Stmt::GCCAsmStmtClass: - assert(cast(Term)->isAsmGoto() && "Encountered GCCAsmStmt without labels"); - // TODO: Handle jumping to labels - return; + ExprEng.processSwitch(builder); + return; + } + + case Stmt::WhileStmtClass: + HandleBranch(cast(Term)->getCond(), Term, B, Pred); + return; + + case Stmt::GCCAsmStmtClass: + assert(cast(Term)->isAsmGoto() && + "Encountered GCCAsmStmt without labels"); + // TODO: Handle jumping to labels + return; } } @@ -451,12 +445,12 @@ void CoreEngine::HandleCallEnter(const CallEnter &CE, ExplodedNode *Pred) { } void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term, - const CFGBlock * B, ExplodedNode *Pred) { + const CFGBlock *B, ExplodedNode *Pred) { assert(B->succ_size() == 2); NodeBuilderContext Ctx(*this, B, Pred); ExplodedNodeSet Dst; ExprEng.processBranch(Cond, Ctx, Pred, Dst, *(B->succ_begin()), - *(B->succ_begin() + 1)); + *(B->succ_begin() + 1)); // Enqueue the new frontier onto the worklist. enqueue(Dst); } @@ -468,7 +462,7 @@ void CoreEngine::HandleCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, NodeBuilderContext Ctx(*this, B, Pred); ExplodedNodeSet Dst; ExprEng.processCleanupTemporaryBranch(BTE, Ctx, Pred, Dst, *(B->succ_begin()), - *(B->succ_begin() + 1)); + *(B->succ_begin() + 1)); // Enqueue the new frontier onto the worklist. enqueue(Dst); } @@ -478,8 +472,8 @@ void CoreEngine::HandleStaticInit(const DeclStmt *DS, const CFGBlock *B, assert(B->succ_size() == 2); NodeBuilderContext Ctx(*this, B, Pred); ExplodedNodeSet Dst; - ExprEng.processStaticInitializer(DS, Ctx, Pred, Dst, - *(B->succ_begin()), *(B->succ_begin()+1)); + ExprEng.processStaticInitializer(DS, Ctx, Pred, Dst, *(B->succ_begin()), + *(B->succ_begin() + 1)); // Enqueue the new frontier onto the worklist. enqueue(Dst); } @@ -522,8 +516,7 @@ void CoreEngine::HandleVirtualBaseBranch(const CFGBlock *B, /// generateNode - Utility method to generate nodes, hook up successors, /// and add nodes to the worklist. -void CoreEngine::generateNode(const ProgramPoint &Loc, - ProgramStateRef State, +void CoreEngine::generateNode(const ProgramPoint &Loc, ProgramStateRef State, ExplodedNode *Pred) { bool IsNew; ExplodedNode *Node = G.getNode(Loc, State, false, &IsNew); @@ -536,11 +529,12 @@ void CoreEngine::generateNode(const ProgramPoint &Loc, } // Only add 'Node' to the worklist if it was freshly generated. - if (IsNew) WList->enqueue(Node); + if (IsNew) + WList->enqueue(Node); } -void CoreEngine::enqueueStmtNode(ExplodedNode *N, - const CFGBlock *Block, unsigned Idx) { +void CoreEngine::enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, + unsigned Idx) { assert(Block); assert(!N->isSink()); @@ -554,9 +548,9 @@ void CoreEngine::enqueueStmtNode(ExplodedNode *N, // Do not create extra nodes. Move to the next CFG element. if (N->getLocation().getAs() || - N->getLocation().getAs()|| + N->getLocation().getAs() || N->getLocation().getAs()) { - WList->enqueue(N, Block, Idx+1); + WList->enqueue(N, Block, Idx + 1); return; } @@ -566,7 +560,7 @@ void CoreEngine::enqueueStmtNode(ExplodedNode *N, } if ((*Block)[Idx].getKind() == CFGElement::NewAllocator) { - WList->enqueue(N, Block, Idx+1); + WList->enqueue(N, Block, Idx + 1); return; } @@ -577,7 +571,7 @@ void CoreEngine::enqueueStmtNode(ExplodedNode *N, if (Loc == N->getLocation().withTag(nullptr)) { // Note: 'N' should be a fresh node because otherwise it shouldn't be // a member of Deferred. - WList->enqueue(N, Block, Idx+1); + WList->enqueue(N, Block, Idx + 1); return; } @@ -586,7 +580,7 @@ void CoreEngine::enqueueStmtNode(ExplodedNode *N, Succ->addPredecessor(N, G); if (IsNew) - WList->enqueue(Succ, Block, Idx+1); + WList->enqueue(Succ, Block, Idx + 1); } ExplodedNode *CoreEngine::generateCallExitBeginNode(ExplodedNode *N, @@ -608,13 +602,14 @@ void CoreEngine::enqueue(ExplodedNodeSet &Set) { WList->enqueue(I); } -void CoreEngine::enqueue(ExplodedNodeSet &Set, - const CFGBlock *Block, unsigned Idx) { +void CoreEngine::enqueue(ExplodedNodeSet &Set, const CFGBlock *Block, + unsigned Idx) { for (const auto I : Set) enqueueStmtNode(I, Block, Idx); } -void CoreEngine::enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS) { +void CoreEngine::enqueueEndOfFunction(ExplodedNodeSet &Set, + const ReturnStmt *RS) { for (auto *I : Set) { // If we are in an inlined call, generate CallExitBegin node. if (I->getLocationContext()->getParent()) { @@ -631,7 +626,7 @@ void CoreEngine::enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS void NodeBuilder::anchor() {} -ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc, +ExplodedNode *NodeBuilder::generateNodeImpl(const ProgramPoint &Loc, ProgramStateRef State, ExplodedNode *FromN, bool MarkAsSink) { @@ -667,16 +662,15 @@ ExplodedNode *BranchNodeBuilder::generateNode(ProgramStateRef State, if (!isFeasible(branch)) return nullptr; - ProgramPoint Loc = BlockEdge(C.Block, branch ? DstT:DstF, - NodePred->getLocationContext()); + ProgramPoint Loc = + BlockEdge(C.Block, branch ? DstT : DstF, NodePred->getLocationContext()); ExplodedNode *Succ = generateNodeImpl(Loc, State, NodePred); return Succ; } -ExplodedNode* -IndirectGotoNodeBuilder::generateNode(const iterator &I, - ProgramStateRef St, - bool IsSink) { +ExplodedNode *IndirectGotoNodeBuilder::generateNode(const iterator &I, + ProgramStateRef St, + bool IsSink) { bool IsNew; ExplodedNode *Succ = Eng.G.getNode(BlockEdge(Src, I.getBlock(), Pred->getLocationContext()), @@ -692,9 +686,8 @@ IndirectGotoNodeBuilder::generateNode(const iterator &I, return Succ; } -ExplodedNode* -SwitchNodeBuilder::generateCaseStmtNode(const iterator &I, - ProgramStateRef St) { +ExplodedNode *SwitchNodeBuilder::generateCaseStmtNode(const iterator &I, + ProgramStateRef St) { bool IsNew; ExplodedNode *Succ = Eng.G.getNode(BlockEdge(Src, I.getBlock(), Pred->getLocationContext()), @@ -707,9 +700,8 @@ SwitchNodeBuilder::generateCaseStmtNode(const iterator &I, return Succ; } -ExplodedNode* -SwitchNodeBuilder::generateDefaultCaseNode(ProgramStateRef St, - bool IsSink) { +ExplodedNode *SwitchNodeBuilder::generateDefaultCaseNode(ProgramStateRef St, + bool IsSink) { // Get the block for the default case. assert(Src->succ_rbegin() != Src->succ_rend()); CFGBlock *DefaultBlock = *Src->succ_rbegin(); diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp index 427f51109853b..4b12f6ca72936 100644 --- a/clang/lib/StaticAnalyzer/Core/Environment.cpp +++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp @@ -72,13 +72,11 @@ static const Stmt *ignoreTransparentExprs(const Stmt *S) { } EnvironmentEntry::EnvironmentEntry(const Stmt *S, const LocationContext *L) - : std::pair(ignoreTransparentExprs(S), - L ? L->getStackFrame() - : nullptr) {} + : std::pair( + ignoreTransparentExprs(S), L ? L->getStackFrame() : nullptr) {} SVal Environment::lookupExpr(const EnvironmentEntry &E) const { - const SVal* X = ExprBindings.lookup(E); + const SVal *X = ExprBindings.lookup(E); if (X) { SVal V = *X; return V; @@ -87,7 +85,7 @@ SVal Environment::lookupExpr(const EnvironmentEntry &E) const { } SVal Environment::getSVal(const EnvironmentEntry &Entry, - SValBuilder& svalBuilder) const { + SValBuilder &svalBuilder) const { const Stmt *S = Entry.getStmt(); assert(!isa(S) && "Use ExprEngine::hasMoreIteration()!"); @@ -136,8 +134,7 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry, } Environment EnvironmentManager::bindExpr(Environment Env, - const EnvironmentEntry &E, - SVal V, + const EnvironmentEntry &E, SVal V, bool Invalidate) { if (V.isUnknown()) { if (Invalidate) @@ -176,10 +173,9 @@ class MarkLiveCallback final : public SymbolVisitor { // - Mark their reachable symbols live in SymbolReaper, // see ScanReachableSymbols. // - Mark the region in DRoots if the binding is a loc::MemRegionVal. -Environment -EnvironmentManager::removeDeadBindings(Environment Env, - SymbolReaper &SymReaper, - ProgramStateRef ST) { +Environment EnvironmentManager::removeDeadBindings(Environment Env, + SymbolReaper &SymReaper, + ProgramStateRef ST) { // We construct a new Environment object entirely, as this is cheaper than // individually removing all the subexpression bindings (which will greatly // outnumber block-level expression bindings). @@ -188,9 +184,8 @@ EnvironmentManager::removeDeadBindings(Environment Env, MarkLiveCallback CB(SymReaper); ScanReachableSymbols RSScaner(ST, CB); - llvm::ImmutableMapRef - EBMapRef(NewEnv.ExprBindings.getRootWithoutRetain(), - F.getTreeFactory()); + llvm::ImmutableMapRef EBMapRef( + NewEnv.ExprBindings.getRootWithoutRetain(), F.getTreeFactory()); // Iterate over the block-expr bindings. for (Environment::iterator I = Env.begin(), End = Env.end(); I != End; ++I) { diff --git a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index f84da769d182f..cf22c823b47a1 100644 --- a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -210,7 +210,7 @@ void ExplodedNode::addPredecessor(ExplodedNode *V, ExplodedGraph &G) { void ExplodedNode::NodeGroup::replaceNode(ExplodedNode *node) { assert(!getFlag()); - GroupStorage &Storage = reinterpret_cast(P); + GroupStorage &Storage = reinterpret_cast(P); assert(Storage.is()); Storage = node; assert(Storage.is()); @@ -219,7 +219,7 @@ void ExplodedNode::NodeGroup::replaceNode(ExplodedNode *node) { void ExplodedNode::NodeGroup::addNode(ExplodedNode *N, ExplodedGraph &G) { assert(!getFlag()); - GroupStorage &Storage = reinterpret_cast(P); + GroupStorage &Storage = reinterpret_cast(P); if (Storage.isNull()) { Storage = N; assert(Storage.is()); @@ -256,7 +256,7 @@ unsigned ExplodedNode::NodeGroup::size() const { return 1; } -ExplodedNode * const *ExplodedNode::NodeGroup::begin() const { +ExplodedNode *const *ExplodedNode::NodeGroup::begin() const { if (getFlag()) return nullptr; @@ -268,7 +268,7 @@ ExplodedNode * const *ExplodedNode::NodeGroup::begin() const { return Storage.getAddrOfPtr1(); } -ExplodedNode * const *ExplodedNode::NodeGroup::end() const { +ExplodedNode *const *ExplodedNode::NodeGroup::end() const { if (getFlag()) return nullptr; @@ -353,18 +353,18 @@ const Stmt *ExplodedNode::getNextStmtForDiagnostics() const { // Check if the statement is '?' or '&&'/'||'. These are "merges", // not actual statement points. switch (S->getStmtClass()) { - case Stmt::ChooseExprClass: - case Stmt::BinaryConditionalOperatorClass: - case Stmt::ConditionalOperatorClass: + case Stmt::ChooseExprClass: + case Stmt::BinaryConditionalOperatorClass: + case Stmt::ConditionalOperatorClass: + continue; + case Stmt::BinaryOperatorClass: { + BinaryOperatorKind Op = cast(S)->getOpcode(); + if (Op == BO_LAnd || Op == BO_LOr) continue; - case Stmt::BinaryOperatorClass: { - BinaryOperatorKind Op = cast(S)->getOpcode(); - if (Op == BO_LAnd || Op == BO_LOr) - continue; - break; - } - default: - break; + break; + } + default: + break; } // We found the statement, so return it. return S; @@ -390,22 +390,20 @@ const Stmt *ExplodedNode::getCurrentOrPreviousStmtForDiagnostics() const { } ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L, - ProgramStateRef State, - bool IsSink, - bool* IsNew) { + ProgramStateRef State, bool IsSink, + bool *IsNew) { // Profile 'State' to determine if we already have an existing node. llvm::FoldingSetNodeID profile; void *InsertPos = nullptr; NodeTy::Profile(profile, L, State, IsSink); - NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos); + NodeTy *V = Nodes.FindNodeOrInsertPos(profile, InsertPos); if (!V) { if (!FreeNodes.empty()) { V = FreeNodes.back(); FreeNodes.pop_back(); - } - else { + } else { // Allocate a new node. V = getAllocator().Allocate(); } @@ -419,18 +417,17 @@ ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L, // Insert the node into the node set and return it. Nodes.InsertNode(V, InsertPos); - if (IsNew) *IsNew = true; - } - else - if (IsNew) *IsNew = false; + if (IsNew) + *IsNew = true; + } else if (IsNew) + *IsNew = false; return V; } ExplodedNode *ExplodedGraph::createUncachedNode(const ProgramPoint &L, ProgramStateRef State, - int64_t Id, - bool IsSink) { + int64_t Id, bool IsSink) { NodeTy *V = getAllocator().Allocate(); new (V) NodeTy(L, State, Id, IsSink); return V; @@ -450,7 +447,7 @@ ExplodedGraph::trim(ArrayRef Sinks, InterExplodedGraphMap Pass2Scratch; Pass2Ty &Pass2 = ForwardMap ? *ForwardMap : Pass2Scratch; - SmallVector WL1, WL2; + SmallVector WL1, WL2; // ===- Pass 1 (reverse DFS) -=== for (const auto Sink : Sinks) @@ -497,7 +494,8 @@ ExplodedGraph::trim(ArrayRef Sinks, Pass2[N] = NewN; // Also record the reverse mapping from the new node to the old node. - if (InverseMap) (*InverseMap)[NewN] = N; + if (InverseMap) + (*InverseMap)[NewN] = N; // If this node is a root, designate it as such in the graph. if (N->Preds.empty()) diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 09c69f9612d96..a655eb216a8ff 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -89,16 +89,15 @@ using namespace ento; #define DEBUG_TYPE "ExprEngine" -STATISTIC(NumRemoveDeadBindings, - "The # of times RemoveDeadBindings is called"); +STATISTIC(NumRemoveDeadBindings, "The # of times RemoveDeadBindings is called"); STATISTIC(NumMaxBlockCountReached, - "The # of aborted paths due to reaching the maximum block count in " - "a top level function"); + "The # of aborted paths due to reaching the maximum block count in " + "a top level function"); STATISTIC(NumMaxBlockCountReachedInInlined, - "The # of aborted paths due to reaching the maximum block count in " - "an inlined function"); + "The # of aborted paths due to reaching the maximum block count in " + "an inlined function"); STATISTIC(NumTimesRetriedWithoutInlining, - "The # of times we re-evaluated a call without inlining"); + "The # of times we re-evaluated a call without inlining"); //===----------------------------------------------------------------------===// // Internal program state traits. @@ -126,7 +125,7 @@ class ConstructedObjectKey { public: explicit ConstructedObjectKey(const ConstructionContextItem &Item, - const LocationContext *LC) + const LocationContext *LC) : Impl(Item, LC) {} const ConstructionContextItem &getItem() const { return Impl.first; } @@ -216,7 +215,7 @@ REGISTER_TRAIT_WITH_PROGRAMSTATE(PendingArrayDestruction, // Engine construction and deletion. //===----------------------------------------------------------------------===// -static const char* TagProviderName = "ExprEngine"; +static const char *TagProviderName = "ExprEngine"; ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn, @@ -267,9 +266,9 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { break; SVal V = state->getSVal(loc::MemRegionVal(R)); - SVal Constraint_untested = evalBinOp(state, BO_GT, V, - svalBuilder.makeZeroVal(T), - svalBuilder.getConditionType()); + SVal Constraint_untested = + evalBinOp(state, BO_GT, V, svalBuilder.makeZeroVal(T), + svalBuilder.getConditionType()); std::optional Constraint = Constraint_untested.getAs(); @@ -281,8 +280,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { state = newState; } break; - } - while (false); + } while (false); if (const auto *MD = dyn_cast(D)) { // Precondition: 'self' is always non-null upon entry to an Objective-C @@ -657,28 +655,23 @@ bool ExprEngine::areAllObjectsFullyConstructed(ProgramStateRef State, return true; } - //===----------------------------------------------------------------------===// // Top-level transfer function logic (Dispatcher). //===----------------------------------------------------------------------===// /// evalAssume - Called by ConstraintManager. Used to call checker-specific /// logic for handling assumptions on symbolic values. -ProgramStateRef ExprEngine::processAssume(ProgramStateRef state, - SVal cond, bool assumption) { +ProgramStateRef ExprEngine::processAssume(ProgramStateRef state, SVal cond, + bool assumption) { return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption); } -ProgramStateRef -ExprEngine::processRegionChanges(ProgramStateRef state, - const InvalidatedSymbols *invalidated, - ArrayRef Explicits, - ArrayRef Regions, - const LocationContext *LCtx, - const CallEvent *Call) { - return getCheckerManager().runCheckersForRegionChanges(state, invalidated, - Explicits, Regions, - LCtx, Call); +ProgramStateRef ExprEngine::processRegionChanges( + ProgramStateRef state, const InvalidatedSymbols *invalidated, + ArrayRef Explicits, ArrayRef Regions, + const LocationContext *LCtx, const CallEvent *Call) { + return getCheckerManager().runCheckersForRegionChanges( + state, invalidated, Explicits, Regions, LCtx, Call); } static void @@ -970,38 +963,36 @@ void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred, currBldrCtx = Ctx; switch (E.getKind()) { - case CFGElement::Statement: - case CFGElement::Constructor: - case CFGElement::CXXRecordTypedCall: - ProcessStmt(E.castAs().getStmt(), Pred); - return; - case CFGElement::Initializer: - ProcessInitializer(E.castAs(), Pred); - return; - case CFGElement::NewAllocator: - ProcessNewAllocator(E.castAs().getAllocatorExpr(), - Pred); - return; - case CFGElement::AutomaticObjectDtor: - case CFGElement::DeleteDtor: - case CFGElement::BaseDtor: - case CFGElement::MemberDtor: - case CFGElement::TemporaryDtor: - ProcessImplicitDtor(E.castAs(), Pred); - return; - case CFGElement::LoopExit: - ProcessLoopExit(E.castAs().getLoopStmt(), Pred); - return; - case CFGElement::LifetimeEnds: - case CFGElement::CleanupFunction: - case CFGElement::ScopeBegin: - case CFGElement::ScopeEnd: - return; + case CFGElement::Statement: + case CFGElement::Constructor: + case CFGElement::CXXRecordTypedCall: + ProcessStmt(E.castAs().getStmt(), Pred); + return; + case CFGElement::Initializer: + ProcessInitializer(E.castAs(), Pred); + return; + case CFGElement::NewAllocator: + ProcessNewAllocator(E.castAs().getAllocatorExpr(), Pred); + return; + case CFGElement::AutomaticObjectDtor: + case CFGElement::DeleteDtor: + case CFGElement::BaseDtor: + case CFGElement::MemberDtor: + case CFGElement::TemporaryDtor: + ProcessImplicitDtor(E.castAs(), Pred); + return; + case CFGElement::LoopExit: + ProcessLoopExit(E.castAs().getLoopStmt(), Pred); + return; + case CFGElement::LifetimeEnds: + case CFGElement::CleanupFunction: + case CFGElement::ScopeBegin: + case CFGElement::ScopeEnd: + return; } } -static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, - const Stmt *S, +static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S, const ExplodedNode *Pred, const LocationContext *LC) { // Are we never purging state values? @@ -1029,11 +1020,10 @@ static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const LocationContext *LC, - const Stmt *DiagnosticStmt, - ProgramPoint::Kind K) { + const Stmt *DiagnosticStmt, ProgramPoint::Kind K) { assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind || - ReferenceStmt == nullptr || isa(ReferenceStmt)) - && "PostStmt is not generally supported by the SymbolReaper yet"); + ReferenceStmt == nullptr || isa(ReferenceStmt)) && + "PostStmt is not generally supported by the SymbolReaper yet"); assert(LC && "Must pass the current (or expiring) LocationContext"); if (!DiagnosticStmt) { @@ -1118,8 +1108,7 @@ void ExprEngine::ProcessStmt(const Stmt *currStmt, ExplodedNode *Pred) { ExplodedNodeSet CleanedStates; if (shouldRemoveDeadBindings(AMgr, currStmt, Pred, Pred->getLocationContext())) { - removeDead(Pred, CleanedStates, currStmt, - Pred->getLocationContext()); + removeDead(Pred, CleanedStates, currStmt, Pred->getLocationContext()); } else CleanedStates.Add(Pred); @@ -1136,7 +1125,7 @@ void ExprEngine::ProcessStmt(const Stmt *currStmt, ExplodedNode *Pred) { Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); } -void ExprEngine::ProcessLoopExit(const Stmt* S, ExplodedNode *Pred) { +void ExprEngine::ProcessLoopExit(const Stmt *S, ExplodedNode *Pred) { PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), S->getBeginLoc(), "Error evaluating end of the loop"); @@ -1145,7 +1134,7 @@ void ExprEngine::ProcessLoopExit(const Stmt* S, ExplodedNode *Pred) { NodeBuilder Bldr(Pred, Dst, *currBldrCtx); ProgramStateRef NewState = Pred->getState(); - if(AMgr.options.ShouldUnrollLoops) + if (AMgr.options.ShouldUnrollLoops) NewState = processLoopEnd(S, NewState); LoopExit PP(S, Pred->getLocationContext()); @@ -1211,9 +1200,9 @@ void ExprEngine::ProcessInitializer(const CFGInitializer CFGInit, // If we fail to get the value for some reason, use a symbolic value. if (InitVal.isUnknownOrUndef()) { SValBuilder &SVB = getSValBuilder(); - InitVal = SVB.conjureSymbolVal(BMI->getInit(), stackFrame, - Field->getType(), - currBldrCtx->blockCount()); + InitVal = + SVB.conjureSymbolVal(BMI->getInit(), stackFrame, Field->getType(), + currBldrCtx->blockCount()); } } else { InitVal = State->getSVal(BMI->getInit(), stackFrame); @@ -1314,8 +1303,7 @@ void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); } -void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE, - ExplodedNode *Pred) { +void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred) { ExplodedNodeSet Dst; AnalysisManager &AMgr = getAnalysisManager(); AnalyzerOptions &Opts = AMgr.options; @@ -1406,8 +1394,7 @@ void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor, /*IsBase=*/false, Pred, Dst, CallOpts); } -void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, - ExplodedNode *Pred, +void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, ExplodedNode *Pred, ExplodedNodeSet &Dst) { ProgramStateRef State = Pred->getState(); const LocationContext *LCtx = Pred->getLocationContext(); @@ -1482,28 +1469,27 @@ void ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, VisitCXXDestructor(DTy, ArgR, DE, /*IsBase=*/false, Pred, Dst, CallOpts); } -void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, - ExplodedNode *Pred, ExplodedNodeSet &Dst) { +void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, + ExplodedNodeSet &Dst) { const LocationContext *LCtx = Pred->getLocationContext(); const auto *CurDtor = cast(LCtx->getDecl()); - Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, - LCtx->getStackFrame()); + Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, LCtx->getStackFrame()); SVal ThisVal = Pred->getState()->getSVal(ThisPtr); // Create the base object region. const CXXBaseSpecifier *Base = D.getBaseSpecifier(); QualType BaseTy = Base->getType(); - SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy, - Base->isVirtual()); + SVal BaseVal = + getStoreManager().evalDerivedToBase(ThisVal, BaseTy, Base->isVirtual()); EvalCallOptions CallOpts; VisitCXXDestructor(BaseTy, BaseVal.getAsRegion(), CurDtor->getBody(), /*IsBase=*/true, Pred, Dst, CallOpts); } -void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, - ExplodedNode *Pred, ExplodedNodeSet &Dst) { +void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, + ExplodedNodeSet &Dst) { const auto *DtorDecl = D.getDestructorDecl(getContext()); const FieldDecl *Member = D.getFieldDecl(); QualType T = Member->getType(); @@ -1683,8 +1669,7 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, } ProgramStateRef ExprEngine::escapeValues(ProgramStateRef State, - ArrayRef Vs, - PointerEscapeKind K, + ArrayRef Vs, PointerEscapeKind K, const CallEvent *Call) const { class CollectReachableSymbolsCallback final : public SymbolVisitor { InvalidatedSymbols &Symbols; @@ -1719,708 +1704,701 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, assert(!isa(S) || S == cast(S)->IgnoreParens()); switch (S->getStmtClass()) { - // C++, OpenMP and ARC stuff we don't support yet. - case Stmt::CXXDependentScopeMemberExprClass: - case Stmt::CXXTryStmtClass: - case Stmt::CXXTypeidExprClass: - case Stmt::CXXUuidofExprClass: - case Stmt::CXXFoldExprClass: - case Stmt::MSPropertyRefExprClass: - case Stmt::MSPropertySubscriptExprClass: - case Stmt::CXXUnresolvedConstructExprClass: - case Stmt::DependentScopeDeclRefExprClass: - case Stmt::ArrayTypeTraitExprClass: - case Stmt::ExpressionTraitExprClass: - case Stmt::UnresolvedLookupExprClass: - case Stmt::UnresolvedMemberExprClass: - case Stmt::TypoExprClass: - case Stmt::RecoveryExprClass: - case Stmt::CXXNoexceptExprClass: - case Stmt::PackExpansionExprClass: - case Stmt::PackIndexingExprClass: - case Stmt::SubstNonTypeTemplateParmPackExprClass: - case Stmt::FunctionParmPackExprClass: - case Stmt::CoroutineBodyStmtClass: - case Stmt::CoawaitExprClass: - case Stmt::DependentCoawaitExprClass: - case Stmt::CoreturnStmtClass: - case Stmt::CoyieldExprClass: - case Stmt::SEHTryStmtClass: - case Stmt::SEHExceptStmtClass: - case Stmt::SEHLeaveStmtClass: - case Stmt::SEHFinallyStmtClass: - case Stmt::OMPCanonicalLoopClass: - case Stmt::OMPParallelDirectiveClass: - case Stmt::OMPSimdDirectiveClass: - case Stmt::OMPForDirectiveClass: - case Stmt::OMPForSimdDirectiveClass: - case Stmt::OMPSectionsDirectiveClass: - case Stmt::OMPSectionDirectiveClass: - case Stmt::OMPScopeDirectiveClass: - case Stmt::OMPSingleDirectiveClass: - case Stmt::OMPMasterDirectiveClass: - case Stmt::OMPCriticalDirectiveClass: - case Stmt::OMPParallelForDirectiveClass: - case Stmt::OMPParallelForSimdDirectiveClass: - case Stmt::OMPParallelSectionsDirectiveClass: - case Stmt::OMPParallelMasterDirectiveClass: - case Stmt::OMPParallelMaskedDirectiveClass: - case Stmt::OMPTaskDirectiveClass: - case Stmt::OMPTaskyieldDirectiveClass: - case Stmt::OMPBarrierDirectiveClass: - case Stmt::OMPTaskwaitDirectiveClass: - case Stmt::OMPErrorDirectiveClass: - case Stmt::OMPTaskgroupDirectiveClass: - case Stmt::OMPFlushDirectiveClass: - case Stmt::OMPDepobjDirectiveClass: - case Stmt::OMPScanDirectiveClass: - case Stmt::OMPOrderedDirectiveClass: - case Stmt::OMPAtomicDirectiveClass: - case Stmt::OMPTargetDirectiveClass: - case Stmt::OMPTargetDataDirectiveClass: - case Stmt::OMPTargetEnterDataDirectiveClass: - case Stmt::OMPTargetExitDataDirectiveClass: - case Stmt::OMPTargetParallelDirectiveClass: - case Stmt::OMPTargetParallelForDirectiveClass: - case Stmt::OMPTargetUpdateDirectiveClass: - case Stmt::OMPTeamsDirectiveClass: - case Stmt::OMPCancellationPointDirectiveClass: - case Stmt::OMPCancelDirectiveClass: - case Stmt::OMPTaskLoopDirectiveClass: - case Stmt::OMPTaskLoopSimdDirectiveClass: - case Stmt::OMPMasterTaskLoopDirectiveClass: - case Stmt::OMPMaskedTaskLoopDirectiveClass: - case Stmt::OMPMasterTaskLoopSimdDirectiveClass: - case Stmt::OMPMaskedTaskLoopSimdDirectiveClass: - case Stmt::OMPParallelMasterTaskLoopDirectiveClass: - case Stmt::OMPParallelMaskedTaskLoopDirectiveClass: - case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass: - case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass: - case Stmt::OMPDistributeDirectiveClass: - case Stmt::OMPDistributeParallelForDirectiveClass: - case Stmt::OMPDistributeParallelForSimdDirectiveClass: - case Stmt::OMPDistributeSimdDirectiveClass: - case Stmt::OMPTargetParallelForSimdDirectiveClass: - case Stmt::OMPTargetSimdDirectiveClass: - case Stmt::OMPTeamsDistributeDirectiveClass: - case Stmt::OMPTeamsDistributeSimdDirectiveClass: - case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: - case Stmt::OMPTeamsDistributeParallelForDirectiveClass: - case Stmt::OMPTargetTeamsDirectiveClass: - case Stmt::OMPTargetTeamsDistributeDirectiveClass: - case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: - case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: - case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: - case Stmt::OMPTileDirectiveClass: - case Stmt::OMPInteropDirectiveClass: - case Stmt::OMPDispatchDirectiveClass: - case Stmt::OMPMaskedDirectiveClass: - case Stmt::OMPGenericLoopDirectiveClass: - case Stmt::OMPTeamsGenericLoopDirectiveClass: - case Stmt::OMPTargetTeamsGenericLoopDirectiveClass: - case Stmt::OMPParallelGenericLoopDirectiveClass: - case Stmt::OMPTargetParallelGenericLoopDirectiveClass: - case Stmt::CapturedStmtClass: - case Stmt::OpenACCComputeConstructClass: - case Stmt::OMPUnrollDirectiveClass: - case Stmt::OMPMetaDirectiveClass: { - const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); - Engine.addAbortedBlock(node, currBldrCtx->getBlock()); - break; - } + // C++, OpenMP and ARC stuff we don't support yet. + case Stmt::CXXDependentScopeMemberExprClass: + case Stmt::CXXTryStmtClass: + case Stmt::CXXTypeidExprClass: + case Stmt::CXXUuidofExprClass: + case Stmt::CXXFoldExprClass: + case Stmt::MSPropertyRefExprClass: + case Stmt::MSPropertySubscriptExprClass: + case Stmt::CXXUnresolvedConstructExprClass: + case Stmt::DependentScopeDeclRefExprClass: + case Stmt::ArrayTypeTraitExprClass: + case Stmt::ExpressionTraitExprClass: + case Stmt::UnresolvedLookupExprClass: + case Stmt::UnresolvedMemberExprClass: + case Stmt::TypoExprClass: + case Stmt::RecoveryExprClass: + case Stmt::CXXNoexceptExprClass: + case Stmt::PackExpansionExprClass: + case Stmt::PackIndexingExprClass: + case Stmt::SubstNonTypeTemplateParmPackExprClass: + case Stmt::FunctionParmPackExprClass: + case Stmt::CoroutineBodyStmtClass: + case Stmt::CoawaitExprClass: + case Stmt::DependentCoawaitExprClass: + case Stmt::CoreturnStmtClass: + case Stmt::CoyieldExprClass: + case Stmt::SEHTryStmtClass: + case Stmt::SEHExceptStmtClass: + case Stmt::SEHLeaveStmtClass: + case Stmt::SEHFinallyStmtClass: + case Stmt::OMPCanonicalLoopClass: + case Stmt::OMPParallelDirectiveClass: + case Stmt::OMPSimdDirectiveClass: + case Stmt::OMPForDirectiveClass: + case Stmt::OMPForSimdDirectiveClass: + case Stmt::OMPSectionsDirectiveClass: + case Stmt::OMPSectionDirectiveClass: + case Stmt::OMPScopeDirectiveClass: + case Stmt::OMPSingleDirectiveClass: + case Stmt::OMPMasterDirectiveClass: + case Stmt::OMPCriticalDirectiveClass: + case Stmt::OMPParallelForDirectiveClass: + case Stmt::OMPParallelForSimdDirectiveClass: + case Stmt::OMPParallelSectionsDirectiveClass: + case Stmt::OMPParallelMasterDirectiveClass: + case Stmt::OMPParallelMaskedDirectiveClass: + case Stmt::OMPTaskDirectiveClass: + case Stmt::OMPTaskyieldDirectiveClass: + case Stmt::OMPBarrierDirectiveClass: + case Stmt::OMPTaskwaitDirectiveClass: + case Stmt::OMPErrorDirectiveClass: + case Stmt::OMPTaskgroupDirectiveClass: + case Stmt::OMPFlushDirectiveClass: + case Stmt::OMPDepobjDirectiveClass: + case Stmt::OMPScanDirectiveClass: + case Stmt::OMPOrderedDirectiveClass: + case Stmt::OMPAtomicDirectiveClass: + case Stmt::OMPTargetDirectiveClass: + case Stmt::OMPTargetDataDirectiveClass: + case Stmt::OMPTargetEnterDataDirectiveClass: + case Stmt::OMPTargetExitDataDirectiveClass: + case Stmt::OMPTargetParallelDirectiveClass: + case Stmt::OMPTargetParallelForDirectiveClass: + case Stmt::OMPTargetUpdateDirectiveClass: + case Stmt::OMPTeamsDirectiveClass: + case Stmt::OMPCancellationPointDirectiveClass: + case Stmt::OMPCancelDirectiveClass: + case Stmt::OMPTaskLoopDirectiveClass: + case Stmt::OMPTaskLoopSimdDirectiveClass: + case Stmt::OMPMasterTaskLoopDirectiveClass: + case Stmt::OMPMaskedTaskLoopDirectiveClass: + case Stmt::OMPMasterTaskLoopSimdDirectiveClass: + case Stmt::OMPMaskedTaskLoopSimdDirectiveClass: + case Stmt::OMPParallelMasterTaskLoopDirectiveClass: + case Stmt::OMPParallelMaskedTaskLoopDirectiveClass: + case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass: + case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass: + case Stmt::OMPDistributeDirectiveClass: + case Stmt::OMPDistributeParallelForDirectiveClass: + case Stmt::OMPDistributeParallelForSimdDirectiveClass: + case Stmt::OMPDistributeSimdDirectiveClass: + case Stmt::OMPTargetParallelForSimdDirectiveClass: + case Stmt::OMPTargetSimdDirectiveClass: + case Stmt::OMPTeamsDistributeDirectiveClass: + case Stmt::OMPTeamsDistributeSimdDirectiveClass: + case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: + case Stmt::OMPTeamsDistributeParallelForDirectiveClass: + case Stmt::OMPTargetTeamsDirectiveClass: + case Stmt::OMPTargetTeamsDistributeDirectiveClass: + case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: + case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: + case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: + case Stmt::OMPTileDirectiveClass: + case Stmt::OMPInteropDirectiveClass: + case Stmt::OMPDispatchDirectiveClass: + case Stmt::OMPMaskedDirectiveClass: + case Stmt::OMPGenericLoopDirectiveClass: + case Stmt::OMPTeamsGenericLoopDirectiveClass: + case Stmt::OMPTargetTeamsGenericLoopDirectiveClass: + case Stmt::OMPParallelGenericLoopDirectiveClass: + case Stmt::OMPTargetParallelGenericLoopDirectiveClass: + case Stmt::CapturedStmtClass: + case Stmt::OpenACCComputeConstructClass: + case Stmt::OMPUnrollDirectiveClass: + case Stmt::OMPMetaDirectiveClass: { + const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); + Engine.addAbortedBlock(node, currBldrCtx->getBlock()); + break; + } - case Stmt::ParenExprClass: - llvm_unreachable("ParenExprs already handled."); - case Stmt::GenericSelectionExprClass: - llvm_unreachable("GenericSelectionExprs already handled."); - // Cases that should never be evaluated simply because they shouldn't - // appear in the CFG. - case Stmt::BreakStmtClass: - case Stmt::CaseStmtClass: - case Stmt::CompoundStmtClass: - case Stmt::ContinueStmtClass: - case Stmt::CXXForRangeStmtClass: - case Stmt::DefaultStmtClass: - case Stmt::DoStmtClass: - case Stmt::ForStmtClass: - case Stmt::GotoStmtClass: - case Stmt::IfStmtClass: - case Stmt::IndirectGotoStmtClass: - case Stmt::LabelStmtClass: - case Stmt::NoStmtClass: - case Stmt::NullStmtClass: - case Stmt::SwitchStmtClass: - case Stmt::WhileStmtClass: - case Expr::MSDependentExistsStmtClass: - llvm_unreachable("Stmt should not be in analyzer evaluation loop"); - case Stmt::ImplicitValueInitExprClass: - // These nodes are shared in the CFG and would case caching out. - // Moreover, no additional evaluation required for them, the - // analyzer can reconstruct these values from the AST. - llvm_unreachable("Should be pruned from CFG"); - - case Stmt::ObjCSubscriptRefExprClass: - case Stmt::ObjCPropertyRefExprClass: - llvm_unreachable("These are handled by PseudoObjectExpr"); - - case Stmt::GNUNullExprClass: { - // GNU __null is a pointer-width integer, not an actual pointer. - ProgramStateRef state = Pred->getState(); - state = state->BindExpr( - S, Pred->getLocationContext(), - svalBuilder.makeIntValWithWidth(getContext().VoidPtrTy, 0)); - Bldr.generateNode(S, Pred, state); - break; - } + case Stmt::ParenExprClass: + llvm_unreachable("ParenExprs already handled."); + case Stmt::GenericSelectionExprClass: + llvm_unreachable("GenericSelectionExprs already handled."); + // Cases that should never be evaluated simply because they shouldn't + // appear in the CFG. + case Stmt::BreakStmtClass: + case Stmt::CaseStmtClass: + case Stmt::CompoundStmtClass: + case Stmt::ContinueStmtClass: + case Stmt::CXXForRangeStmtClass: + case Stmt::DefaultStmtClass: + case Stmt::DoStmtClass: + case Stmt::ForStmtClass: + case Stmt::GotoStmtClass: + case Stmt::IfStmtClass: + case Stmt::IndirectGotoStmtClass: + case Stmt::LabelStmtClass: + case Stmt::NoStmtClass: + case Stmt::NullStmtClass: + case Stmt::SwitchStmtClass: + case Stmt::WhileStmtClass: + case Expr::MSDependentExistsStmtClass: + llvm_unreachable("Stmt should not be in analyzer evaluation loop"); + case Stmt::ImplicitValueInitExprClass: + // These nodes are shared in the CFG and would case caching out. + // Moreover, no additional evaluation required for them, the + // analyzer can reconstruct these values from the AST. + llvm_unreachable("Should be pruned from CFG"); + + case Stmt::ObjCSubscriptRefExprClass: + case Stmt::ObjCPropertyRefExprClass: + llvm_unreachable("These are handled by PseudoObjectExpr"); + + case Stmt::GNUNullExprClass: { + // GNU __null is a pointer-width integer, not an actual pointer. + ProgramStateRef state = Pred->getState(); + state = state->BindExpr( + S, Pred->getLocationContext(), + svalBuilder.makeIntValWithWidth(getContext().VoidPtrTy, 0)); + Bldr.generateNode(S, Pred, state); + break; + } - case Stmt::ObjCAtSynchronizedStmtClass: - Bldr.takeNodes(Pred); - VisitObjCAtSynchronizedStmt(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::ObjCAtSynchronizedStmtClass: + Bldr.takeNodes(Pred); + VisitObjCAtSynchronizedStmt(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Expr::ConstantExprClass: - case Stmt::ExprWithCleanupsClass: - // Handled due to fully linearised CFG. - break; + case Expr::ConstantExprClass: + case Stmt::ExprWithCleanupsClass: + // Handled due to fully linearised CFG. + break; - case Stmt::CXXBindTemporaryExprClass: { - Bldr.takeNodes(Pred); - ExplodedNodeSet PreVisit; - getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); - ExplodedNodeSet Next; - VisitCXXBindTemporaryExpr(cast(S), PreVisit, Next); - getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this); - Bldr.addNodes(Dst); - break; - } + case Stmt::CXXBindTemporaryExprClass: { + Bldr.takeNodes(Pred); + ExplodedNodeSet PreVisit; + getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); + ExplodedNodeSet Next; + VisitCXXBindTemporaryExpr(cast(S), PreVisit, Next); + getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this); + Bldr.addNodes(Dst); + break; + } - case Stmt::ArrayInitLoopExprClass: - Bldr.takeNodes(Pred); - VisitArrayInitLoopExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; - // Cases not handled yet; but will handle some day. - case Stmt::DesignatedInitExprClass: - case Stmt::DesignatedInitUpdateExprClass: - case Stmt::ArrayInitIndexExprClass: - case Stmt::ExtVectorElementExprClass: - case Stmt::ImaginaryLiteralClass: - case Stmt::ObjCAtCatchStmtClass: - case Stmt::ObjCAtFinallyStmtClass: - case Stmt::ObjCAtTryStmtClass: - case Stmt::ObjCAutoreleasePoolStmtClass: - case Stmt::ObjCEncodeExprClass: - case Stmt::ObjCIsaExprClass: - case Stmt::ObjCProtocolExprClass: - case Stmt::ObjCSelectorExprClass: - case Stmt::ParenListExprClass: - case Stmt::ShuffleVectorExprClass: - case Stmt::ConvertVectorExprClass: - case Stmt::VAArgExprClass: - case Stmt::CUDAKernelCallExprClass: - case Stmt::OpaqueValueExprClass: - case Stmt::AsTypeExprClass: - case Stmt::ConceptSpecializationExprClass: - case Stmt::CXXRewrittenBinaryOperatorClass: - case Stmt::RequiresExprClass: - case Expr::CXXParenListInitExprClass: - // Fall through. - - // Cases we intentionally don't evaluate, since they don't need - // to be explicitly evaluated. - case Stmt::PredefinedExprClass: - case Stmt::AddrLabelExprClass: - case Stmt::AttributedStmtClass: - case Stmt::IntegerLiteralClass: - case Stmt::FixedPointLiteralClass: - case Stmt::CharacterLiteralClass: - case Stmt::CXXScalarValueInitExprClass: - case Stmt::CXXBoolLiteralExprClass: - case Stmt::ObjCBoolLiteralExprClass: - case Stmt::ObjCAvailabilityCheckExprClass: - case Stmt::FloatingLiteralClass: - case Stmt::NoInitExprClass: - case Stmt::SizeOfPackExprClass: - case Stmt::StringLiteralClass: - case Stmt::SourceLocExprClass: - case Stmt::ObjCStringLiteralClass: - case Stmt::CXXPseudoDestructorExprClass: - case Stmt::SubstNonTypeTemplateParmExprClass: - case Stmt::CXXNullPtrLiteralExprClass: - case Stmt::OMPArraySectionExprClass: - case Stmt::OMPArrayShapingExprClass: - case Stmt::OMPIteratorExprClass: - case Stmt::SYCLUniqueStableNameExprClass: - case Stmt::TypeTraitExprClass: { - Bldr.takeNodes(Pred); - ExplodedNodeSet preVisit; - getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); - getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this); - Bldr.addNodes(Dst); - break; - } + case Stmt::ArrayInitLoopExprClass: + Bldr.takeNodes(Pred); + VisitArrayInitLoopExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; + // Cases not handled yet; but will handle some day. + case Stmt::DesignatedInitExprClass: + case Stmt::DesignatedInitUpdateExprClass: + case Stmt::ArrayInitIndexExprClass: + case Stmt::ExtVectorElementExprClass: + case Stmt::ImaginaryLiteralClass: + case Stmt::ObjCAtCatchStmtClass: + case Stmt::ObjCAtFinallyStmtClass: + case Stmt::ObjCAtTryStmtClass: + case Stmt::ObjCAutoreleasePoolStmtClass: + case Stmt::ObjCEncodeExprClass: + case Stmt::ObjCIsaExprClass: + case Stmt::ObjCProtocolExprClass: + case Stmt::ObjCSelectorExprClass: + case Stmt::ParenListExprClass: + case Stmt::ShuffleVectorExprClass: + case Stmt::ConvertVectorExprClass: + case Stmt::VAArgExprClass: + case Stmt::CUDAKernelCallExprClass: + case Stmt::OpaqueValueExprClass: + case Stmt::AsTypeExprClass: + case Stmt::ConceptSpecializationExprClass: + case Stmt::CXXRewrittenBinaryOperatorClass: + case Stmt::RequiresExprClass: + case Expr::CXXParenListInitExprClass: + // Fall through. + + // Cases we intentionally don't evaluate, since they don't need + // to be explicitly evaluated. + case Stmt::PredefinedExprClass: + case Stmt::AddrLabelExprClass: + case Stmt::AttributedStmtClass: + case Stmt::IntegerLiteralClass: + case Stmt::FixedPointLiteralClass: + case Stmt::CharacterLiteralClass: + case Stmt::CXXScalarValueInitExprClass: + case Stmt::CXXBoolLiteralExprClass: + case Stmt::ObjCBoolLiteralExprClass: + case Stmt::ObjCAvailabilityCheckExprClass: + case Stmt::FloatingLiteralClass: + case Stmt::NoInitExprClass: + case Stmt::SizeOfPackExprClass: + case Stmt::StringLiteralClass: + case Stmt::SourceLocExprClass: + case Stmt::ObjCStringLiteralClass: + case Stmt::CXXPseudoDestructorExprClass: + case Stmt::SubstNonTypeTemplateParmExprClass: + case Stmt::CXXNullPtrLiteralExprClass: + case Stmt::OMPArraySectionExprClass: + case Stmt::OMPArrayShapingExprClass: + case Stmt::OMPIteratorExprClass: + case Stmt::SYCLUniqueStableNameExprClass: + case Stmt::TypeTraitExprClass: { + Bldr.takeNodes(Pred); + ExplodedNodeSet preVisit; + getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); + getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this); + Bldr.addNodes(Dst); + break; + } - case Stmt::CXXDefaultArgExprClass: - case Stmt::CXXDefaultInitExprClass: { - Bldr.takeNodes(Pred); - ExplodedNodeSet PreVisit; - getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); + case Stmt::CXXDefaultArgExprClass: + case Stmt::CXXDefaultInitExprClass: { + Bldr.takeNodes(Pred); + ExplodedNodeSet PreVisit; + getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); - ExplodedNodeSet Tmp; - StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx); + ExplodedNodeSet Tmp; + StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx); - const Expr *ArgE; - if (const auto *DefE = dyn_cast(S)) - ArgE = DefE->getExpr(); - else if (const auto *DefE = dyn_cast(S)) - ArgE = DefE->getExpr(); - else - llvm_unreachable("unknown constant wrapper kind"); + const Expr *ArgE; + if (const auto *DefE = dyn_cast(S)) + ArgE = DefE->getExpr(); + else if (const auto *DefE = dyn_cast(S)) + ArgE = DefE->getExpr(); + else + llvm_unreachable("unknown constant wrapper kind"); - bool IsTemporary = false; - if (const auto *MTE = dyn_cast(ArgE)) { - ArgE = MTE->getSubExpr(); - IsTemporary = true; - } + bool IsTemporary = false; + if (const auto *MTE = dyn_cast(ArgE)) { + ArgE = MTE->getSubExpr(); + IsTemporary = true; + } - std::optional ConstantVal = svalBuilder.getConstantVal(ArgE); - if (!ConstantVal) - ConstantVal = UnknownVal(); - - const LocationContext *LCtx = Pred->getLocationContext(); - for (const auto I : PreVisit) { - ProgramStateRef State = I->getState(); - State = State->BindExpr(S, LCtx, *ConstantVal); - if (IsTemporary) - State = createTemporaryRegionIfNeeded(State, LCtx, - cast(S), - cast(S)); - Bldr2.generateNode(S, I, State); - } + std::optional ConstantVal = svalBuilder.getConstantVal(ArgE); + if (!ConstantVal) + ConstantVal = UnknownVal(); - getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); - Bldr.addNodes(Dst); - break; + const LocationContext *LCtx = Pred->getLocationContext(); + for (const auto I : PreVisit) { + ProgramStateRef State = I->getState(); + State = State->BindExpr(S, LCtx, *ConstantVal); + if (IsTemporary) + State = createTemporaryRegionIfNeeded(State, LCtx, cast(S), + cast(S)); + Bldr2.generateNode(S, I, State); } - // Cases we evaluate as opaque expressions, conjuring a symbol. - case Stmt::CXXStdInitializerListExprClass: - case Expr::ObjCArrayLiteralClass: - case Expr::ObjCDictionaryLiteralClass: - case Expr::ObjCBoxedExprClass: { - Bldr.takeNodes(Pred); + getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); + Bldr.addNodes(Dst); + break; + } - ExplodedNodeSet preVisit; - getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); + // Cases we evaluate as opaque expressions, conjuring a symbol. + case Stmt::CXXStdInitializerListExprClass: + case Expr::ObjCArrayLiteralClass: + case Expr::ObjCDictionaryLiteralClass: + case Expr::ObjCBoxedExprClass: { + Bldr.takeNodes(Pred); - ExplodedNodeSet Tmp; - StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx); - - const auto *Ex = cast(S); - QualType resultType = Ex->getType(); - - for (const auto N : preVisit) { - const LocationContext *LCtx = N->getLocationContext(); - SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, - resultType, - currBldrCtx->blockCount()); - ProgramStateRef State = N->getState()->BindExpr(Ex, LCtx, result); - - // Escape pointers passed into the list, unless it's an ObjC boxed - // expression which is not a boxable C structure. - if (!(isa(Ex) && - !cast(Ex)->getSubExpr() - ->getType()->isRecordType())) - for (auto Child : Ex->children()) { - assert(Child); - SVal Val = State->getSVal(Child, LCtx); - State = escapeValues(State, Val, PSK_EscapeOther); - } + ExplodedNodeSet preVisit; + getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); - Bldr2.generateNode(S, N, State); - } + ExplodedNodeSet Tmp; + StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx); + + const auto *Ex = cast(S); + QualType resultType = Ex->getType(); + + for (const auto N : preVisit) { + const LocationContext *LCtx = N->getLocationContext(); + SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, resultType, + currBldrCtx->blockCount()); + ProgramStateRef State = N->getState()->BindExpr(Ex, LCtx, result); + + // Escape pointers passed into the list, unless it's an ObjC boxed + // expression which is not a boxable C structure. + if (!(isa(Ex) && + !cast(Ex)->getSubExpr()->getType()->isRecordType())) + for (auto Child : Ex->children()) { + assert(Child); + SVal Val = State->getSVal(Child, LCtx); + State = escapeValues(State, Val, PSK_EscapeOther); + } - getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); - Bldr.addNodes(Dst); - break; + Bldr2.generateNode(S, N, State); } - case Stmt::ArraySubscriptExprClass: - Bldr.takeNodes(Pred); - VisitArraySubscriptExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); + Bldr.addNodes(Dst); + break; + } - case Stmt::MatrixSubscriptExprClass: - llvm_unreachable("Support for MatrixSubscriptExpr is not implemented."); - break; + case Stmt::ArraySubscriptExprClass: + Bldr.takeNodes(Pred); + VisitArraySubscriptExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::GCCAsmStmtClass: - Bldr.takeNodes(Pred); - VisitGCCAsmStmt(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::MatrixSubscriptExprClass: + llvm_unreachable("Support for MatrixSubscriptExpr is not implemented."); + break; - case Stmt::MSAsmStmtClass: + case Stmt::GCCAsmStmtClass: + Bldr.takeNodes(Pred); + VisitGCCAsmStmt(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; + + case Stmt::MSAsmStmtClass: + Bldr.takeNodes(Pred); + VisitMSAsmStmt(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; + + case Stmt::BlockExprClass: + Bldr.takeNodes(Pred); + VisitBlockExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; + + case Stmt::LambdaExprClass: + if (AMgr.options.ShouldInlineLambdas) { Bldr.takeNodes(Pred); - VisitMSAsmStmt(cast(S), Pred, Dst); + VisitLambdaExpr(cast(S), Pred, Dst); Bldr.addNodes(Dst); - break; + } else { + const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); + Engine.addAbortedBlock(node, currBldrCtx->getBlock()); + } + break; - case Stmt::BlockExprClass: + case Stmt::BinaryOperatorClass: { + const auto *B = cast(S); + if (B->isLogicalOp()) { Bldr.takeNodes(Pred); - VisitBlockExpr(cast(S), Pred, Dst); + VisitLogicalExpr(B, Pred, Dst); Bldr.addNodes(Dst); break; - - case Stmt::LambdaExprClass: - if (AMgr.options.ShouldInlineLambdas) { - Bldr.takeNodes(Pred); - VisitLambdaExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - } else { - const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); - Engine.addAbortedBlock(node, currBldrCtx->getBlock()); - } + } else if (B->getOpcode() == BO_Comma) { + ProgramStateRef state = Pred->getState(); + Bldr.generateNode( + B, Pred, + state->BindExpr( + B, Pred->getLocationContext(), + state->getSVal(B->getRHS(), Pred->getLocationContext()))); break; + } - case Stmt::BinaryOperatorClass: { - const auto *B = cast(S); - if (B->isLogicalOp()) { - Bldr.takeNodes(Pred); - VisitLogicalExpr(B, Pred, Dst); - Bldr.addNodes(Dst); - break; - } - else if (B->getOpcode() == BO_Comma) { - ProgramStateRef state = Pred->getState(); - Bldr.generateNode(B, Pred, - state->BindExpr(B, Pred->getLocationContext(), - state->getSVal(B->getRHS(), - Pred->getLocationContext()))); - break; - } + Bldr.takeNodes(Pred); - Bldr.takeNodes(Pred); + if (AMgr.options.ShouldEagerlyAssume && + (B->isRelationalOp() || B->isEqualityOp())) { + ExplodedNodeSet Tmp; + VisitBinaryOperator(cast(S), Pred, Tmp); + evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast(S)); + } else + VisitBinaryOperator(cast(S), Pred, Dst); - if (AMgr.options.ShouldEagerlyAssume && - (B->isRelationalOp() || B->isEqualityOp())) { - ExplodedNodeSet Tmp; - VisitBinaryOperator(cast(S), Pred, Tmp); - evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast(S)); - } - else - VisitBinaryOperator(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; + } - Bldr.addNodes(Dst); - break; - } + case Stmt::CXXOperatorCallExprClass: { + const auto *OCE = cast(S); - case Stmt::CXXOperatorCallExprClass: { - const auto *OCE = cast(S); - - // For instance method operators, make sure the 'this' argument has a - // valid region. - const Decl *Callee = OCE->getCalleeDecl(); - if (const auto *MD = dyn_cast_or_null(Callee)) { - if (MD->isImplicitObjectMemberFunction()) { - ProgramStateRef State = Pred->getState(); - const LocationContext *LCtx = Pred->getLocationContext(); - ProgramStateRef NewState = + // For instance method operators, make sure the 'this' argument has a + // valid region. + const Decl *Callee = OCE->getCalleeDecl(); + if (const auto *MD = dyn_cast_or_null(Callee)) { + if (MD->isImplicitObjectMemberFunction()) { + ProgramStateRef State = Pred->getState(); + const LocationContext *LCtx = Pred->getLocationContext(); + ProgramStateRef NewState = createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0)); - if (NewState != State) { - Pred = Bldr.generateNode(OCE, Pred, NewState, /*tag=*/nullptr, - ProgramPoint::PreStmtKind); - // Did we cache out? - if (!Pred) - break; - } + if (NewState != State) { + Pred = Bldr.generateNode(OCE, Pred, NewState, /*tag=*/nullptr, + ProgramPoint::PreStmtKind); + // Did we cache out? + if (!Pred) + break; } } - [[fallthrough]]; } + [[fallthrough]]; + } - case Stmt::CallExprClass: - case Stmt::CXXMemberCallExprClass: - case Stmt::UserDefinedLiteralClass: - Bldr.takeNodes(Pred); - VisitCallExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; - - case Stmt::CXXCatchStmtClass: - Bldr.takeNodes(Pred); - VisitCXXCatchStmt(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; - - case Stmt::CXXTemporaryObjectExprClass: - case Stmt::CXXConstructExprClass: - Bldr.takeNodes(Pred); - VisitCXXConstructExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; - - case Stmt::CXXInheritedCtorInitExprClass: - Bldr.takeNodes(Pred); - VisitCXXInheritedCtorInitExpr(cast(S), Pred, - Dst); - Bldr.addNodes(Dst); - break; + case Stmt::CallExprClass: + case Stmt::CXXMemberCallExprClass: + case Stmt::UserDefinedLiteralClass: + Bldr.takeNodes(Pred); + VisitCallExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::CXXNewExprClass: { - Bldr.takeNodes(Pred); + case Stmt::CXXCatchStmtClass: + Bldr.takeNodes(Pred); + VisitCXXCatchStmt(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - ExplodedNodeSet PreVisit; - getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); + case Stmt::CXXTemporaryObjectExprClass: + case Stmt::CXXConstructExprClass: + Bldr.takeNodes(Pred); + VisitCXXConstructExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - ExplodedNodeSet PostVisit; - for (const auto i : PreVisit) - VisitCXXNewExpr(cast(S), i, PostVisit); + case Stmt::CXXInheritedCtorInitExprClass: + Bldr.takeNodes(Pred); + VisitCXXInheritedCtorInitExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); - Bldr.addNodes(Dst); - break; - } + case Stmt::CXXNewExprClass: { + Bldr.takeNodes(Pred); - case Stmt::CXXDeleteExprClass: { - Bldr.takeNodes(Pred); - ExplodedNodeSet PreVisit; - const auto *CDE = cast(S); - getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); - ExplodedNodeSet PostVisit; - getCheckerManager().runCheckersForPostStmt(PostVisit, PreVisit, S, *this); + ExplodedNodeSet PreVisit; + getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); - for (const auto i : PostVisit) - VisitCXXDeleteExpr(CDE, i, Dst); + ExplodedNodeSet PostVisit; + for (const auto i : PreVisit) + VisitCXXNewExpr(cast(S), i, PostVisit); - Bldr.addNodes(Dst); - break; - } - // FIXME: ChooseExpr is really a constant. We need to fix - // the CFG do not model them as explicit control-flow. + getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); + Bldr.addNodes(Dst); + break; + } - case Stmt::ChooseExprClass: { // __builtin_choose_expr - Bldr.takeNodes(Pred); - const auto *C = cast(S); - VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); - Bldr.addNodes(Dst); - break; - } + case Stmt::CXXDeleteExprClass: { + Bldr.takeNodes(Pred); + ExplodedNodeSet PreVisit; + const auto *CDE = cast(S); + getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); + ExplodedNodeSet PostVisit; + getCheckerManager().runCheckersForPostStmt(PostVisit, PreVisit, S, *this); - case Stmt::CompoundAssignOperatorClass: - Bldr.takeNodes(Pred); - VisitBinaryOperator(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + for (const auto i : PostVisit) + VisitCXXDeleteExpr(CDE, i, Dst); - case Stmt::CompoundLiteralExprClass: - Bldr.takeNodes(Pred); - VisitCompoundLiteralExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + Bldr.addNodes(Dst); + break; + } + // FIXME: ChooseExpr is really a constant. We need to fix + // the CFG do not model them as explicit control-flow. - case Stmt::BinaryConditionalOperatorClass: - case Stmt::ConditionalOperatorClass: { // '?' operator - Bldr.takeNodes(Pred); - const auto *C = cast(S); - VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst); - Bldr.addNodes(Dst); - break; - } + case Stmt::ChooseExprClass: { // __builtin_choose_expr + Bldr.takeNodes(Pred); + const auto *C = cast(S); + VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); + Bldr.addNodes(Dst); + break; + } - case Stmt::CXXThisExprClass: - Bldr.takeNodes(Pred); - VisitCXXThisExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::CompoundAssignOperatorClass: + Bldr.takeNodes(Pred); + VisitBinaryOperator(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::DeclRefExprClass: { - Bldr.takeNodes(Pred); - const auto *DE = cast(S); - VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst); - Bldr.addNodes(Dst); - break; - } + case Stmt::CompoundLiteralExprClass: + Bldr.takeNodes(Pred); + VisitCompoundLiteralExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::DeclStmtClass: - Bldr.takeNodes(Pred); - VisitDeclStmt(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::BinaryConditionalOperatorClass: + case Stmt::ConditionalOperatorClass: { // '?' operator + Bldr.takeNodes(Pred); + const auto *C = cast(S); + VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst); + Bldr.addNodes(Dst); + break; + } - case Stmt::ImplicitCastExprClass: - case Stmt::CStyleCastExprClass: - case Stmt::CXXStaticCastExprClass: - case Stmt::CXXDynamicCastExprClass: - case Stmt::CXXReinterpretCastExprClass: - case Stmt::CXXConstCastExprClass: - case Stmt::CXXFunctionalCastExprClass: - case Stmt::BuiltinBitCastExprClass: - case Stmt::ObjCBridgedCastExprClass: - case Stmt::CXXAddrspaceCastExprClass: { - Bldr.takeNodes(Pred); - const auto *C = cast(S); - ExplodedNodeSet dstExpr; - VisitCast(C, C->getSubExpr(), Pred, dstExpr); + case Stmt::CXXThisExprClass: + Bldr.takeNodes(Pred); + VisitCXXThisExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - // Handle the postvisit checks. - getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this); - Bldr.addNodes(Dst); - break; - } + case Stmt::DeclRefExprClass: { + Bldr.takeNodes(Pred); + const auto *DE = cast(S); + VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst); + Bldr.addNodes(Dst); + break; + } - case Expr::MaterializeTemporaryExprClass: { - Bldr.takeNodes(Pred); - const auto *MTE = cast(S); - ExplodedNodeSet dstPrevisit; - getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this); - ExplodedNodeSet dstExpr; - for (const auto i : dstPrevisit) - CreateCXXTemporaryObject(MTE, i, dstExpr); - getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this); - Bldr.addNodes(Dst); - break; - } + case Stmt::DeclStmtClass: + Bldr.takeNodes(Pred); + VisitDeclStmt(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::InitListExprClass: - Bldr.takeNodes(Pred); - VisitInitListExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::ImplicitCastExprClass: + case Stmt::CStyleCastExprClass: + case Stmt::CXXStaticCastExprClass: + case Stmt::CXXDynamicCastExprClass: + case Stmt::CXXReinterpretCastExprClass: + case Stmt::CXXConstCastExprClass: + case Stmt::CXXFunctionalCastExprClass: + case Stmt::BuiltinBitCastExprClass: + case Stmt::ObjCBridgedCastExprClass: + case Stmt::CXXAddrspaceCastExprClass: { + Bldr.takeNodes(Pred); + const auto *C = cast(S); + ExplodedNodeSet dstExpr; + VisitCast(C, C->getSubExpr(), Pred, dstExpr); + + // Handle the postvisit checks. + getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this); + Bldr.addNodes(Dst); + break; + } - case Stmt::MemberExprClass: - Bldr.takeNodes(Pred); - VisitMemberExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Expr::MaterializeTemporaryExprClass: { + Bldr.takeNodes(Pred); + const auto *MTE = cast(S); + ExplodedNodeSet dstPrevisit; + getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this); + ExplodedNodeSet dstExpr; + for (const auto i : dstPrevisit) + CreateCXXTemporaryObject(MTE, i, dstExpr); + getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this); + Bldr.addNodes(Dst); + break; + } - case Stmt::AtomicExprClass: - Bldr.takeNodes(Pred); - VisitAtomicExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::InitListExprClass: + Bldr.takeNodes(Pred); + VisitInitListExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::ObjCIvarRefExprClass: - Bldr.takeNodes(Pred); - VisitLvalObjCIvarRefExpr(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::MemberExprClass: + Bldr.takeNodes(Pred); + VisitMemberExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::ObjCForCollectionStmtClass: - Bldr.takeNodes(Pred); - VisitObjCForCollectionStmt(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::AtomicExprClass: + Bldr.takeNodes(Pred); + VisitAtomicExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::ObjCMessageExprClass: - Bldr.takeNodes(Pred); - VisitObjCMessage(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::ObjCIvarRefExprClass: + Bldr.takeNodes(Pred); + VisitLvalObjCIvarRefExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::ObjCAtThrowStmtClass: - case Stmt::CXXThrowExprClass: - // FIXME: This is not complete. We basically treat @throw as - // an abort. - Bldr.generateSink(S, Pred, Pred->getState()); - break; + case Stmt::ObjCForCollectionStmtClass: + Bldr.takeNodes(Pred); + VisitObjCForCollectionStmt(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::ReturnStmtClass: - Bldr.takeNodes(Pred); - VisitReturnStmt(cast(S), Pred, Dst); - Bldr.addNodes(Dst); - break; + case Stmt::ObjCMessageExprClass: + Bldr.takeNodes(Pred); + VisitObjCMessage(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - case Stmt::OffsetOfExprClass: { - Bldr.takeNodes(Pred); - ExplodedNodeSet PreVisit; - getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); + case Stmt::ObjCAtThrowStmtClass: + case Stmt::CXXThrowExprClass: + // FIXME: This is not complete. We basically treat @throw as + // an abort. + Bldr.generateSink(S, Pred, Pred->getState()); + break; - ExplodedNodeSet PostVisit; - for (const auto Node : PreVisit) - VisitOffsetOfExpr(cast(S), Node, PostVisit); + case Stmt::ReturnStmtClass: + Bldr.takeNodes(Pred); + VisitReturnStmt(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); - Bldr.addNodes(Dst); - break; - } + case Stmt::OffsetOfExprClass: { + Bldr.takeNodes(Pred); + ExplodedNodeSet PreVisit; + getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); - case Stmt::UnaryExprOrTypeTraitExprClass: - Bldr.takeNodes(Pred); - VisitUnaryExprOrTypeTraitExpr(cast(S), - Pred, Dst); - Bldr.addNodes(Dst); - break; + ExplodedNodeSet PostVisit; + for (const auto Node : PreVisit) + VisitOffsetOfExpr(cast(S), Node, PostVisit); - case Stmt::StmtExprClass: { - const auto *SE = cast(S); + getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); + Bldr.addNodes(Dst); + break; + } - if (SE->getSubStmt()->body_empty()) { - // Empty statement expression. - assert(SE->getType() == getContext().VoidTy - && "Empty statement expression must have void type."); - break; - } + case Stmt::UnaryExprOrTypeTraitExprClass: + Bldr.takeNodes(Pred); + VisitUnaryExprOrTypeTraitExpr(cast(S), Pred, Dst); + Bldr.addNodes(Dst); + break; - if (const auto *LastExpr = - dyn_cast(*SE->getSubStmt()->body_rbegin())) { - ProgramStateRef state = Pred->getState(); - Bldr.generateNode(SE, Pred, - state->BindExpr(SE, Pred->getLocationContext(), - state->getSVal(LastExpr, - Pred->getLocationContext()))); - } - break; - } + case Stmt::StmtExprClass: { + const auto *SE = cast(S); - case Stmt::UnaryOperatorClass: { - Bldr.takeNodes(Pred); - const auto *U = cast(S); - if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) { - ExplodedNodeSet Tmp; - VisitUnaryOperator(U, Pred, Tmp); - evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U); - } - else - VisitUnaryOperator(U, Pred, Dst); - Bldr.addNodes(Dst); + if (SE->getSubStmt()->body_empty()) { + // Empty statement expression. + assert(SE->getType() == getContext().VoidTy && + "Empty statement expression must have void type."); break; } - case Stmt::PseudoObjectExprClass: { - Bldr.takeNodes(Pred); + if (const auto *LastExpr = + dyn_cast(*SE->getSubStmt()->body_rbegin())) { ProgramStateRef state = Pred->getState(); - const auto *PE = cast(S); - if (const Expr *Result = PE->getResultExpr()) { - SVal V = state->getSVal(Result, Pred->getLocationContext()); - Bldr.generateNode(S, Pred, - state->BindExpr(S, Pred->getLocationContext(), V)); - } - else - Bldr.generateNode(S, Pred, - state->BindExpr(S, Pred->getLocationContext(), - UnknownVal())); - - Bldr.addNodes(Dst); - break; + Bldr.generateNode( + SE, Pred, + state->BindExpr( + SE, Pred->getLocationContext(), + state->getSVal(LastExpr, Pred->getLocationContext()))); } + break; + } - case Expr::ObjCIndirectCopyRestoreExprClass: { - // ObjCIndirectCopyRestoreExpr implies passing a temporary for - // correctness of lifetime management. Due to limited analysis - // of ARC, this is implemented as direct arg passing. - Bldr.takeNodes(Pred); - ProgramStateRef state = Pred->getState(); - const auto *OIE = cast(S); - const Expr *E = OIE->getSubExpr(); - SVal V = state->getSVal(E, Pred->getLocationContext()); + case Stmt::UnaryOperatorClass: { + Bldr.takeNodes(Pred); + const auto *U = cast(S); + if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) { + ExplodedNodeSet Tmp; + VisitUnaryOperator(U, Pred, Tmp); + evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U); + } else + VisitUnaryOperator(U, Pred, Dst); + Bldr.addNodes(Dst); + break; + } + + case Stmt::PseudoObjectExprClass: { + Bldr.takeNodes(Pred); + ProgramStateRef state = Pred->getState(); + const auto *PE = cast(S); + if (const Expr *Result = PE->getResultExpr()) { + SVal V = state->getSVal(Result, Pred->getLocationContext()); Bldr.generateNode(S, Pred, - state->BindExpr(S, Pred->getLocationContext(), V)); - Bldr.addNodes(Dst); - break; - } + state->BindExpr(S, Pred->getLocationContext(), V)); + } else + Bldr.generateNode( + S, Pred, + state->BindExpr(S, Pred->getLocationContext(), UnknownVal())); + + Bldr.addNodes(Dst); + break; + } + + case Expr::ObjCIndirectCopyRestoreExprClass: { + // ObjCIndirectCopyRestoreExpr implies passing a temporary for + // correctness of lifetime management. Due to limited analysis + // of ARC, this is implemented as direct arg passing. + Bldr.takeNodes(Pred); + ProgramStateRef state = Pred->getState(); + const auto *OIE = cast(S); + const Expr *E = OIE->getSubExpr(); + SVal V = state->getSVal(E, Pred->getLocationContext()); + Bldr.generateNode(S, Pred, + state->BindExpr(S, Pred->getLocationContext(), V)); + Bldr.addNodes(Dst); + break; + } } } @@ -2469,7 +2447,7 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N, // Note, changing the state ensures that we are not going to cache out. ProgramStateRef NewNodeState = BeforeProcessingCall->getState(); NewNodeState = - NewNodeState->set(const_cast(CE)); + NewNodeState->set(const_cast(CE)); // Make the new node a successor of BeforeProcessingCall. bool IsNew = false; @@ -2483,7 +2461,7 @@ bool ExprEngine::replayWithoutInlining(ExplodedNode *N, // Add the new node to the work list. Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(), - CalleeSF->getIndex()); + CalleeSF->getIndex()); NumTimesRetriedWithoutInlining++; return true; } @@ -2495,7 +2473,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L, PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); // If we reach a loop which has a known bound (and meets // other constraints) then consider completely unrolling it. - if(AMgr.options.ShouldUnrollLoops) { + if (AMgr.options.ShouldUnrollLoops) { unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath; const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminatorStmt(); if (Term) { @@ -2509,7 +2487,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L, } } // Is we are inside an unrolled loop then no need the check the counters. - if(isUnrolledState(Pred->getState())) + if (isUnrolledState(Pred->getState())) return; } @@ -2533,14 +2511,14 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L, if (BlockCount >= AMgr.options.maxBlockVisitOnPath) { static SimpleProgramPointTag tag(TagProviderName, "Block count exceeded"); const ExplodedNode *Sink = - nodeBuilder.generateSink(Pred->getState(), Pred, &tag); + nodeBuilder.generateSink(Pred->getState(), Pred, &tag); // Check if we stopped at the top level function or not. // Root node should have the location context of the top most function. const LocationContext *CalleeLC = Pred->getLocation().getLocationContext(); const LocationContext *CalleeSF = CalleeLC->getStackFrame(); const LocationContext *RootLC = - (*G.roots_begin())->getLocation().getLocationContext(); + (*G.roots_begin())->getLocation().getLocationContext(); if (RootLC->getStackFrame() != CalleeSF) { Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl()); @@ -2569,10 +2547,8 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L, /// integers that promote their values (which are currently not tracked well). /// This function returns the SVal bound to Condition->IgnoreCasts if all the // cast(s) did was sign-extend the original value. -static SVal RecoverCastedSymbol(ProgramStateRef state, - const Stmt *Condition, - const LocationContext *LCtx, - ASTContext &Ctx) { +static SVal RecoverCastedSymbol(ProgramStateRef state, const Stmt *Condition, + const LocationContext *LCtx, ASTContext &Ctx) { const auto *Ex = dyn_cast(Condition); if (!Ex) @@ -2633,8 +2609,7 @@ static const Stmt *getRightmostLeaf(const Stmt *Condition) { // not evaluated, and is thus not in the SVal cache, we need to use that leaf // expression to evaluate the truth value of the condition in the current state // space. -static const Stmt *ResolveCondition(const Stmt *Condition, - const CFGBlock *B) { +static const Stmt *ResolveCondition(const Stmt *Condition, const CFGBlock *B) { if (const auto *Ex = dyn_cast(Condition)) Condition = Ex->IgnoreParens(); @@ -2676,10 +2651,9 @@ ProgramStateRef ExprEngine::setWhetherHasMoreIteration( return State->set({O, LC}, HasMoreIteraton); } -ProgramStateRef -ExprEngine::removeIterationState(ProgramStateRef State, - const ObjCForCollectionStmt *O, - const LocationContext *LC) { +ProgramStateRef ExprEngine::removeIterationState(ProgramStateRef State, + const ObjCForCollectionStmt *O, + const LocationContext *LC) { assert(State->contains({O, LC})); return State->remove({O, LC}); } @@ -2742,10 +2716,8 @@ assumeCondition(const Stmt *Condition, ExplodedNode *N) { } void ExprEngine::processBranch(const Stmt *Condition, - NodeBuilderContext& BldCtx, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, - const CFGBlock *DstT, + NodeBuilderContext &BldCtx, ExplodedNode *Pred, + ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) { assert((!Condition || !isa(Condition)) && "CXXBindTemporaryExprs are handled by processBindTemporary."); @@ -2819,12 +2791,9 @@ void ExprEngine::processBranch(const Stmt *Condition, REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedGlobalsSet, llvm::ImmutableSet) -void ExprEngine::processStaticInitializer(const DeclStmt *DS, - NodeBuilderContext &BuilderCtx, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, - const CFGBlock *DstT, - const CFGBlock *DstF) { +void ExprEngine::processStaticInitializer( + const DeclStmt *DS, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, + ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) { PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); currBldrCtx = &BuilderCtx; @@ -2873,7 +2842,7 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { if (isa(V)) { // Dispatch to the first target and mark it as a sink. - //ExplodedNode* N = builder.generateNode(builder.begin(), state, true); + // ExplodedNode* N = builder.generateNode(builder.begin(), state, true); // FIXME: add checker visit. // UndefBranches.insert(N); return; @@ -2896,7 +2865,7 @@ void ExprEngine::processBeginOfFunction(NodeBuilderContext &BC, /// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path /// nodes when the control reaches the end of a function. -void ExprEngine::processEndOfFunction(NodeBuilderContext& BC, +void ExprEngine::processEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, const ReturnStmt *RS) { ProgramStateRef State = Pred->getState(); @@ -2970,17 +2939,17 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext& BC, /// ProcessSwitch - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a switch statement. -void ExprEngine::processSwitch(SwitchNodeBuilder& builder) { +void ExprEngine::processSwitch(SwitchNodeBuilder &builder) { using iterator = SwitchNodeBuilder::iterator; ProgramStateRef state = builder.getState(); const Expr *CondE = builder.getCondition(); - SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext()); + SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext()); if (CondV_untested.isUndef()) { - //ExplodedNode* N = builder.generateDefaultCaseNode(state, true); - // FIXME: add checker - //UndefBranches.insert(N); + // ExplodedNode* N = builder.generateDefaultCaseNode(state, true); + // FIXME: add checker + // UndefBranches.insert(N); return; } @@ -2991,7 +2960,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) { iterator I = builder.begin(), EI = builder.end(); bool defaultIsFeasible = I == EI; - for ( ; I != EI; ++I) { + for (; I != EI; ++I) { // Successor may be pruned out during CFG construction. if (!I.getBlock()) continue; @@ -3083,8 +3052,7 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, // Sema follows a sequence of complex rules to determine whether the // variable should be captured. if (const FieldDecl *FD = LambdaCaptureFields[VD]) { - Loc CXXThis = - svalBuilder.getCXXThis(MD, LocCtxt->getStackFrame()); + Loc CXXThis = svalBuilder.getCXXThis(MD, LocCtxt->getStackFrame()); SVal CXXThisVal = state->getSVal(CXXThis); VInfo = std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType()); } @@ -3292,10 +3260,10 @@ void ExprEngine::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex, /// VisitArraySubscriptExpr - Transfer function for array accesses void ExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr *A, - ExplodedNode *Pred, - ExplodedNodeSet &Dst){ + ExplodedNode *Pred, + ExplodedNodeSet &Dst) { const Expr *Base = A->getBase()->IgnoreParens(); - const Expr *Idx = A->getIdx()->IgnoreParens(); + const Expr *Idx = A->getIdx()->IgnoreParens(); ExplodedNodeSet CheckerPreStmt; getCheckerManager().runCheckersForPreStmt(CheckerPreStmt, Pred, A, *this); @@ -3308,8 +3276,9 @@ void ExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr *A, // The "like" case is for situations where C standard prohibits the type to // be an lvalue, e.g. taking the address of a subscript of an expression of // type "void *". - bool IsGLValueLike = A->isGLValue() || - (A->getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus); + bool IsGLValueLike = + A->isGLValue() || + (A->getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus); for (auto *Node : CheckerPreStmt) { const LocationContext *LCtx = Node->getLocationContext(); @@ -3324,11 +3293,10 @@ void ExprEngine::VisitArraySubscriptExpr(const ArraySubscriptExpr *A, if (T->isVoidType()) T = getContext().CharTy; - SVal V = state->getLValue(T, - state->getSVal(Idx, LCtx), + SVal V = state->getLValue(T, state->getSVal(Idx, LCtx), state->getSVal(Base, LCtx)); Bldr.generateNode(A, Node, state->BindExpr(A, LCtx, V), nullptr, - ProgramPoint::PostLValueKind); + ProgramPoint::PostLValueKind); } else if (IsVectorType) { // FIXME: non-glvalue vector reads are not modelled. Bldr.generateNode(A, Node, state, nullptr); @@ -3403,8 +3371,8 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, // pointers as soon as they are used. if (!M->isGLValue()) { assert(M->getType()->isArrayType()); - const auto *PE = - dyn_cast(I->getParentMap().getParentIgnoreParens(M)); + const auto *PE = dyn_cast( + I->getParentMap().getParentIgnoreParens(M)); if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) { llvm_unreachable("should always be wrapped in ArrayToPointerDecay"); } @@ -3453,18 +3421,17 @@ void ExprEngine::VisitAtomicExpr(const AtomicExpr *AE, ExplodedNode *Pred, } State = State->invalidateRegions(ValuesToInvalidate, AE, - currBldrCtx->blockCount(), - LCtx, - /*CausedByPointerEscape*/true, - /*Symbols=*/nullptr); + currBldrCtx->blockCount(), LCtx, + /*CausedByPointerEscape*/ true, + /*Symbols=*/nullptr); SVal ResultVal = UnknownVal(); State = State->BindExpr(AE, LCtx, ResultVal); - Bldr.generateNode(AE, I, State, nullptr, - ProgramPoint::PostStmtKind); + Bldr.generateNode(AE, I, State, nullptr, ProgramPoint::PostStmtKind); } - getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE, *this); + getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE, + *this); } // A value escapes in four possible cases: @@ -3523,21 +3490,16 @@ ExprEngine::processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, nullptr); } -ProgramStateRef -ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State, - const InvalidatedSymbols *Invalidated, - ArrayRef ExplicitRegions, - const CallEvent *Call, +ProgramStateRef ExprEngine::notifyCheckersOfPointerEscape( + ProgramStateRef State, const InvalidatedSymbols *Invalidated, + ArrayRef ExplicitRegions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits) { if (!Invalidated || Invalidated->empty()) return State; if (!Call) - return getCheckerManager().runCheckersForPointerEscape(State, - *Invalidated, - nullptr, - PSK_EscapeOther, - &ITraits); + return getCheckerManager().runCheckersForPointerEscape( + State, *Invalidated, nullptr, PSK_EscapeOther, &ITraits); // If the symbols were invalidated by a call, we want to find out which ones // were invalidated directly due to being arguments to the call. @@ -3555,13 +3517,15 @@ ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State, } if (!SymbolsDirectlyInvalidated.empty()) - State = getCheckerManager().runCheckersForPointerEscape(State, - SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall, &ITraits); + State = getCheckerManager().runCheckersForPointerEscape( + State, SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall, + &ITraits); // Notify about the symbols that get indirectly invalidated by the call. if (!SymbolsIndirectlyInvalidated.empty()) - State = getCheckerManager().runCheckersForPointerEscape(State, - SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall, &ITraits); + State = getCheckerManager().runCheckersForPointerEscape( + State, SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall, + &ITraits); return State; } @@ -3569,8 +3533,7 @@ ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State, /// evalBind - Handle the semantics of binding a value to a specific location. /// This method is used by evalStore and (soon) VisitDeclStmt, and others. void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, - ExplodedNode *Pred, - SVal location, SVal Val, + ExplodedNode *Pred, SVal location, SVal Val, bool atDeclInit, const ProgramPoint *PP) { const LocationContext *LC = Pred->getLocationContext(); PostStmt PS(StoreE, LC); @@ -3587,8 +3550,8 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, // If the location is not a 'Loc', it will already be handled by // the checkers. There is nothing left to do. if (!isa(location)) { - const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr, - /*tag*/nullptr); + const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/ nullptr, + /*tag*/ nullptr); ProgramStateRef state = Pred->getState(); state = processPointerEscapedOnBind(state, location, Val, LC); Bldr.generateNode(L, state, Pred); @@ -3603,8 +3566,8 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, // When binding the value, pass on the hint that this is a initialization. // For initializations, we do not need to inform clients of region // changes. - state = state->bindLoc(location.castAs(), - Val, LC, /* notifyChanges = */ !atDeclInit); + state = state->bindLoc(location.castAs(), Val, LC, + /* notifyChanges = */ !atDeclInit); const MemRegion *LocReg = nullptr; if (std::optional LocRegVal = @@ -3626,10 +3589,9 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, /// @param location The location to store the value /// @param Val The value to be stored void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, - const Expr *LocationE, - ExplodedNode *Pred, - ProgramStateRef state, SVal location, SVal Val, - const ProgramPointTag *tag) { + const Expr *LocationE, ExplodedNode *Pred, + ProgramStateRef state, SVal location, SVal Val, + const ProgramPointTag *tag) { // Proceed with the store. We use AssignE as the anchor for the PostStore // ProgramPoint if it is non-NULL, and LocationE otherwise. const Expr *StoreE = AssignE ? AssignE : LocationE; @@ -3648,14 +3610,10 @@ void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, evalBind(Dst, StoreE, I, location, Val, false); } -void ExprEngine::evalLoad(ExplodedNodeSet &Dst, - const Expr *NodeEx, - const Expr *BoundEx, - ExplodedNode *Pred, - ProgramStateRef state, - SVal location, - const ProgramPointTag *tag, - QualType LoadTy) { +void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx, + const Expr *BoundEx, ExplodedNode *Pred, + ProgramStateRef state, SVal location, + const ProgramPointTag *tag, QualType LoadTy) { assert(!isa(location) && "location cannot be a NonLoc."); assert(NodeEx); assert(BoundEx); @@ -3686,12 +3644,9 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst, } } -void ExprEngine::evalLocation(ExplodedNodeSet &Dst, - const Stmt *NodeEx, - const Stmt *BoundEx, - ExplodedNode *Pred, - ProgramStateRef state, - SVal location, +void ExprEngine::evalLocation(ExplodedNodeSet &Dst, const Stmt *NodeEx, + const Stmt *BoundEx, ExplodedNode *Pred, + ProgramStateRef state, SVal location, bool isLoad) { StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx); // Early checks for performance reason. @@ -3716,18 +3671,17 @@ void ExprEngine::evalLocation(ExplodedNodeSet &Dst, Bldr.generateNode(NodeEx, Pred, state, &tag); } ExplodedNodeSet Tmp; - getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad, - NodeEx, BoundEx, *this); + getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad, NodeEx, + BoundEx, *this); BldrTop.addNodes(Tmp); } -std::pair +std::pair ExprEngine::geteagerlyAssumeBinOpBifurcationTags() { - static SimpleProgramPointTag - eagerlyAssumeBinOpBifurcationTrue(TagProviderName, - "Eagerly Assume True"), - eagerlyAssumeBinOpBifurcationFalse(TagProviderName, - "Eagerly Assume False"); + static SimpleProgramPointTag eagerlyAssumeBinOpBifurcationTrue( + TagProviderName, "Eagerly Assume True"), + eagerlyAssumeBinOpBifurcationFalse(TagProviderName, + "Eagerly Assume False"); return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue, &eagerlyAssumeBinOpBifurcationFalse); } @@ -3750,8 +3704,8 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, SVal V = state->getSVal(Ex, Pred->getLocationContext()); std::optional SEV = V.getAs(); if (SEV && SEV->isExpression()) { - const std::pair &tags = - geteagerlyAssumeBinOpBifurcationTags(); + const std::pair &tags = + geteagerlyAssumeBinOpBifurcationTags(); ProgramStateRef StateTrue, StateFalse; std::tie(StateTrue, StateFalse) = state->assume(*SEV); @@ -3808,13 +3762,14 @@ void ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, namespace llvm { -template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits { - DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} +template <> +struct DOTGraphTraits : public DefaultDOTGraphTraits { + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} static bool nodeHasBugReport(const ExplodedNode *N) { BugReporter &BR = static_cast( - N->getState()->getStateManager().getOwningEngine()).getBugReporter(); + N->getState()->getStateManager().getOwningEngine()) + .getBugReporter(); for (const auto &Class : BR.equivalenceClasses()) { for (const auto &Report : Class.getReports()) { @@ -3857,7 +3812,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { return N->isTrivial(); } - static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G){ + static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G) { std::string Buf; llvm::raw_string_ostream Out(Buf); @@ -3865,8 +3820,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { const unsigned int Space = 1; ProgramStateRef State = N->getState(); - Out << "{ \"state_id\": " << State->getID() - << ",\\l"; + Out << "{ \"state_id\": " << State->getID() << ",\\l"; Indent(Out, Space, IsDot) << "\"program_points\": [\\l"; @@ -3881,9 +3835,9 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { Out << '\"' << Tag->getTagDescription() << '\"'; else Out << "null"; - Out << ", \"node_id\": " << OtherNode->getID() << - ", \"is_sink\": " << OtherNode->isSink() << - ", \"has_report\": " << nodeHasBugReport(OtherNode) << " }"; + Out << ", \"node_id\": " << OtherNode->getID() + << ", \"is_sink\": " << OtherNode->isSink() + << ", \"has_report\": " << nodeHasBugReport(OtherNode) << " }"; }, // Adds a comma and a new-line between each program point. [&](const ExplodedNode *) { Out << ",\\l"; }, @@ -3952,4 +3906,4 @@ void *ProgramStateTrait::GDMIndex() { return &index; } -void ExprEngine::anchor() { } +void ExprEngine::anchor() {} diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index c3fc56ac30ee9..6e49c43000d89 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -26,9 +26,11 @@ using llvm::APSInt; /// (offset) if it is unknown so that memory arithmetic always /// results in an ElementRegion. /// \p Count The number of times the current basic block was visited. -static SVal conjureOffsetSymbolOnLocation( - SVal Symbol, SVal Other, Expr* Expression, SValBuilder &svalBuilder, - unsigned Count, const LocationContext *LCtx) { +static SVal conjureOffsetSymbolOnLocation(SVal Symbol, SVal Other, + Expr *Expression, + SValBuilder &svalBuilder, + unsigned Count, + const LocationContext *LCtx) { QualType Ty = Expression->getType(); if (isa(Other) && Ty->isIntegralOrEnumerationType() && Symbol.isUnknown()) { @@ -37,9 +39,8 @@ static SVal conjureOffsetSymbolOnLocation( return Symbol; } -void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, - ExplodedNode *Pred, - ExplodedNodeSet &Dst) { +void ExprEngine::VisitBinaryOperator(const BinaryOperator *B, + ExplodedNode *Pred, ExplodedNodeSet &Dst) { Expr *LHS = B->getLHS()->IgnoreParens(); Expr *RHS = B->getRHS()->IgnoreParens(); @@ -50,8 +51,8 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this); // With both the LHS and RHS evaluated, process the operation itself. - for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end(); - it != ei; ++it) { + for (ExplodedNodeSet::iterator it = CheckedSet.begin(), ei = CheckedSet.end(); + it != ei; ++it) { ProgramStateRef state = (*it)->getState(); const LocationContext *LCtx = (*it)->getLocationContext(); @@ -65,14 +66,14 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, // FIXME: Handle structs. if (RightV.isUnknown()) { unsigned Count = currBldrCtx->blockCount(); - RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, - Count); + RightV = + svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, Count); } // Simulate the effects of a "store": bind the value of the RHS // to the L-Value represented by the LHS. SVal ExprVal = B->isGLValue() ? LeftV : RightV; - evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal), - LeftV, RightV); + evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal), LeftV, + RightV); continue; } @@ -83,10 +84,10 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, // TODO: This can be removed after we enable history tracking with // SymSymExpr. unsigned Count = currBldrCtx->blockCount(); - RightV = conjureOffsetSymbolOnLocation( - RightV, LeftV, RHS, svalBuilder, Count, LCtx); - LeftV = conjureOffsetSymbolOnLocation( - LeftV, RightV, LHS, svalBuilder, Count, LCtx); + RightV = conjureOffsetSymbolOnLocation(RightV, LeftV, RHS, svalBuilder, + Count, LCtx); + LeftV = conjureOffsetSymbolOnLocation(LeftV, RightV, LHS, svalBuilder, + Count, LCtx); } // Although we don't yet model pointers-to-members, we do need to make @@ -110,21 +111,41 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, continue; } - assert (B->isCompoundAssignmentOp()); + assert(B->isCompoundAssignmentOp()); switch (Op) { - default: - llvm_unreachable("Invalid opcode for compound assignment."); - case BO_MulAssign: Op = BO_Mul; break; - case BO_DivAssign: Op = BO_Div; break; - case BO_RemAssign: Op = BO_Rem; break; - case BO_AddAssign: Op = BO_Add; break; - case BO_SubAssign: Op = BO_Sub; break; - case BO_ShlAssign: Op = BO_Shl; break; - case BO_ShrAssign: Op = BO_Shr; break; - case BO_AndAssign: Op = BO_And; break; - case BO_XorAssign: Op = BO_Xor; break; - case BO_OrAssign: Op = BO_Or; break; + default: + llvm_unreachable("Invalid opcode for compound assignment."); + case BO_MulAssign: + Op = BO_Mul; + break; + case BO_DivAssign: + Op = BO_Div; + break; + case BO_RemAssign: + Op = BO_Rem; + break; + case BO_AddAssign: + Op = BO_Add; + break; + case BO_SubAssign: + Op = BO_Sub; + break; + case BO_ShlAssign: + Op = BO_Shl; + break; + case BO_ShrAssign: + Op = BO_Shr; + break; + case BO_AndAssign: + Op = BO_And; + break; + case BO_XorAssign: + Op = BO_Xor; + break; + case BO_OrAssign: + Op = BO_Or; + break; } // Perform a load (the LHS). This performs the checks for @@ -140,11 +161,11 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, // Get the computation type. QualType CTy = - cast(B)->getComputationResultType(); + cast(B)->getComputationResultType(); CTy = getContext().getCanonicalType(CTy); QualType CLHSTy = - cast(B)->getComputationLHSType(); + cast(B)->getComputationLHSType(); CLHSTy = getContext().getCanonicalType(CLHSTy); QualType LTy = getContext().getCanonicalType(LHS->getType()); @@ -197,8 +218,7 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, const BlockDecl *BD = BE->getBlockDecl(); // Get the value of the block itself. - SVal V = svalBuilder.getBlockPointer(BD, T, - Pred->getLocationContext(), + SVal V = svalBuilder.getBlockPointer(BD, T, Pred->getLocationContext(), currBldrCtx->blockCount()); ProgramStateRef State = Pred->getState(); @@ -206,7 +226,7 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, // If we created a new MemRegion for the block, we should explicitly bind // the captured variables. if (const BlockDataRegion *BDR = - dyn_cast_or_null(V.getAsRegion())) { + dyn_cast_or_null(V.getAsRegion())) { auto ReferencedVars = BDR->referenced_vars(); auto CI = BD->capture_begin(); @@ -218,9 +238,9 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, // If the capture had a copy expression, use the result of evaluating // that expression, otherwise use the original value. // We rely on the invariant that the block declaration's capture variables - // are a prefix of the BlockDataRegion's referenced vars (which may include - // referenced globals, etc.) to enable fast lookup of the capture for a - // given referenced var. + // are a prefix of the BlockDataRegion's referenced vars (which may + // include referenced globals, etc.) to enable fast lookup of the capture + // for a given referenced var. const Expr *copyExpr = nullptr; if (CI != CE) { assert(CI->getVariable() == capturedR->getDecl()); @@ -244,17 +264,18 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet Tmp; StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx); Bldr.generateNode(BE, Pred, - State->BindExpr(BE, Pred->getLocationContext(), V), - nullptr, ProgramPoint::PostLValueKind); + State->BindExpr(BE, Pred->getLocationContext(), V), nullptr, + ProgramPoint::PostLValueKind); // FIXME: Move all post/pre visits to ::Visit(). getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this); } -ProgramStateRef ExprEngine::handleLValueBitCast( - ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx, - QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr, - ExplodedNode* Pred) { +ProgramStateRef +ExprEngine::handleLValueBitCast(ProgramStateRef state, const Expr *Ex, + const LocationContext *LCtx, QualType T, + QualType ExTy, const CastExpr *CastE, + StmtNodeBuilder &Bldr, ExplodedNode *Pred) { if (T->isLValueReferenceType()) { assert(!CastE->getType()->isLValueReferenceType()); ExTy = getContext().getLValueReferenceType(ExTy); @@ -299,7 +320,8 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, QualType T = CastE->getType(); QualType ExTy = Ex->getType(); - if (const ExplicitCastExpr *ExCast=dyn_cast_or_null(CastE)) + if (const ExplicitCastExpr *ExCast = + dyn_cast_or_null(CastE)) T = ExCast->getTypeAsWritten(); StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx); @@ -308,230 +330,225 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, const LocationContext *LCtx = Pred->getLocationContext(); switch (CastE->getCastKind()) { - case CK_LValueToRValue: - case CK_LValueToRValueBitCast: - llvm_unreachable("LValueToRValue casts handled earlier."); - case CK_ToVoid: - continue; - // The analyzer doesn't do anything special with these casts, - // since it understands retain/release semantics already. - case CK_ARCProduceObject: - case CK_ARCConsumeObject: - case CK_ARCReclaimReturnedObject: - case CK_ARCExtendBlockObject: // Fall-through. - case CK_CopyAndAutoreleaseBlockObject: - // The analyser can ignore atomic casts for now, although some future - // checkers may want to make certain that you're not modifying the same - // value through atomic and nonatomic pointers. - case CK_AtomicToNonAtomic: - case CK_NonAtomicToAtomic: - // True no-ops. - case CK_NoOp: - case CK_ConstructorConversion: - case CK_UserDefinedConversion: - case CK_FunctionToPointerDecay: - case CK_BuiltinFnToFnPtr: { - // Copy the SVal of Ex to CastE. - ProgramStateRef state = Pred->getState(); - const LocationContext *LCtx = Pred->getLocationContext(); - SVal V = state->getSVal(Ex, LCtx); - state = state->BindExpr(CastE, LCtx, V); - Bldr.generateNode(CastE, Pred, state); - continue; - } - case CK_MemberPointerToBoolean: - case CK_PointerToBoolean: { - SVal V = state->getSVal(Ex, LCtx); - auto PTMSV = V.getAs(); - if (PTMSV) - V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy); - if (V.isUndef() || PTMSV) { - state = state->BindExpr(CastE, LCtx, V); - Bldr.generateNode(CastE, Pred, state); - continue; - } - // Explicitly proceed with default handler for this case cascade. - state = - handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); - continue; - } - case CK_Dependent: - case CK_ArrayToPointerDecay: - case CK_BitCast: - case CK_AddressSpaceConversion: - case CK_BooleanToSignedIntegral: - case CK_IntegralToPointer: - case CK_PointerToIntegral: { - SVal V = state->getSVal(Ex, LCtx); - if (isa(V)) { - state = state->BindExpr(CastE, LCtx, UnknownVal()); - Bldr.generateNode(CastE, Pred, state); - continue; - } - // Explicitly proceed with default handler for this case cascade. - state = - handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); - continue; - } - case CK_IntegralToBoolean: - case CK_IntegralToFloating: - case CK_FloatingToIntegral: - case CK_FloatingToBoolean: - case CK_FloatingCast: - case CK_FloatingRealToComplex: - case CK_FloatingComplexToReal: - case CK_FloatingComplexToBoolean: - case CK_FloatingComplexCast: - case CK_FloatingComplexToIntegralComplex: - case CK_IntegralRealToComplex: - case CK_IntegralComplexToReal: - case CK_IntegralComplexToBoolean: - case CK_IntegralComplexCast: - case CK_IntegralComplexToFloatingComplex: - case CK_CPointerToObjCPointerCast: - case CK_BlockPointerToObjCPointerCast: - case CK_AnyPointerToBlockPointerCast: - case CK_ObjCObjectLValueCast: - case CK_ZeroToOCLOpaqueType: - case CK_IntToOCLSampler: - case CK_LValueBitCast: - case CK_FloatingToFixedPoint: - case CK_FixedPointToFloating: - case CK_FixedPointCast: - case CK_FixedPointToBoolean: - case CK_FixedPointToIntegral: - case CK_IntegralToFixedPoint: { - state = - handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); - continue; - } - case CK_IntegralCast: { - // Delegate to SValBuilder to process. - SVal V = state->getSVal(Ex, LCtx); - if (AMgr.options.ShouldSupportSymbolicIntegerCasts) - V = svalBuilder.evalCast(V, T, ExTy); - else - V = svalBuilder.evalIntegralCast(state, V, T, ExTy); + case CK_LValueToRValue: + case CK_LValueToRValueBitCast: + llvm_unreachable("LValueToRValue casts handled earlier."); + case CK_ToVoid: + continue; + // The analyzer doesn't do anything special with these casts, + // since it understands retain/release semantics already. + case CK_ARCProduceObject: + case CK_ARCConsumeObject: + case CK_ARCReclaimReturnedObject: + case CK_ARCExtendBlockObject: // Fall-through. + case CK_CopyAndAutoreleaseBlockObject: + // The analyser can ignore atomic casts for now, although some future + // checkers may want to make certain that you're not modifying the same + // value through atomic and nonatomic pointers. + case CK_AtomicToNonAtomic: + case CK_NonAtomicToAtomic: + // True no-ops. + case CK_NoOp: + case CK_ConstructorConversion: + case CK_UserDefinedConversion: + case CK_FunctionToPointerDecay: + case CK_BuiltinFnToFnPtr: { + // Copy the SVal of Ex to CastE. + ProgramStateRef state = Pred->getState(); + const LocationContext *LCtx = Pred->getLocationContext(); + SVal V = state->getSVal(Ex, LCtx); + state = state->BindExpr(CastE, LCtx, V); + Bldr.generateNode(CastE, Pred, state); + continue; + } + case CK_MemberPointerToBoolean: + case CK_PointerToBoolean: { + SVal V = state->getSVal(Ex, LCtx); + auto PTMSV = V.getAs(); + if (PTMSV) + V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy); + if (V.isUndef() || PTMSV) { state = state->BindExpr(CastE, LCtx, V); Bldr.generateNode(CastE, Pred, state); continue; } - case CK_DerivedToBase: - case CK_UncheckedDerivedToBase: { - // For DerivedToBase cast, delegate to the store manager. - SVal val = state->getSVal(Ex, LCtx); - val = getStoreManager().evalDerivedToBase(val, CastE); - state = state->BindExpr(CastE, LCtx, val); + // Explicitly proceed with default handler for this case cascade. + state = handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); + continue; + } + case CK_Dependent: + case CK_ArrayToPointerDecay: + case CK_BitCast: + case CK_AddressSpaceConversion: + case CK_BooleanToSignedIntegral: + case CK_IntegralToPointer: + case CK_PointerToIntegral: { + SVal V = state->getSVal(Ex, LCtx); + if (isa(V)) { + state = state->BindExpr(CastE, LCtx, UnknownVal()); Bldr.generateNode(CastE, Pred, state); continue; } - // Handle C++ dyn_cast. - case CK_Dynamic: { - SVal val = state->getSVal(Ex, LCtx); + // Explicitly proceed with default handler for this case cascade. + state = handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); + continue; + } + case CK_IntegralToBoolean: + case CK_IntegralToFloating: + case CK_FloatingToIntegral: + case CK_FloatingToBoolean: + case CK_FloatingCast: + case CK_FloatingRealToComplex: + case CK_FloatingComplexToReal: + case CK_FloatingComplexToBoolean: + case CK_FloatingComplexCast: + case CK_FloatingComplexToIntegralComplex: + case CK_IntegralRealToComplex: + case CK_IntegralComplexToReal: + case CK_IntegralComplexToBoolean: + case CK_IntegralComplexCast: + case CK_IntegralComplexToFloatingComplex: + case CK_CPointerToObjCPointerCast: + case CK_BlockPointerToObjCPointerCast: + case CK_AnyPointerToBlockPointerCast: + case CK_ObjCObjectLValueCast: + case CK_ZeroToOCLOpaqueType: + case CK_IntToOCLSampler: + case CK_LValueBitCast: + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: + case CK_FixedPointCast: + case CK_FixedPointToBoolean: + case CK_FixedPointToIntegral: + case CK_IntegralToFixedPoint: { + state = handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); + continue; + } + case CK_IntegralCast: { + // Delegate to SValBuilder to process. + SVal V = state->getSVal(Ex, LCtx); + if (AMgr.options.ShouldSupportSymbolicIntegerCasts) + V = svalBuilder.evalCast(V, T, ExTy); + else + V = svalBuilder.evalIntegralCast(state, V, T, ExTy); + state = state->BindExpr(CastE, LCtx, V); + Bldr.generateNode(CastE, Pred, state); + continue; + } + case CK_DerivedToBase: + case CK_UncheckedDerivedToBase: { + // For DerivedToBase cast, delegate to the store manager. + SVal val = state->getSVal(Ex, LCtx); + val = getStoreManager().evalDerivedToBase(val, CastE); + state = state->BindExpr(CastE, LCtx, val); + Bldr.generateNode(CastE, Pred, state); + continue; + } + // Handle C++ dyn_cast. + case CK_Dynamic: { + SVal val = state->getSVal(Ex, LCtx); - // Compute the type of the result. - QualType resultType = CastE->getType(); - if (CastE->isGLValue()) - resultType = getContext().getPointerType(resultType); + // Compute the type of the result. + QualType resultType = CastE->getType(); + if (CastE->isGLValue()) + resultType = getContext().getPointerType(resultType); - bool Failed = true; + bool Failed = true; - // Check if the value being cast does not evaluates to 0. - if (!val.isZeroConstant()) - if (std::optional V = - StateMgr.getStoreManager().evalBaseToDerived(val, T)) { + // Check if the value being cast does not evaluates to 0. + if (!val.isZeroConstant()) + if (std::optional V = + StateMgr.getStoreManager().evalBaseToDerived(val, T)) { val = *V; Failed = false; - } + } - if (Failed) { - if (T->isReferenceType()) { - // A bad_cast exception is thrown if input value is a reference. - // Currently, we model this, by generating a sink. - Bldr.generateSink(CastE, Pred, state); - continue; - } else { - // If the cast fails on a pointer, bind to 0. - state = state->BindExpr(CastE, LCtx, - svalBuilder.makeNullWithType(resultType)); - } + if (Failed) { + if (T->isReferenceType()) { + // A bad_cast exception is thrown if input value is a reference. + // Currently, we model this, by generating a sink. + Bldr.generateSink(CastE, Pred, state); + continue; } else { - // If we don't know if the cast succeeded, conjure a new symbol. - if (val.isUnknown()) { - DefinedOrUnknownSVal NewSym = - svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType, - currBldrCtx->blockCount()); - state = state->BindExpr(CastE, LCtx, NewSym); - } else - // Else, bind to the derived region value. - state = state->BindExpr(CastE, LCtx, val); + // If the cast fails on a pointer, bind to 0. + state = state->BindExpr(CastE, LCtx, + svalBuilder.makeNullWithType(resultType)); } - Bldr.generateNode(CastE, Pred, state); - continue; - } - case CK_BaseToDerived: { - SVal val = state->getSVal(Ex, LCtx); - QualType resultType = CastE->getType(); - if (CastE->isGLValue()) - resultType = getContext().getPointerType(resultType); - - if (!val.isConstant()) { - std::optional V = getStoreManager().evalBaseToDerived(val, T); - val = V ? *V : UnknownVal(); - } - - // Failed to cast or the result is unknown, fall back to conservative. + } else { + // If we don't know if the cast succeeded, conjure a new symbol. if (val.isUnknown()) { - val = - svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType, - currBldrCtx->blockCount()); - } - state = state->BindExpr(CastE, LCtx, val); - Bldr.generateNode(CastE, Pred, state); - continue; + DefinedOrUnknownSVal NewSym = svalBuilder.conjureSymbolVal( + nullptr, CastE, LCtx, resultType, currBldrCtx->blockCount()); + state = state->BindExpr(CastE, LCtx, NewSym); + } else + // Else, bind to the derived region value. + state = state->BindExpr(CastE, LCtx, val); } - case CK_NullToPointer: { - SVal V = svalBuilder.makeNullWithType(CastE->getType()); - state = state->BindExpr(CastE, LCtx, V); - Bldr.generateNode(CastE, Pred, state); - continue; - } - case CK_NullToMemberPointer: { - SVal V = svalBuilder.getMemberPointer(nullptr); - state = state->BindExpr(CastE, LCtx, V); - Bldr.generateNode(CastE, Pred, state); - continue; + Bldr.generateNode(CastE, Pred, state); + continue; + } + case CK_BaseToDerived: { + SVal val = state->getSVal(Ex, LCtx); + QualType resultType = CastE->getType(); + if (CastE->isGLValue()) + resultType = getContext().getPointerType(resultType); + + if (!val.isConstant()) { + std::optional V = getStoreManager().evalBaseToDerived(val, T); + val = V ? *V : UnknownVal(); } - case CK_DerivedToBaseMemberPointer: - case CK_BaseToDerivedMemberPointer: - case CK_ReinterpretMemberPointer: { - SVal V = state->getSVal(Ex, LCtx); - if (auto PTMSV = V.getAs()) { - SVal CastedPTMSV = - svalBuilder.makePointerToMember(getBasicVals().accumCXXBase( - CastE->path(), *PTMSV, CastE->getCastKind())); - state = state->BindExpr(CastE, LCtx, CastedPTMSV); - Bldr.generateNode(CastE, Pred, state); - continue; - } - // Explicitly proceed with default handler for this case cascade. + + // Failed to cast or the result is unknown, fall back to conservative. + if (val.isUnknown()) { + val = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType, + currBldrCtx->blockCount()); } - [[fallthrough]]; - // Various C++ casts that are not handled yet. - case CK_ToUnion: - case CK_MatrixCast: - case CK_VectorSplat: - case CK_HLSLVectorTruncation: { - QualType resultType = CastE->getType(); - if (CastE->isGLValue()) - resultType = getContext().getPointerType(resultType); - SVal result = svalBuilder.conjureSymbolVal( - /*symbolTag=*/nullptr, CastE, LCtx, resultType, - currBldrCtx->blockCount()); - state = state->BindExpr(CastE, LCtx, result); + state = state->BindExpr(CastE, LCtx, val); + Bldr.generateNode(CastE, Pred, state); + continue; + } + case CK_NullToPointer: { + SVal V = svalBuilder.makeNullWithType(CastE->getType()); + state = state->BindExpr(CastE, LCtx, V); + Bldr.generateNode(CastE, Pred, state); + continue; + } + case CK_NullToMemberPointer: { + SVal V = svalBuilder.getMemberPointer(nullptr); + state = state->BindExpr(CastE, LCtx, V); + Bldr.generateNode(CastE, Pred, state); + continue; + } + case CK_DerivedToBaseMemberPointer: + case CK_BaseToDerivedMemberPointer: + case CK_ReinterpretMemberPointer: { + SVal V = state->getSVal(Ex, LCtx); + if (auto PTMSV = V.getAs()) { + SVal CastedPTMSV = + svalBuilder.makePointerToMember(getBasicVals().accumCXXBase( + CastE->path(), *PTMSV, CastE->getCastKind())); + state = state->BindExpr(CastE, LCtx, CastedPTMSV); Bldr.generateNode(CastE, Pred, state); continue; } + // Explicitly proceed with default handler for this case cascade. + } + [[fallthrough]]; + // Various C++ casts that are not handled yet. + case CK_ToUnion: + case CK_MatrixCast: + case CK_VectorSplat: + case CK_HLSLVectorTruncation: { + QualType resultType = CastE->getType(); + if (CastE->isGLValue()) + resultType = getContext().getPointerType(resultType); + SVal result = svalBuilder.conjureSymbolVal( + /*symbolTag=*/nullptr, CastE, LCtx, resultType, + currBldrCtx->blockCount()); + state = state->BindExpr(CastE, LCtx, result); + Bldr.generateNode(CastE, Pred, state); + continue; + } } } } @@ -579,7 +596,7 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, const VarDecl *VD = dyn_cast_or_null(*DS->decl_begin()); if (!VD) { - //TODO:AZ: remove explicit insertion after refactoring is done. + // TODO:AZ: remove explicit insertion after refactoring is done. Dst.insert(Pred); return; } @@ -591,7 +608,7 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet dstEvaluated; StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx); for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end(); - I!=E; ++I) { + I != E; ++I) { ExplodedNode *N = *I; ProgramStateRef state = N->getState(); const LocationContext *LC = N->getLocationContext(); @@ -622,14 +639,12 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, currBldrCtx->blockCount()); } - B.takeNodes(UpdatedN); ExplodedNodeSet Dst2; evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true); B.addNodes(Dst2); } - } - else { + } else { B.generateNode(DS, N, state); } } @@ -637,7 +652,7 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this); } -void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, +void ExprEngine::VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst) { // This method acts upon CFG elements for logical operators && and || // and attaches the value (true or false) to them as expressions. @@ -654,8 +669,7 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, // Due to this ambiguity, a more reliable solution would have been to // track the short circuit operation history path-sensitively until // we evaluate the respective logical operator. - assert(B->getOpcode() == BO_LAnd || - B->getOpcode() == BO_LOr); + assert(B->getOpcode() == BO_LAnd || B->getOpcode() == BO_LOr); StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); ProgramStateRef state = Pred->getState(); @@ -673,8 +687,8 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, ExplodedNode *N = Pred; while (!N->getLocation().getAs()) { ProgramPoint P = N->getLocation(); - assert(P.getAs()|| P.getAs()); - (void) P; + assert(P.getAs() || P.getAs()); + (void)P; if (N->pred_size() != 1) { // We failed to track back where we came from. Bldr.generateNode(B, Pred, state); @@ -700,14 +714,13 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, // The only terminator (if there is one) that makes sense is a logical op. CFGTerminator T = SrcBlock->getTerminator(); if (const BinaryOperator *Term = cast_or_null(T.getStmt())) { - (void) Term; + (void)Term; assert(Term->isLogicalOp()); assert(SrcBlock->succ_size() == 2); // Did we take the true or false branch? unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0; X = svalBuilder.makeIntVal(constant, B->getType()); - } - else { + } else { // If there is no terminator, by construction the last statement // in SrcBlock is the value of the enclosing expression. // However, we still need to constrain that value to be 0 or 1. @@ -731,8 +744,7 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X)); } -void ExprEngine::VisitInitListExpr(const InitListExpr *IE, - ExplodedNode *Pred, +void ExprEngine::VisitInitListExpr(const InitListExpr *IE, ExplodedNode *Pred, ExplodedNodeSet &Dst) { StmtNodeBuilder B(Pred, Dst, *currBldrCtx); @@ -759,9 +771,9 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE, vals = getBasicVals().prependSVal(V, vals); } - B.generateNode(IE, Pred, - state->BindExpr(IE, LCtx, - svalBuilder.makeCompoundVal(T, vals))); + B.generateNode( + IE, Pred, + state->BindExpr(IE, LCtx, svalBuilder.makeCompoundVal(T, vals))); return; } @@ -779,11 +791,8 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE, B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V)); } -void ExprEngine::VisitGuardedExpr(const Expr *Ex, - const Expr *L, - const Expr *R, - ExplodedNode *Pred, - ExplodedNodeSet &Dst) { +void ExprEngine::VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, + ExplodedNode *Pred, ExplodedNodeSet &Dst) { assert(L && R); StmtNodeBuilder B(Pred, Dst, *currBldrCtx); @@ -793,7 +802,7 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex, // Find the predecessor block. ProgramStateRef SrcState = state; - for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) { + for (const ExplodedNode *N = Pred; N; N = *N->pred_begin()) { ProgramPoint PP = N->getLocation(); if (PP.getAs() || PP.getAs()) { // If the state N has multiple predecessors P, it means that successors @@ -843,9 +852,8 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex, B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true)); } -void ExprEngine:: -VisitOffsetOfExpr(const OffsetOfExpr *OOE, - ExplodedNode *Pred, ExplodedNodeSet &Dst) { +void ExprEngine::VisitOffsetOfExpr(const OffsetOfExpr *OOE, ExplodedNode *Pred, + ExplodedNodeSet &Dst) { StmtNodeBuilder B(Pred, Dst, *currBldrCtx); Expr::EvalResult Result; if (OOE->EvaluateAsInt(Result, getContext())) { @@ -854,18 +862,16 @@ VisitOffsetOfExpr(const OffsetOfExpr *OOE, assert(OOE->getType()->castAs()->isInteger()); assert(IV.isSigned() == OOE->getType()->isSignedIntegerType()); SVal X = svalBuilder.makeIntVal(IV); - B.generateNode(OOE, Pred, - Pred->getState()->BindExpr(OOE, Pred->getLocationContext(), - X)); + B.generateNode( + OOE, Pred, + Pred->getState()->BindExpr(OOE, Pred->getLocationContext(), X)); } // FIXME: Handle the case where __builtin_offsetof is not a constant. } - -void ExprEngine:: -VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, - ExplodedNode *Pred, - ExplodedNodeSet &Dst) { +void ExprEngine::VisitUnaryExprOrTypeTraitExpr( + const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, + ExplodedNodeSet &Dst) { // FIXME: Prechecks eventually go in ::Visit(). ExplodedNodeSet CheckedSet; getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this); @@ -919,7 +925,7 @@ void ExprEngine::handleUOExtension(ExplodedNode *N, const UnaryOperator *U, Bldr.generateNode(U, N, state->BindExpr(U, LCtx, state->getSVal(Ex, LCtx))); } -void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred, +void ExprEngine::VisitUnaryOperator(const UnaryOperator *U, ExplodedNode *Pred, ExplodedNodeSet &Dst) { // FIXME: Prechecks eventually go in ::Visit(). ExplodedNodeSet CheckedSet; @@ -947,7 +953,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred, } // For all other types, UO_Real is an identity operation. - assert (U->getType() == Ex->getType()); + assert(U->getType() == Ex->getType()); ProgramStateRef state = N->getState(); const LocationContext *LCtx = N->getLocationContext(); Bldr.generateNode(U, N, @@ -1000,7 +1006,7 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred, case UO_LNot: case UO_Minus: case UO_Not: { - assert (!U->isGLValue()); + assert(!U->isGLValue()); const Expr *Ex = U->getSubExpr()->IgnoreParens(); ProgramStateRef state = N->getState(); const LocationContext *LCtx = N->getLocationContext(); @@ -1014,37 +1020,37 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred, } switch (U->getOpcode()) { - default: - llvm_unreachable("Invalid Opcode."); - case UO_Not: - // FIXME: Do we need to handle promotions? - state = state->BindExpr( - U, LCtx, svalBuilder.evalComplement(V.castAs())); - break; - case UO_Minus: - // FIXME: Do we need to handle promotions? - state = state->BindExpr(U, LCtx, - svalBuilder.evalMinus(V.castAs())); - break; - case UO_LNot: - // C99 6.5.3.3: "The expression !E is equivalent to (0==E)." - // - // Note: technically we do "E == 0", but this is the same in the - // transfer functions as "0 == E". - SVal Result; - if (std::optional LV = V.getAs()) { + default: + llvm_unreachable("Invalid Opcode."); + case UO_Not: + // FIXME: Do we need to handle promotions? + state = state->BindExpr(U, LCtx, + svalBuilder.evalComplement(V.castAs())); + break; + case UO_Minus: + // FIXME: Do we need to handle promotions? + state = + state->BindExpr(U, LCtx, svalBuilder.evalMinus(V.castAs())); + break; + case UO_LNot: + // C99 6.5.3.3: "The expression !E is equivalent to (0==E)." + // + // Note: technically we do "E == 0", but this is the same in the + // transfer functions as "0 == E". + SVal Result; + if (std::optional LV = V.getAs()) { Loc X = svalBuilder.makeNullWithType(Ex->getType()); Result = evalBinOp(state, BO_EQ, *LV, X, U->getType()); - } else if (Ex->getType()->isFloatingType()) { + } else if (Ex->getType()->isFloatingType()) { // FIXME: handle floating point types. Result = UnknownVal(); - } else { + } else { nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType())); Result = evalBinOp(state, BO_EQ, V.castAs(), X, U->getType()); - } + } - state = state->BindExpr(U, LCtx, Result); - break; + state = state->BindExpr(U, LCtx, Result); + break; } Bldr.generateNode(U, N, state); break; @@ -1055,11 +1061,11 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred, getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this); } -void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U, +void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator *U, ExplodedNode *Pred, ExplodedNodeSet &Dst) { // Handle ++ and -- (both pre- and post-increment). - assert (U->isIncrementDecrementOp()); + assert(U->isIncrementDecrementOp()); const Expr *Ex = U->getSubExpr()->IgnoreParens(); const LocationContext *LCtx = Pred->getLocationContext(); @@ -1117,24 +1123,23 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U, Result = evalBinOp(state, Op, V2, RHS, U->getType()); // Conjure a new symbol if necessary to recover precision. - if (Result.isUnknown()){ - DefinedOrUnknownSVal SymVal = - svalBuilder.conjureSymbolVal(nullptr, U, LCtx, - currBldrCtx->blockCount()); + if (Result.isUnknown()) { + DefinedOrUnknownSVal SymVal = svalBuilder.conjureSymbolVal( + nullptr, U, LCtx, currBldrCtx->blockCount()); Result = SymVal; // If the value is a location, ++/-- should always preserve // non-nullness. Check if the original value was non-null, and if so // propagate that constraint. if (Loc::isLocType(U->getType())) { - DefinedOrUnknownSVal Constraint = - svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType())); + DefinedOrUnknownSVal Constraint = svalBuilder.evalEQ( + state, V2, svalBuilder.makeZeroVal(U->getType())); if (!state->assume(Constraint, true)) { // It isn't feasible for the original value to be null. // Propagate this constraint. - Constraint = svalBuilder.evalEQ(state, SymVal, - svalBuilder.makeZeroVal(U->getType())); + Constraint = svalBuilder.evalEQ( + state, SymVal, svalBuilder.makeZeroVal(U->getType())); state = state->assume(Constraint, false); assert(state); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 504fd7f05e0f9..33a994813a0f2 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -149,10 +149,9 @@ SVal ExprEngine::computeObjectUnderConstruction( if (Init->isBaseInitializer()) { const auto *ThisReg = cast(ThisVal.getAsRegion()); const CXXRecordDecl *BaseClass = - Init->getBaseClass()->getAsCXXRecordDecl(); - const auto *BaseReg = - MRMgr.getCXXBaseObjectRegion(BaseClass, ThisReg, - Init->isBaseVirtual()); + Init->getBaseClass()->getAsCXXRecordDecl(); + const auto *BaseReg = MRMgr.getCXXBaseObjectRegion( + BaseClass, ThisReg, Init->isBaseVirtual()); return SVB.makeLoc(BaseReg); } if (Init->isDelegatingInitializer()) @@ -191,7 +190,7 @@ SVal ExprEngine::computeObjectUnderConstruction( return loc::MemRegionVal(R); } - return V; + return V; } // TODO: Detect when the allocator returns a null pointer. // Constructor shall not be called in this case. @@ -413,99 +412,99 @@ ProgramStateRef ExprEngine::updateObjectsUnderConstruction( case ConstructionContext::SimpleVariableKind: { const auto *DSCC = cast(CC); return addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, V); - } - case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind: - case ConstructionContext::SimpleConstructorInitializerKind: { - const auto *ICC = cast(CC); - const auto *Init = ICC->getCXXCtorInitializer(); - // Base and delegating initializers handled above - assert(Init->isAnyMemberInitializer() && - "Base and delegating initializers should have been handled by" - "computeObjectUnderConstruction()"); - return addObjectUnderConstruction(State, Init, LCtx, V); - } - case ConstructionContext::NewAllocatedObjectKind: { + } + case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind: + case ConstructionContext::SimpleConstructorInitializerKind: { + const auto *ICC = cast(CC); + const auto *Init = ICC->getCXXCtorInitializer(); + // Base and delegating initializers handled above + assert(Init->isAnyMemberInitializer() && + "Base and delegating initializers should have been handled by" + "computeObjectUnderConstruction()"); + return addObjectUnderConstruction(State, Init, LCtx, V); + } + case ConstructionContext::NewAllocatedObjectKind: { + return State; + } + case ConstructionContext::SimpleReturnedValueKind: + case ConstructionContext::CXX17ElidedCopyReturnedValueKind: { + const StackFrameContext *SFC = LCtx->getStackFrame(); + const LocationContext *CallerLCtx = SFC->getParent(); + if (!CallerLCtx) { + // No extra work is necessary in top frame. return State; } - case ConstructionContext::SimpleReturnedValueKind: - case ConstructionContext::CXX17ElidedCopyReturnedValueKind: { - const StackFrameContext *SFC = LCtx->getStackFrame(); - const LocationContext *CallerLCtx = SFC->getParent(); - if (!CallerLCtx) { - // No extra work is necessary in top frame. - return State; - } - - auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()] - .getAs(); - assert(RTC && "Could not have had a target region without it"); - if (isa(CallerLCtx)) { - // Unwrap block invocation contexts. They're mostly part of - // the current stack frame. - CallerLCtx = CallerLCtx->getParent(); - assert(!isa(CallerLCtx)); - } - return updateObjectsUnderConstruction(V, - cast(SFC->getCallSite()), State, CallerLCtx, - RTC->getConstructionContext(), CallOpts); + auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()] + .getAs(); + assert(RTC && "Could not have had a target region without it"); + if (isa(CallerLCtx)) { + // Unwrap block invocation contexts. They're mostly part of + // the current stack frame. + CallerLCtx = CallerLCtx->getParent(); + assert(!isa(CallerLCtx)); } - case ConstructionContext::ElidedTemporaryObjectKind: { - assert(AMgr.getAnalyzerOptions().ShouldElideConstructors); - if (!CallOpts.IsElidableCtorThatHasNotBeenElided) { - const auto *TCC = cast(CC); - State = updateObjectsUnderConstruction( - V, TCC->getConstructorAfterElision(), State, LCtx, - TCC->getConstructionContextAfterElision(), CallOpts); - - // Remember that we've elided the constructor. - State = addObjectUnderConstruction( - State, TCC->getConstructorAfterElision(), LCtx, V); - - // Remember that we've elided the destructor. - if (const auto *BTE = TCC->getCXXBindTemporaryExpr()) - State = elideDestructor(State, BTE, LCtx); - - // Instead of materialization, shamelessly return - // the final object destination. - if (const auto *MTE = TCC->getMaterializedTemporaryExpr()) - State = addObjectUnderConstruction(State, MTE, LCtx, V); - - return State; - } - // If we decided not to elide the constructor, proceed as if - // it's a simple temporary. - [[fallthrough]]; - } - case ConstructionContext::SimpleTemporaryObjectKind: { - const auto *TCC = cast(CC); + + return updateObjectsUnderConstruction( + V, cast(SFC->getCallSite()), State, CallerLCtx, + RTC->getConstructionContext(), CallOpts); + } + case ConstructionContext::ElidedTemporaryObjectKind: { + assert(AMgr.getAnalyzerOptions().ShouldElideConstructors); + if (!CallOpts.IsElidableCtorThatHasNotBeenElided) { + const auto *TCC = cast(CC); + State = updateObjectsUnderConstruction( + V, TCC->getConstructorAfterElision(), State, LCtx, + TCC->getConstructionContextAfterElision(), CallOpts); + + // Remember that we've elided the constructor. + State = addObjectUnderConstruction( + State, TCC->getConstructorAfterElision(), LCtx, V); + + // Remember that we've elided the destructor. if (const auto *BTE = TCC->getCXXBindTemporaryExpr()) - State = addObjectUnderConstruction(State, BTE, LCtx, V); + State = elideDestructor(State, BTE, LCtx); + // Instead of materialization, shamelessly return + // the final object destination. if (const auto *MTE = TCC->getMaterializedTemporaryExpr()) State = addObjectUnderConstruction(State, MTE, LCtx, V); return State; } - case ConstructionContext::LambdaCaptureKind: { - const auto *LCC = cast(CC); + // If we decided not to elide the constructor, proceed as if + // it's a simple temporary. + [[fallthrough]]; + } + case ConstructionContext::SimpleTemporaryObjectKind: { + const auto *TCC = cast(CC); + if (const auto *BTE = TCC->getCXXBindTemporaryExpr()) + State = addObjectUnderConstruction(State, BTE, LCtx, V); - // If we capture and array, we want to store the super region, not a - // sub-region. - if (const auto *EL = dyn_cast_or_null(V.getAsRegion())) - V = loc::MemRegionVal(EL->getSuperRegion()); + if (const auto *MTE = TCC->getMaterializedTemporaryExpr()) + State = addObjectUnderConstruction(State, MTE, LCtx, V); - return addObjectUnderConstruction( - State, {LCC->getLambdaExpr(), LCC->getIndex()}, LCtx, V); - } - case ConstructionContext::ArgumentKind: { - const auto *ACC = cast(CC); - if (const auto *BTE = ACC->getCXXBindTemporaryExpr()) - State = addObjectUnderConstruction(State, BTE, LCtx, V); + return State; + } + case ConstructionContext::LambdaCaptureKind: { + const auto *LCC = cast(CC); - return addObjectUnderConstruction( - State, {ACC->getCallLikeExpr(), ACC->getIndex()}, LCtx, V); - } + // If we capture and array, we want to store the super region, not a + // sub-region. + if (const auto *EL = dyn_cast_or_null(V.getAsRegion())) + V = loc::MemRegionVal(EL->getSuperRegion()); + + return addObjectUnderConstruction( + State, {LCC->getLambdaExpr(), LCC->getIndex()}, LCtx, V); + } + case ConstructionContext::ArgumentKind: { + const auto *ACC = cast(CC); + if (const auto *BTE = ACC->getCXXBindTemporaryExpr()) + State = addObjectUnderConstruction(State, BTE, LCtx, V); + + return addObjectUnderConstruction( + State, {ACC->getCallLikeExpr(), ACC->getIndex()}, LCtx, V); + } } llvm_unreachable("Unhandled construction context!"); } @@ -579,8 +578,7 @@ bindRequiredArrayElementToEnvironment(ProgramStateRef State, return State->BindExpr(CE->getArg(0), LCtx, NthElem); } -void ExprEngine::handleConstructor(const Expr *E, - ExplodedNode *Pred, +void ExprEngine::handleConstructor(const Expr *E, ExplodedNode *Pred, ExplodedNodeSet &destNodes) { const auto *CE = dyn_cast(E); const auto *CIE = dyn_cast(E); @@ -594,16 +592,16 @@ void ExprEngine::handleConstructor(const Expr *E, if (CE) { if (std::optional ElidedTarget = getObjectUnderConstruction(State, CE, LCtx)) { - // We've previously modeled an elidable constructor by pretending that - // it in fact constructs into the correct target. This constructor can - // therefore be skipped. - Target = *ElidedTarget; - StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx); - State = finishObjectConstruction(State, CE, LCtx); - if (auto L = Target.getAs()) - State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType())); - Bldr.generateNode(CE, Pred, State); - return; + // We've previously modeled an elidable constructor by pretending that + // it in fact constructs into the correct target. This constructor can + // therefore be skipped. + Target = *ElidedTarget; + StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx); + State = finishObjectConstruction(State, CE, LCtx); + if (auto L = Target.getAs()) + State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType())); + Bldr.generateNode(CE, Pred, State); + return; } } @@ -701,8 +699,7 @@ void ExprEngine::handleConstructor(const Expr *E, [[fallthrough]]; case CXXConstructionKind::Delegating: { const CXXMethodDecl *CurCtor = cast(LCtx->getDecl()); - Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, - LCtx->getStackFrame()); + Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, LCtx->getStackFrame()); SVal ThisVal = State->getSVal(ThisPtr); if (CK == CXXConstructionKind::Delegating) { @@ -771,8 +768,8 @@ void ExprEngine::handleConstructor(const Expr *E, } ExplodedNodeSet DstPreCall; - getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized, - *Call, *this); + getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized, *Call, + *this); ExplodedNodeSet DstEvaluated; @@ -835,9 +832,8 @@ void ExprEngine::handleConstructor(const Expr *E, // If there were other constructors called for object-type arguments // of this constructor, clean them up. ExplodedNodeSet DstPostCall; - getCheckerManager().runCheckersForPostCall(DstPostCall, - DstPostArgumentCleanup, - *Call, *this); + getCheckerManager().runCheckersForPostCall( + DstPostCall, DstPostArgumentCleanup, *Call, *this); getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, E, *this); } @@ -853,12 +849,9 @@ void ExprEngine::VisitCXXInheritedCtorInitExpr( handleConstructor(CE, Pred, Dst); } -void ExprEngine::VisitCXXDestructor(QualType ObjectType, - const MemRegion *Dest, - const Stmt *S, - bool IsBaseDtor, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, +void ExprEngine::VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, + const Stmt *S, bool IsBaseDtor, + ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &CallOpts) { assert(S && "A destructor without a trigger!"); const LocationContext *LCtx = Pred->getLocationContext(); @@ -893,8 +886,8 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType, } else { static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor"); NodeBuilder Bldr(Pred, Dst, *currBldrCtx); - Bldr.generateSink(Pred->getLocation().withTag(&T), - Pred->getState(), Pred); + Bldr.generateSink(Pred->getLocation().withTag(&T), Pred->getState(), + Pred); return; } } @@ -908,16 +901,14 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType, "Error evaluating destructor"); ExplodedNodeSet DstPreCall; - getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, - *Call, *this); + getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, *Call, *this); ExplodedNodeSet DstInvalidated; StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); for (ExplodedNode *N : DstPreCall) defaultEvalCall(Bldr, N, *Call, CallOpts); - getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, - *Call, *this); + getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, *Call, *this); } void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, @@ -933,8 +924,7 @@ void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, CEMgr.getCXXAllocatorCall(CNE, State, LCtx, getCFGElementRef()); ExplodedNodeSet DstPreCall; - getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, - *Call, *this); + getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, *Call, *this); ExplodedNodeSet DstPostCall; StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx); @@ -993,7 +983,7 @@ void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, } void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, - ExplodedNodeSet &Dst) { + ExplodedNodeSet &Dst) { // FIXME: Much of this should eventually migrate to CXXAllocatorCall. // Also, we need to decide how allocators actually work -- they're not // really part of the CXXNewExpr because they happen BEFORE the @@ -1165,15 +1155,13 @@ void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, } void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, - ExplodedNodeSet &Dst) { + ExplodedNodeSet &Dst) { StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); // Get the this object region from StoreManager. const LocationContext *LCtx = Pred->getLocationContext(); - const MemRegion *R = - svalBuilder.getRegionManager().getCXXThisRegion( - getContext().getCanonicalType(TE->getType()), - LCtx); + const MemRegion *R = svalBuilder.getRegionManager().getCXXThisRegion( + getContext().getCanonicalType(TE->getType()), LCtx); ProgramStateRef state = Pred->getState(); SVal V = state->getSVal(loc::MemRegionVal(R)); @@ -1185,8 +1173,8 @@ void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, const LocationContext *LocCtxt = Pred->getLocationContext(); // Get the region of the lambda itself. - const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion( - LE, LocCtxt); + const MemRegion *R = + svalBuilder.getRegionManager().getCXXTempObjectRegion(LE, LocCtxt); SVal V = loc::MemRegionVal(R); ProgramStateRef State = Pred->getState(); @@ -1246,9 +1234,8 @@ void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet Tmp; StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx); // FIXME: is this the right program point kind? - Bldr.generateNode(LE, Pred, - State->BindExpr(LE, LocCtxt, LambdaRVal), - nullptr, ProgramPoint::PostLValueKind); + Bldr.generateNode(LE, Pred, State->BindExpr(LE, LocCtxt, LambdaRVal), nullptr, + ProgramPoint::PostLValueKind); // FIXME: Move all post/pre visits to ::Visit(). getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 4755b6bfa6dc0..4c06d205981c5 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -32,16 +32,16 @@ using namespace ento; #define DEBUG_TYPE "ExprEngine" -STATISTIC(NumOfDynamicDispatchPathSplits, - "The # of times we split the path due to imprecise dynamic dispatch info"); +STATISTIC( + NumOfDynamicDispatchPathSplits, + "The # of times we split the path due to imprecise dynamic dispatch info"); -STATISTIC(NumInlinedCalls, - "The # of times we inlined a call"); +STATISTIC(NumInlinedCalls, "The # of times we inlined a call"); STATISTIC(NumReachedInlineCountMax, - "The # of times we reached inline count maximum"); + "The # of times we reached inline count maximum"); -void ExprEngine::processCallEnter(NodeBuilderContext& BC, CallEnter CE, +void ExprEngine::processCallEnter(NodeBuilderContext &BC, CallEnter CE, ExplodedNode *Pred) { // Get the entry block in the CFG of the callee. const StackFrameContext *calleeCtx = CE.getCalleeContext(); @@ -74,8 +74,8 @@ void ExprEngine::processCallEnter(NodeBuilderContext& BC, CallEnter CE, // Find the last statement on the path to the exploded node and the // corresponding Block. -static std::pair getLastStmt(const ExplodedNode *Node) { +static std::pair +getLastStmt(const ExplodedNode *Node) { const Stmt *S = nullptr; const CFGBlock *Blk = nullptr; const StackFrameContext *SF = Node->getStackFrame(); @@ -162,7 +162,7 @@ static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy, return UnknownVal(); } -void ExprEngine::removeDeadOnEndOfFunction(NodeBuilderContext& BC, +void ExprEngine::removeDeadOnEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst) { // Find the last statement in the function and the corresponding basic block. @@ -186,8 +186,9 @@ void ExprEngine::removeDeadOnEndOfFunction(NodeBuilderContext& BC, ProgramPoint::PostStmtPurgeDeadSymbolsKind); } -static bool wasDifferentDeclUsedForInlining(CallEventRef<> Call, - const StackFrameContext *calleeCtx) { +static bool +wasDifferentDeclUsedForInlining(CallEventRef<> Call, + const StackFrameContext *calleeCtx) { const Decl *RuntimeCallee = calleeCtx->getDecl(); const Decl *StaticDecl = Call->getDecl(); assert(RuntimeCallee); @@ -258,8 +259,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { // The parent context might not be a stack frame, so make sure we // look up the first enclosing stack frame. - const StackFrameContext *callerCtx = - calleeCtx->getParent()->getStackFrame(); + const StackFrameContext *callerCtx = calleeCtx->getParent()->getStackFrame(); const Stmt *CE = calleeCtx->getCallSite(); ProgramStateRef state = CEBNode->getState(); @@ -301,7 +301,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { // Ensure that the return type matches the type of the returned Expr. if (wasDifferentDeclUsedForInlining(Call, calleeCtx)) { QualType ReturnedTy = - CallEvent::getDeclaredResultType(calleeCtx->getDecl()); + CallEvent::getDeclaredResultType(calleeCtx->getDecl()); if (!ReturnedTy.isNull()) { if (const Expr *Ex = dyn_cast(CE)) { V = adjustReturnValue(V, Ex->getType(), ReturnedTy, @@ -316,7 +316,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { // Bind the constructed object value to CXXConstructExpr. if (const CXXConstructExpr *CCE = dyn_cast(CE)) { loc::MemRegionVal This = - svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx); + svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx); SVal ThisV = state->getSVal(This); ThisV = state->getSVal(ThisV.castAs()); state = state->BindExpr(CCE, callerCtx, ThisV); @@ -419,8 +419,8 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { } else if (CE && !(isa(CE) && // Called when visiting CXXNewExpr. AMgr.getAnalyzerOptions().MayInlineCXXAllocator)) { - getCheckerManager().runCheckersForPostStmt(Dst, DstPostCall, CE, - *this, /*wasInlined=*/true); + getCheckerManager().runCheckersForPostStmt(Dst, DstPostCall, CE, *this, + /*wasInlined=*/true); } else { Dst.insert(DstPostCall); } @@ -456,7 +456,7 @@ bool ExprEngine::isHuge(AnalysisDeclContext *ADC) const { } void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx, - bool &IsRecursive, unsigned &StackDepth) { + bool &IsRecursive, unsigned &StackDepth) { IsRecursive = false; StackDepth = 0; @@ -489,14 +489,14 @@ void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx, // This is the map from the receiver region to a bool, specifying either we // consider this region's information precise or not along the given path. namespace { - enum DynamicDispatchMode { - DynamicDispatchModeInlined = 1, - DynamicDispatchModeConservative - }; +enum DynamicDispatchMode { + DynamicDispatchModeInlined = 1, + DynamicDispatchModeConservative +}; } // end anonymous namespace -REGISTER_MAP_WITH_PROGRAMSTATE(DynamicDispatchBifurcationMap, - const MemRegion *, unsigned) +REGISTER_MAP_WITH_PROGRAMSTATE(DynamicDispatchBifurcationMap, const MemRegion *, + unsigned) REGISTER_TRAIT_WITH_PROGRAMSTATE(CTUDispatchBifurcation, bool) void ExprEngine::ctuBifurcate(const CallEvent &Call, const Decl *D, @@ -540,9 +540,8 @@ void ExprEngine::inlineCall(WorkList *WList, const CallEvent &Call, const BlockDataRegion *BR = cast(Call).getBlockRegion(); assert(BR && "If we have the block definition we should have its region"); AnalysisDeclContext *BlockCtx = AMgr.getAnalysisDeclContext(D); - ParentOfCallee = BlockCtx->getBlockInvocationContext(CallerSFC, - cast(D), - BR); + ParentOfCallee = + BlockCtx->getBlockInvocationContext(CallerSFC, cast(D), BR); } // This may be NULL, but that's fine. @@ -622,8 +621,7 @@ void ExprEngine::VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, // the created nodes in 'Dst'. // Note that if the call was inlined, dstCallEvaluated will be empty. // The post-CallExpr check will occur in processCallExit. - getCheckerManager().runCheckersForPostStmt(dst, dstCallEvaluated, CE, - *this); + getCheckerManager().runCheckersForPostStmt(dst, dstCallEvaluated, CE, *this); } ProgramStateRef ExprEngine::finishArgumentConstruction(ProgramStateRef State, @@ -641,7 +639,8 @@ ProgramStateRef ExprEngine::finishArgumentConstruction(ProgramStateRef State, SVal VV = *V; (void)VV; assert(cast(VV.castAs().getRegion()) - ->getStackFrame()->getParent() + ->getStackFrame() + ->getParent() ->getStackFrame() == LC->getStackFrame()); State = finishObjectConstruction(State, {E, I}, LC); } @@ -680,8 +679,7 @@ void ExprEngine::evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, // Run any pre-call checks using the generic call interface. ExplodedNodeSet dstPreVisit; - getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred, - Call, *this); + getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred, Call, *this); // Actually evaluate the function call. We try each of the checkers // to see if the can evaluate the function call, and get a callback at @@ -723,7 +721,8 @@ void ExprEngine::evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, if (Pointee.isConstQualified() || Pointee->isVoidType()) continue; if (const MemRegion *MR = Call.getArgSVal(Arg).getAsRegion()) - Escaped.emplace_back(loc::MemRegionVal(MR), State->getSVal(MR, Pointee)); + Escaped.emplace_back(loc::MemRegionVal(MR), + State->getSVal(MR, Pointee)); } } @@ -756,7 +755,8 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call, return State->BindExpr(E, LCtx, Msg->getReceiverSVal()); } } - } else if (const CXXConstructorCall *C = dyn_cast(&Call)){ + } else if (const CXXConstructorCall *C = + dyn_cast(&Call)) { SVal ThisV = C->getCXXThisVal(); ThisV = State->getSVal(ThisV.castAs()); return State->BindExpr(E, LCtx, ThisV); @@ -781,7 +781,8 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call, // the structure is a product of conservative evaluation // and therefore contains nothing interesting at this point. RegionAndSymbolInvalidationTraits ITraits; - ITraits.setTrait(TargetR, + ITraits.setTrait( + TargetR, RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); State = State->invalidateRegions(TargetR, E, Count, LCtx, /* CausesPointerEscape=*/false, nullptr, @@ -829,7 +830,8 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call, // Conservatively evaluate call by invalidating regions and binding // a conjured return value. void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr, - ExplodedNode *Pred, ProgramStateRef State) { + ExplodedNode *Pred, + ProgramStateRef State) { State = Call.invalidateRegions(currBldrCtx->blockCount(), State); State = bindReturnValue(Call, Pred->getLocationContext(), State); @@ -862,8 +864,8 @@ ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred, const CXXConstructExpr *CtorExpr = Ctor.getOriginExpr(); auto CCE = getCurrentCFGElement().getAs(); - const ConstructionContext *CC = CCE ? CCE->getConstructionContext() - : nullptr; + const ConstructionContext *CC = + CCE ? CCE->getConstructionContext() : nullptr; if (llvm::isa_and_nonnull(CC) && !Opts.MayInlineCXXAllocator) @@ -931,8 +933,7 @@ ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred, } // Allow disabling temporary destructor inlining with a separate option. - if (CallOpts.IsTemporaryCtorOrDtor && - !Opts.MayInlineCXXTemporaryDtors) + if (CallOpts.IsTemporaryCtorOrDtor && !Opts.MayInlineCXXTemporaryDtors) return CIP_DisallowedOnce; // If we did not find the correct this-region, it would be pointless @@ -974,8 +975,7 @@ static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD, /// Our heuristic for this is whether it contains a method named 'begin()' or a /// nested type named 'iterator' or 'iterator_category'. static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD) { - return hasMember(Ctx, RD, "begin") || - hasMember(Ctx, RD, "iterator") || + return hasMember(Ctx, RD, "begin") || hasMember(Ctx, RD, "iterator") || hasMember(Ctx, RD, "iterator_category"); } @@ -984,8 +984,7 @@ static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD) { /// /// We generally do a poor job modeling most containers right now, and might /// prefer not to inline their methods. -static bool isContainerMethod(const ASTContext &Ctx, - const FunctionDecl *FD) { +static bool isContainerMethod(const ASTContext &Ctx, const FunctionDecl *FD) { if (const CXXMethodDecl *MD = dyn_cast(FD)) return isContainerClass(Ctx, MD->getParent()); return false; @@ -1001,7 +1000,7 @@ static bool isCXXSharedPtrDtor(const FunctionDecl *FD) { const CXXRecordDecl *RD = Dtor->getParent(); if (const IdentifierInfo *II = RD->getDeclName().getAsIdentifierInfo()) if (II->isStr("shared_ptr")) - return true; + return true; return false; } @@ -1266,17 +1265,16 @@ void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred, conservativeEvalCall(*Call, Bldr, Pred, State); } -void ExprEngine::BifurcateCall(const MemRegion *BifurReg, - const CallEvent &Call, const Decl *D, - NodeBuilder &Bldr, ExplodedNode *Pred) { +void ExprEngine::BifurcateCall(const MemRegion *BifurReg, const CallEvent &Call, + const Decl *D, NodeBuilder &Bldr, + ExplodedNode *Pred) { assert(BifurReg); BifurReg = BifurReg->StripCasts(); // Check if we've performed the split already - note, we only want // to split the path once per memory region. ProgramStateRef State = Pred->getState(); - const unsigned *BState = - State->get(BifurReg); + const unsigned *BState = State->get(BifurReg); if (BState) { // If we are on "inline path", keep inlining if possible. if (*BState == DynamicDispatchModeInlined) @@ -1290,14 +1288,12 @@ void ExprEngine::BifurcateCall(const MemRegion *BifurReg, // If we got here, this is the first time we process a message to this // region, so split the path. - ProgramStateRef IState = - State->set(BifurReg, - DynamicDispatchModeInlined); + ProgramStateRef IState = State->set( + BifurReg, DynamicDispatchModeInlined); ctuBifurcate(Call, D, Bldr, Pred, IState); - ProgramStateRef NoIState = - State->set(BifurReg, - DynamicDispatchModeConservative); + ProgramStateRef NoIState = State->set( + BifurReg, DynamicDispatchModeConservative); conservativeEvalCall(Call, Bldr, Pred, NoIState); NumOfDynamicDispatchPathSplits++; @@ -1312,7 +1308,8 @@ void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred, if (RS->getRetValue()) { for (ExplodedNodeSet::iterator it = dstPreVisit.begin(), - ei = dstPreVisit.end(); it != ei; ++it) { + ei = dstPreVisit.end(); + it != ei; ++it) { B.generateNode(RS, *it, (*it)->getState()); } } diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp index f075df3ab5e4d..b8280131bc470 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp @@ -66,8 +66,8 @@ static void populateObjCForDestinationSet( SVal V; if (hasElements) { - SymbolRef Sym = SymMgr.conjureSymbol(elem, LCtx, T, - currBldrCtx->blockCount()); + SymbolRef Sym = + SymMgr.conjureSymbol(elem, LCtx, T, currBldrCtx->blockCount()); V = svalBuilder.makeLoc(Sym); } else { V = svalBuilder.makeIntVal(0, T); @@ -144,8 +144,7 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); } -void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME, - ExplodedNode *Pred, +void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst) { CallEventManager &CEMgr = getStateManager().getCallEventManager(); CallEventRef Msg = CEMgr.getObjCMethodCall( @@ -197,8 +196,7 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME, SVal recVal = Msg->getReceiverSVal(); if (!recVal.isUndef()) { // Bifurcate the state into nil and non-nil ones. - DefinedOrUnknownSVal receiverVal = - recVal.castAs(); + DefinedOrUnknownSVal receiverVal = recVal.castAs(); ProgramStateRef State = Pred->getState(); ProgramStateRef notNilState, nilState; @@ -241,8 +239,8 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME, // Handle the previsits checks. ExplodedNodeSet dstPrevisit; - getCheckerManager().runCheckersForPreObjCMessage(dstPrevisit, Pred, - *Msg, *this); + getCheckerManager().runCheckersForPreObjCMessage(dstPrevisit, Pred, *Msg, + *this); ExplodedNodeSet dstGenericPrevisit; getCheckerManager().runCheckersForPreCall(dstGenericPrevisit, dstPrevisit, *Msg, *this); @@ -252,7 +250,8 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME, StmtNodeBuilder Bldr(dstGenericPrevisit, dstEval, *currBldrCtx); for (ExplodedNodeSet::iterator DI = dstGenericPrevisit.begin(), - DE = dstGenericPrevisit.end(); DI != DE; ++DI) { + DE = dstGenericPrevisit.end(); + DI != DE; ++DI) { ExplodedNode *Pred = *DI; ProgramStateRef State = Pred->getState(); CallEventRef UpdatedMsg = Msg.cloneWithState(State); @@ -287,11 +286,11 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME, finishArgumentConstruction(dstArgCleanup, I, *Msg); ExplodedNodeSet dstPostvisit; - getCheckerManager().runCheckersForPostCall(dstPostvisit, dstArgCleanup, - *Msg, *this); + getCheckerManager().runCheckersForPostCall(dstPostvisit, dstArgCleanup, *Msg, + *this); // Finally, perform the post-condition check of the ObjCMessageExpr and store // the created nodes in 'Dst'. - getCheckerManager().runCheckersForPostObjCMessage(Dst, dstPostvisit, - *Msg, *this); + getCheckerManager().runCheckersForPostObjCMessage(Dst, dstPostvisit, *Msg, + *this); } diff --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index fb5030d373c2f..8f55bb3e0e9ec 100644 --- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -242,8 +242,7 @@ void ento::createSarifHTMLDiagnosticConsumer( //===----------------------------------------------------------------------===// void HTMLDiagnostics::FlushDiagnosticsImpl( - std::vector &Diags, - FilesMade *filesMade) { + std::vector &Diags, FilesMade *filesMade) { for (const auto Diag : Diags) ReportDiag(*Diag, filesMade); } @@ -260,14 +259,14 @@ static llvm::SmallString<32> getIssueHash(const PathDiagnostic &D, D.getDeclWithIssue(), PP.getLangOpts()); } -void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, +void HTMLDiagnostics::ReportDiag(const PathDiagnostic &D, FilesMade *filesMade) { // Create the HTML directory if it is missing. if (!createdDir) { createdDir = true; if (std::error_code ec = llvm::sys::fs::create_directories(Directory)) { - llvm::errs() << "warning: could not create directory '" - << Directory << "': " << ec.message() << '\n'; + llvm::errs() << "warning: could not create directory '" << Directory + << "': " << ec.message() << '\n'; noDir = true; return; } @@ -284,24 +283,23 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, const SourceManager &SMgr = path.front()->getLocation().getManager(); // Create a new rewriter to generate HTML. - Rewriter R(const_cast(SMgr), PP.getLangOpts()); + Rewriter R(const_cast(SMgr), PP.getLangOpts()); // Get the function/method name SmallString<128> declName("unknown"); int offsetDecl = 0; if (const Decl *DeclWithIssue = D.getDeclWithIssue()) { - if (const auto *ND = dyn_cast(DeclWithIssue)) - declName = ND->getDeclName().getAsString(); - - if (const Stmt *Body = DeclWithIssue->getBody()) { - // Retrieve the relative position of the declaration which will be used - // for the file name - FullSourceLoc L( - SMgr.getExpansionLoc(path.back()->getLocation().asLocation()), - SMgr); - FullSourceLoc FunL(SMgr.getExpansionLoc(Body->getBeginLoc()), SMgr); - offsetDecl = L.getExpansionLineNumber() - FunL.getExpansionLineNumber(); - } + if (const auto *ND = dyn_cast(DeclWithIssue)) + declName = ND->getDeclName().getAsString(); + + if (const Stmt *Body = DeclWithIssue->getBody()) { + // Retrieve the relative position of the declaration which will be used + // for the file name + FullSourceLoc L( + SMgr.getExpansionLoc(path.back()->getLocation().asLocation()), SMgr); + FullSourceLoc FunL(SMgr.getExpansionLoc(Body->getBeginLoc()), SMgr); + offsetDecl = L.getExpansionLineNumber() - FunL.getExpansionLineNumber(); + } } SmallString<32> IssueHash = getIssueHash(D, PP); @@ -377,8 +375,10 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, os << report; } -std::string HTMLDiagnostics::GenerateHTML(const PathDiagnostic& D, Rewriter &R, - const SourceManager& SMgr, const PathPieces& path, const char *declName) { +std::string HTMLDiagnostics::GenerateHTML(const PathDiagnostic &D, Rewriter &R, + const SourceManager &SMgr, + const PathPieces &path, + const char *declName) { // Rewrite source files as HTML for every new file the path crosses std::vector FileIDs; for (auto I : path) { @@ -450,16 +450,14 @@ std::string HTMLDiagnostics::GenerateHTML(const PathDiagnostic& D, Rewriter &R, return file; } -void HTMLDiagnostics::dumpCoverageData( - const PathDiagnostic &D, - const PathPieces &path, - llvm::raw_string_ostream &os) { +void HTMLDiagnostics::dumpCoverageData(const PathDiagnostic &D, + const PathPieces &path, + llvm::raw_string_ostream &os) { const FilesToLineNumsMap &ExecutedLines = D.getExecutedLines(); os << "var relevant_lines = {"; - for (auto I = ExecutedLines.begin(), - E = ExecutedLines.end(); I != E; ++I) { + for (auto I = ExecutedLines.begin(), E = ExecutedLines.end(); I != E; ++I) { if (I != ExecutedLines.begin()) os << ", "; @@ -476,8 +474,9 @@ void HTMLDiagnostics::dumpCoverageData( os << "};"; } -std::string HTMLDiagnostics::showRelevantLinesJavascript( - const PathDiagnostic &D, const PathPieces &path) { +std::string +HTMLDiagnostics::showRelevantLinesJavascript(const PathDiagnostic &D, + const PathPieces &path) { std::string s; llvm::raw_string_ostream os(s); os << "