szepet created this revision.
Herald added subscribers: baloghadamsoftware, whisperity.

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. (There 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


https://reviews.llvm.org/D38922

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


Index: test/Analysis/loop-unrolling.cpp
===================================================================
--- test/Analysis/loop-unrolling.cpp
+++ test/Analysis/loop-unrolling.cpp
@@ -373,3 +373,9 @@
   return 0;
 }
 
+
+void pr34943() {
+  for (int i = 0; i < 6L; ++i) {
+    clang_analyzer_numTimesReached(); // expected-warning {{6}}
+  }
+}
Index: lib/StaticAnalyzer/Core/LoopUnrolling.cpp
===================================================================
--- lib/StaticAnalyzer/Core/LoopUnrolling.cpp
+++ lib/StaticAnalyzer/Core/LoopUnrolling.cpp
@@ -208,9 +208,16 @@
     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: test/Analysis/loop-unrolling.cpp
===================================================================
--- test/Analysis/loop-unrolling.cpp
+++ test/Analysis/loop-unrolling.cpp
@@ -373,3 +373,9 @@
   return 0;
 }
 
+
+void pr34943() {
+  for (int i = 0; i < 6L; ++i) {
+    clang_analyzer_numTimesReached(); // expected-warning {{6}}
+  }
+}
Index: lib/StaticAnalyzer/Core/LoopUnrolling.cpp
===================================================================
--- lib/StaticAnalyzer/Core/LoopUnrolling.cpp
+++ lib/StaticAnalyzer/Core/LoopUnrolling.cpp
@@ -208,9 +208,16 @@
     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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to