[clang] [analyzer] Fix zext assertion failure in loop unrolling (PR #121203)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 27 03:02:29 PST 2024
https://github.com/shenjunjiekoda created https://github.com/llvm/llvm-project/pull/121203
The current implementation of APInt extension in the code can trigger an assertion failure when the `zext` function is called with a target width smaller than the current bit width. For example:
```cpp
if (InitNum.getBitWidth() != BoundNum.getBitWidth()) {
InitNum = InitNum.zext(BoundNum.getBitWidth());
BoundNum = BoundNum.zext(InitNum.getBitWidth());
}
```
This logic does not guarantee that the `zext` target width is always greater than or equal to the current bit width, leading to potential crashes.
Expected Behavior:
- Ensure InitNum and BoundNum are extended to the maximum of their respective widths.
- Prevent assertion failures by enforcing correct `zext` usage.
Depend on ##121201
>From 3bcf5c8f05df2f62a9ef13537b813e7df2871d1b Mon Sep 17 00:00:00 2001
From: shenjunjie <shenjunjiekoda at foxmail.com>
Date: Fri, 27 Dec 2024 11:00:27 +0000
Subject: [PATCH] [analyzer] Fix zext assertion failure in loop unrolling
---
clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp b/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
index 96f5d7c44baf89..e3b27e22712b58 100644
--- a/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
+++ b/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
@@ -283,10 +283,12 @@ static bool shouldCompletelyUnroll(const Stmt *LoopStmt, ASTContext &ASTCtx,
llvm::APInt InitNum =
Matches[0].getNodeAs<IntegerLiteral>("initNum")->getValue();
auto CondOp = Matches[0].getNodeAs<BinaryOperator>("conditionOperator");
- if (InitNum.getBitWidth() != BoundNum.getBitWidth()) {
- InitNum = InitNum.zext(BoundNum.getBitWidth());
- BoundNum = BoundNum.zext(InitNum.getBitWidth());
- }
+ unsigned MaxWidth = std::max(InitNum.getBitWidth(), BoundNum.getBitWidth());
+
+ if (InitNum.getBitWidth() != MaxWidth)
+ InitNum = InitNum.zext(MaxWidth);
+ if (BoundNum.getBitWidth() != MaxWidth)
+ BoundNum = BoundNum.zext(MaxWidth);
if (CondOp->getOpcode() == BO_GE || CondOp->getOpcode() == BO_LE)
maxStep = (BoundNum - InitNum + 1).abs().getZExtValue();
More information about the cfe-commits
mailing list