[analyzer] LoopUnrolling: check the bitwidth of the used numbers (pr34943)
authorPeter Szecsi <szepet95@gmail.com>
Sat, 28 Oct 2017 12:19:08 +0000 (12:19 +0000)
committerPeter Szecsi <szepet95@gmail.com>
Sat, 28 Oct 2017 12:19:08 +0000 (12:19 +0000)
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

llvm-svn: 316830

clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
clang/test/Analysis/loop-unrolling.cpp

index 98b6ebd3670f967d30efd69070581d88161bb5d3..a8c4b05cea131843272474cc4098b617a8c56b5d 100644 (file)
@@ -208,9 +208,16 @@ bool shouldCompletelyUnroll(const Stmt *LoopStmt, ASTContext &ASTCtx,
     return false;
 
   auto CounterVar = Matches[0].getNodeAs<VarDecl>("initVarName");
-  auto BoundNum = Matches[0].getNodeAs<IntegerLiteral>("boundNum")->getValue();
-  auto InitNum = Matches[0].getNodeAs<IntegerLiteral>("initNum")->getValue();
+  llvm::APInt BoundNum =
+      Matches[0].getNodeAs<IntegerLiteral>("boundNum")->getValue();
+  llvm::APInt InitNum =
+      Matches[0].getNodeAs<IntegerLiteral>("initNum")->getValue();
   auto CondOp = Matches[0].getNodeAs<BinaryOperator>("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
index 8ea5b82aadb59f3bef7784aece365c945195c251..844d1f18ea578b4c6e34da2f18e543f3cc56350c 100644 (file)
@@ -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}}
+  }
+}