[clang] [analyzer] Fix zext assertion failure in loop unrolling (PR #121203)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 27 07:21:45 PST 2024
https://github.com/shenjunjiekoda updated https://github.com/llvm/llvm-project/pull/121203
>From 2cee5fc2abd0cf2979c9ba975906e659adcd4463 Mon Sep 17 00:00:00 2001
From: shenjunjie <shenjunjiekoda at foxmail.com>
Date: Fri, 27 Dec 2024 14:08:55 +0000
Subject: [PATCH 1/6] [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..9227a7876c0b2f 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();
>From a4d3a24ea797c5f53c5171e05f7172434096bd65 Mon Sep 17 00:00:00 2001
From: shenjunjie <shenjunjiekoda at foxmail.com>
Date: Fri, 27 Dec 2024 14:20:23 +0000
Subject: [PATCH 2/6] add testcase
---
clang/test/Analysis/PR121201.cpp | 50 ++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 clang/test/Analysis/PR121201.cpp
diff --git a/clang/test/Analysis/PR121201.cpp b/clang/test/Analysis/PR121201.cpp
new file mode 100644
index 00000000000000..a2cea89dc10b79
--- /dev/null
+++ b/clang/test/Analysis/PR121201.cpp
@@ -0,0 +1,50 @@
+
+template < bool, typename T, typename > using conditional_t = T;
+class basic_format_arg;
+template < typename > struct formatter;
+template < typename Context > struct value {
+ template < typename T > value(T) {
+ using value_type = T;
+ format_custom_arg<
+ value_type, typename Context::template formatter_type< value_type > >;
+ }
+ template < typename, typename Formatter > static void format_custom_arg() {
+ Context ctx;
+ auto f = Formatter();
+ f.format(0, ctx);
+ }
+};
+struct context {
+ template < typename T > using formatter_type = formatter< T >;
+};
+enum { max_packed_args };
+template < typename Context, long >
+using arg_t =
+ conditional_t< max_packed_args, value< Context >, basic_format_arg >;
+template < int NUM_ARGS > struct format_arg_store {
+ arg_t< context, NUM_ARGS > args;
+};
+template < typename... T, long NUM_ARGS = sizeof...(T) >
+auto make_format_args(T... args) -> format_arg_store< NUM_ARGS > {
+ return {args...};
+}
+template < typename F > void write_padded(F write) { write(0); }
+template < typename... T > void format(T... args) { make_format_args(args...); }
+template < int > struct bitset {
+ bitset(long);
+};
+template < long N > struct formatter< bitset< N > > {
+ struct writer {
+ bitset< N > bs;
+ template < typename OutputIt > void operator()(OutputIt) {
+ for (auto pos = N; pos > 0; --pos)
+ ;
+ }
+ };
+ template < typename FormatContext >
+ void format(bitset< N > bs, FormatContext) {
+ write_padded(writer{bs});
+ }
+};
+bitset< 6 > TestBody_bs(2);
+void TestBody() { format(TestBody_bs); }
\ No newline at end of file
>From ee331f6f1e257c7636913616c4f223de49d10641 Mon Sep 17 00:00:00 2001
From: shenjunjie <shenjunjiekoda at foxmail.com>
Date: Fri, 27 Dec 2024 14:35:12 +0000
Subject: [PATCH 3/6] fix testcase
---
clang/test/Analysis/PR121201.cpp | 67 ++++++++++++++++++++------------
1 file changed, 42 insertions(+), 25 deletions(-)
diff --git a/clang/test/Analysis/PR121201.cpp b/clang/test/Analysis/PR121201.cpp
index a2cea89dc10b79..49ce92957ad8a8 100644
--- a/clang/test/Analysis/PR121201.cpp
+++ b/clang/test/Analysis/PR121201.cpp
@@ -1,50 +1,67 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config
+// unroll-loops=true -verify %s
-template < bool, typename T, typename > using conditional_t = T;
+// expected-no-diagnostics
+
+template <bool, typename T, typename> using conditional_t = T;
class basic_format_arg;
-template < typename > struct formatter;
-template < typename Context > struct value {
- template < typename T > value(T) {
+template <typename> struct formatter;
+
+template <typename Context> struct value {
+ template <typename T> value(T) {
using value_type = T;
- format_custom_arg<
- value_type, typename Context::template formatter_type< value_type > >;
+ format_custom_arg<value_type,
+ typename Context::template formatter_type<value_type>>;
}
- template < typename, typename Formatter > static void format_custom_arg() {
+
+ template <typename, typename Formatter> static void format_custom_arg() {
Context ctx;
auto f = Formatter();
f.format(0, ctx);
}
};
+
struct context {
- template < typename T > using formatter_type = formatter< T >;
+ template <typename T> using formatter_type = formatter<T>;
};
+
enum { max_packed_args };
-template < typename Context, long >
-using arg_t =
- conditional_t< max_packed_args, value< Context >, basic_format_arg >;
-template < int NUM_ARGS > struct format_arg_store {
- arg_t< context, NUM_ARGS > args;
+
+template <typename Context, long>
+using arg_t = conditional_t<max_packed_args, value<Context>, basic_format_arg>;
+
+template <int NUM_ARGS> struct format_arg_store {
+ arg_t<context, NUM_ARGS> args;
};
-template < typename... T, long NUM_ARGS = sizeof...(T) >
-auto make_format_args(T... args) -> format_arg_store< NUM_ARGS > {
+
+template <typename... T, long NUM_ARGS = sizeof...(T)>
+auto make_format_args(T... args) -> format_arg_store<NUM_ARGS> {
return {args...};
}
-template < typename F > void write_padded(F write) { write(0); }
-template < typename... T > void format(T... args) { make_format_args(args...); }
-template < int > struct bitset {
+
+template <typename F> void write_padded(F write) { write(0); }
+
+template <typename... T> void format(T... args) { make_format_args(args...); }
+
+template <int> struct bitset {
bitset(long);
};
-template < long N > struct formatter< bitset< N > > {
+
+template <long N> struct formatter<bitset<N>> {
struct writer {
- bitset< N > bs;
- template < typename OutputIt > void operator()(OutputIt) {
+ bitset<N> bs;
+
+ template <typename OutputIt> void operator()(OutputIt) {
for (auto pos = N; pos > 0; --pos)
;
}
};
- template < typename FormatContext >
- void format(bitset< N > bs, FormatContext) {
+
+ template <typename FormatContext> void format(bitset<N> bs, FormatContext) {
write_padded(writer{bs});
}
};
-bitset< 6 > TestBody_bs(2);
-void TestBody() { format(TestBody_bs); }
\ No newline at end of file
+
+bitset<6> TestBody_bs(2);
+
+void TestBody() { format(TestBody_bs); }
>From 1e7f333823aa88e5ddba4db0a0f1426201db8e46 Mon Sep 17 00:00:00 2001
From: shenjunjie <shenjunjiekoda at foxmail.com>
Date: Fri, 27 Dec 2024 14:39:27 +0000
Subject: [PATCH 4/6] fix testcase
---
clang/test/Analysis/PR121201.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/Analysis/PR121201.cpp b/clang/test/Analysis/PR121201.cpp
index 49ce92957ad8a8..7332b7237206a8 100644
--- a/clang/test/Analysis/PR121201.cpp
+++ b/clang/test/Analysis/PR121201.cpp
@@ -52,7 +52,7 @@ template <long N> struct formatter<bitset<N>> {
bitset<N> bs;
template <typename OutputIt> void operator()(OutputIt) {
- for (auto pos = N; pos > 0; --pos)
+ for (auto pos = N; pos > 0; --pos) // no-crash
;
}
};
>From d8cc2b9fc8eeaa8ad2ac6a32d7d43e3a9f75e35a Mon Sep 17 00:00:00 2001
From: shenjunjie <shenjunjiekoda at foxmail.com>
Date: Fri, 27 Dec 2024 14:53:24 +0000
Subject: [PATCH 5/6] fix testcase
---
clang/test/Analysis/PR121201.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/test/Analysis/PR121201.cpp b/clang/test/Analysis/PR121201.cpp
index 7332b7237206a8..58facc50ba1a3c 100644
--- a/clang/test/Analysis/PR121201.cpp
+++ b/clang/test/Analysis/PR121201.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config
-// unroll-loops=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s \
+// RUN: -analyzer-config unroll-loops=true
// expected-no-diagnostics
@@ -52,8 +52,8 @@ template <long N> struct formatter<bitset<N>> {
bitset<N> bs;
template <typename OutputIt> void operator()(OutputIt) {
- for (auto pos = N; pos > 0; --pos) // no-crash
- ;
+ for (auto pos = N; pos > 0; --pos)
+ ; // no-crash
}
};
>From 9ae83de2af1a351e89418a31bac2ba14fe8b0060 Mon Sep 17 00:00:00 2001
From: shenjunjie <shenjunjiekoda at foxmail.com>
Date: Fri, 27 Dec 2024 15:20:16 +0000
Subject: [PATCH 6/6] fix testcase
---
clang/test/Analysis/PR121201.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/test/Analysis/PR121201.cpp b/clang/test/Analysis/PR121201.cpp
index 58facc50ba1a3c..acd2492d011fad 100644
--- a/clang/test/Analysis/PR121201.cpp
+++ b/clang/test/Analysis/PR121201.cpp
@@ -10,7 +10,7 @@ template <typename> struct formatter;
template <typename Context> struct value {
template <typename T> value(T) {
using value_type = T;
- format_custom_arg<value_type,
+ (void)format_custom_arg<value_type,
typename Context::template formatter_type<value_type>>;
}
@@ -52,8 +52,8 @@ template <long N> struct formatter<bitset<N>> {
bitset<N> bs;
template <typename OutputIt> void operator()(OutputIt) {
- for (auto pos = N; pos > 0; --pos)
- ; // no-crash
+ for (auto pos = N; pos > 0; --pos) // no-crash
+ ;
}
};
More information about the cfe-commits
mailing list