Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h @@ -49,6 +49,8 @@ return !T.isNull() && !T->isVoidType(); } + mutable unsigned Complexity = 0; + public: virtual ~SymExpr() = default; @@ -85,7 +87,7 @@ symbol_iterator symbol_begin() const { return symbol_iterator(this); } static symbol_iterator symbol_end() { return symbol_iterator(); } - unsigned computeComplexity() const; + virtual unsigned computeComplexity() const = 0; /// Find the region from which this symbol originates. /// @@ -127,6 +129,10 @@ SymbolID getSymbolID() const { return Sym; } + unsigned computeComplexity() const override { + return 1; + }; + // Implement isa support. static inline bool classof(const SymExpr *SE) { Kind k = SE->getKind(); Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -270,6 +270,12 @@ // Otherwise, 'To' should also be a valid type. } + unsigned computeComplexity() const override { + if (Complexity == 0) + Complexity = 1 + Operand->computeComplexity(); + return Complexity; + } + QualType getType() const override { return ToTy; } const SymExpr *getOperand() const { return Operand; } @@ -337,6 +343,12 @@ const SymExpr *getLHS() const { return LHS; } const llvm::APSInt &getRHS() const { return RHS; } + unsigned computeComplexity() const override { + if (Complexity == 0) + Complexity = 1 + LHS->computeComplexity(); + return Complexity; + } + static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt& rhs, QualType t) { @@ -374,6 +386,12 @@ const SymExpr *getRHS() const { return RHS; } const llvm::APSInt &getLHS() const { return LHS; } + unsigned computeComplexity() const override { + if (Complexity == 0) + Complexity = 1 + RHS->computeComplexity(); + return Complexity; + } + static void Profile(llvm::FoldingSetNodeID& ID, const llvm::APSInt& lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) { @@ -412,6 +430,12 @@ void dumpToStream(raw_ostream &os) const override; + unsigned computeComplexity() const override { + if (Complexity == 0) + Complexity = RHS->computeComplexity() + LHS->computeComplexity(); + return Complexity; + } + static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) { ID.AddInteger((unsigned) SymSymExprKind); Index: lib/StaticAnalyzer/Core/AnalyzerOptions.cpp =================================================================== --- lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -390,7 +390,7 @@ unsigned AnalyzerOptions::getMaxSymbolComplexity() { if (!MaxSymbolComplexity.hasValue()) - MaxSymbolComplexity = getOptionAsInteger("max-symbol-complexity", 25); + MaxSymbolComplexity = getOptionAsInteger("max-symbol-complexity", 35); return MaxSymbolComplexity.getValue(); } Index: lib/StaticAnalyzer/Core/SymbolManager.cpp =================================================================== --- lib/StaticAnalyzer/Core/SymbolManager.cpp +++ lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -159,13 +159,6 @@ llvm_unreachable("unhandled expansion case"); } -unsigned SymExpr::computeComplexity() const { - unsigned R = 0; - for (symbol_iterator I = symbol_begin(), E = symbol_end(); I != E; ++I) - R++; - return R; -} - const SymbolRegionValue* SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) { llvm::FoldingSetNodeID profile;