https://github.com/NagyDonat updated 
https://github.com/llvm/llvm-project/pull/229119

From bbd87b232ddb55e30e7c3fc7ae993c5482f38e45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 5 Oct 2026 17:19:02 +0200
Subject: [PATCH 1/4] [analyzer] Ignore nonstandard function named 'memset'

Previously CStringChecker ran into an assertion failure when it
encountered a function named 'memset' whose third argument was
a `const int &` instead of the standard `size_t`.

This PR introduces an early return to avoid this.

Fixes #228865

Reported-by: k-arrows
---
 .../StaticAnalyzer/Checkers/CStringChecker.cpp  |  5 +++++
 clang/test/Analysis/PR228865.cpp                | 17 +++++++++++++++++
 2 files changed, 22 insertions(+)
 create mode 100644 clang/test/Analysis/PR228865.cpp

diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 69712d15d50c4..1fce634e3c1c4 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -2938,6 +2938,11 @@ void CStringChecker::evalMemset(CheckerContext &C,
   SVal SizeVal = C.getSVal(Size.Expression);
   QualType SizeTy = Size.Expression->getType();
 
+  // Avoid assertion failure in the corner case when we see a function named
+  // 'memset' with a nonstandard declaration.
+  if (!SizeTy->isUnsignedIntegerType())
+    return;
+
   ProgramStateRef ZeroSize, NonZeroSize;
   std::tie(ZeroSize, NonZeroSize) = assumeZero(C, State, SizeVal, SizeTy);
 
diff --git a/clang/test/Analysis/PR228865.cpp b/clang/test/Analysis/PR228865.cpp
new file mode 100644
index 0000000000000..8951d7d0169b9
--- /dev/null
+++ b/clang/test/Analysis/PR228865.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring -verify %s
+
+// Test that a nonstandard 'memset' does not trigger an assertion failure.
+// Code taken from https://github.com/llvm/llvm-project/issues/228865
+
+// expected-no-diagnostics
+
+struct B {
+} b;
+
+struct A {
+  struct B b;
+} a;
+
+void *memset(void *s, int c, const int &cond);
+
+void foo() { memset(&a.b, 0, sizeof(b)); }

From 09937f58992dbf951efd2ce93d7e50aca5bab7f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 5 Oct 2026 21:32:13 +0200
Subject: [PATCH 2/4] Add comments in the test file

---
 clang/test/Analysis/PR228865.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/clang/test/Analysis/PR228865.cpp b/clang/test/Analysis/PR228865.cpp
index 8951d7d0169b9..648140ec7ea1c 100644
--- a/clang/test/Analysis/PR228865.cpp
+++ b/clang/test/Analysis/PR228865.cpp
@@ -12,6 +12,9 @@ struct A {
   struct B b;
 } a;
 
+// Not the standard 'memset' -- there third parameter would be a 'size_t'.
 void *memset(void *s, int c, const int &cond);
 
-void foo() { memset(&a.b, 0, sizeof(b)); }
+void foo() {
+  memset(&a.b, 0, sizeof(b)); // no-crash
+}

From d5de72ed1b0f21b43d13807465bd8b9700b2631b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 5 Oct 2026 21:34:00 +0200
Subject: [PATCH 3/4] Fix typo

---
 clang/test/Analysis/PR228865.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/Analysis/PR228865.cpp b/clang/test/Analysis/PR228865.cpp
index 648140ec7ea1c..80569e7cfa106 100644
--- a/clang/test/Analysis/PR228865.cpp
+++ b/clang/test/Analysis/PR228865.cpp
@@ -12,7 +12,7 @@ struct A {
   struct B b;
 } a;
 
-// Not the standard 'memset' -- there third parameter would be a 'size_t'.
+// Not the standard 'memset' -- there the third parameter would be a 'size_t'.
 void *memset(void *s, int c, const int &cond);
 
 void foo() {

From 535eff24f7393be2e5546928f8e3905abab7a4cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= <[email protected]>
Date: Mon, 5 Oct 2026 22:47:16 +0200
Subject: [PATCH 4/4] Properly rule out reference types

---
 clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 2 +-
 clang/test/Analysis/PR228865.cpp                     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 1fce634e3c1c4..3749c262e8bba 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -2940,7 +2940,7 @@ void CStringChecker::evalMemset(CheckerContext &C,
 
   // Avoid assertion failure in the corner case when we see a function named
   // 'memset' with a nonstandard declaration.
-  if (!SizeTy->isUnsignedIntegerType())
+  if (!SizeTy->isUnsignedIntegerType() || !Size.Expression->isPRValue())
     return;
 
   ProgramStateRef ZeroSize, NonZeroSize;
diff --git a/clang/test/Analysis/PR228865.cpp b/clang/test/Analysis/PR228865.cpp
index 80569e7cfa106..74c8e4a73da77 100644
--- a/clang/test/Analysis/PR228865.cpp
+++ b/clang/test/Analysis/PR228865.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring -verify %s
 
 // Test that a nonstandard 'memset' does not trigger an assertion failure.
-// Code taken from https://github.com/llvm/llvm-project/issues/228865
+// Code adapted from https://github.com/llvm/llvm-project/issues/228865
 
 // expected-no-diagnostics
 
@@ -13,7 +13,7 @@ struct A {
 } a;
 
 // Not the standard 'memset' -- there the third parameter would be a 'size_t'.
-void *memset(void *s, int c, const int &cond);
+void *memset(void *s, int c, const unsigned &cond);
 
 void foo() {
   memset(&a.b, 0, sizeof(b)); // no-crash

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to