From 6eb9e0f5ebb94cccf52ea27aa342001b84c1c8b1 Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum Date: Tue, 24 May 2022 19:04:54 +0000 Subject: [PATCH] [clang][dataflow] Make limit on fixpoint-algorithm iterations proportional to size of CFG. Currently, the maximum number of iterations of the loop for finding the fixpoint of the dataflow analysis is set at 2^16. When things go wrong in an analysis, this can be far too large. This patch changes the limit to be proportional to the size of the CFG, which will generally be far smaller than 2^16 (while still maintaining 2^16 as the absolute limit). Differential Revision: https://reviews.llvm.org/D126316 --- .../lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index aebc9dd..ee1723d 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include #include #include #include @@ -330,10 +331,17 @@ runTypeErasedDataflowAnalysis(const ControlFlowContext &CFCtx, // converging. To limit the damage (infinite loops) that these bugs can cause, // limit the number of iterations. // FIXME: Consider making the maximum number of iterations configurable. + // FIXME: Consider restricting the number of backedges followed, rather than + // iterations. // FIXME: Set up statistics (see llvm/ADT/Statistic.h) to count average number // of iterations, number of functions that time out, etc. + static constexpr uint32_t MaxAverageVisitsPerBlock = 4; + static constexpr uint32_t AbsoluteMaxIterations = 1 << 16; + const uint32_t RelativeMaxIterations = + MaxAverageVisitsPerBlock * BlockStates.size(); + const uint32_t MaxIterations = + std::min(RelativeMaxIterations, AbsoluteMaxIterations); uint32_t Iterations = 0; - static constexpr uint32_t MaxIterations = 1 << 16; while (const CFGBlock *Block = Worklist.dequeue()) { if (++Iterations > MaxIterations) { return llvm::createStringError(std::errc::timed_out, -- 2.7.4