From 5d548d284e653240a44965a6b3ce891de8435341 Mon Sep 17 00:00:00 2001 From: Peter Szecsi Date: Sat, 28 Oct 2017 12:19:08 +0000 Subject: [PATCH] [analyzer] LoopUnrolling: check the bitwidth of the used numbers (pr34943) The loop unrolling feature aims to track the maximum possible steps a loop can make. In order to implement this, it investigates the initial value of the counter variable and the bound number. (It has to be known.) These numbers are used as llvm::APInts, however, it was not checked if their bitwidths are the same which lead to some crashes. This revision solves this problem by extending the "shorter" one (to the length of the "longer" one). For the detailed bug report, see: https://bugs.llvm.org/show_bug.cgi?id=34943 Differential Revision: https://reviews.llvm.org/D38922 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316830 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/LoopUnrolling.cpp | 11 +++++++++-- test/Analysis/loop-unrolling.cpp | 6 ++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/StaticAnalyzer/Core/LoopUnrolling.cpp b/lib/StaticAnalyzer/Core/LoopUnrolling.cpp index 98b6ebd367..a8c4b05cea 100644 --- a/lib/StaticAnalyzer/Core/LoopUnrolling.cpp +++ b/lib/StaticAnalyzer/Core/LoopUnrolling.cpp @@ -208,9 +208,16 @@ bool shouldCompletelyUnroll(const Stmt *LoopStmt, ASTContext &ASTCtx, return false; auto CounterVar = Matches[0].getNodeAs("initVarName"); - auto BoundNum = Matches[0].getNodeAs("boundNum")->getValue(); - auto InitNum = Matches[0].getNodeAs("initNum")->getValue(); + llvm::APInt BoundNum = + Matches[0].getNodeAs("boundNum")->getValue(); + llvm::APInt InitNum = + Matches[0].getNodeAs("initNum")->getValue(); auto CondOp = Matches[0].getNodeAs("conditionOperator"); + if (InitNum.getBitWidth() != BoundNum.getBitWidth()) { + InitNum = InitNum.zextOrSelf(BoundNum.getBitWidth()); + BoundNum = BoundNum.zextOrSelf(InitNum.getBitWidth()); + } + if (CondOp->getOpcode() == BO_GE || CondOp->getOpcode() == BO_LE) maxStep = (BoundNum - InitNum + 1).abs().getZExtValue(); else diff --git a/test/Analysis/loop-unrolling.cpp b/test/Analysis/loop-unrolling.cpp index 8ea5b82aad..844d1f18ea 100644 --- a/test/Analysis/loop-unrolling.cpp +++ b/test/Analysis/loop-unrolling.cpp @@ -373,3 +373,9 @@ int num_steps_over_limit3() { return 0; } + +void pr34943() { + for (int i = 0; i < 6L; ++i) { + clang_analyzer_numTimesReached(); // expected-warning {{6}} + } +} -- 2.40.0