https://github.com/flovent created 
https://github.com/llvm/llvm-project/pull/150222

Fix assertion failed and avoid further model non standard `strnlen`  like this:

```
char* strnlen(const char*, size_t)
```

Fixes #149757.


>From cec3aa7177075962f1980fa8787debc79afe7fe9 Mon Sep 17 00:00:00 2001
From: flovent <flb...@protonmail.com>
Date: Wed, 23 Jul 2025 21:29:55 +0800
Subject: [PATCH] [analyzer] Fix assertion failed caused by non standard
 strnlen function

---
 .../Checkers/CStringChecker.cpp               | 20 ++++++++++++-------
 .../Analysis/cstring-no-standard-function.c   | 14 +++++++++++++
 2 files changed, 27 insertions(+), 7 deletions(-)
 create mode 100644 clang/test/Analysis/cstring-no-standard-function.c

diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 31cb150892a5d..738640029cfb0 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -1767,18 +1767,24 @@ void CStringChecker::evalstrLengthCommon(CheckerContext 
&C,
       // All we know is the return value is the min of the string length
       // and the limit. This is better than nothing.
       result = C.getSValBuilder().conjureSymbolVal(Call, C.blockCount());
-      NonLoc resultNL = result.castAs<NonLoc>();
+      std::optional<NonLoc> resultNL = result.getAs<NonLoc>();
+      if (!resultNL)
+        return;
 
       if (strLengthNL) {
-        state = state->assume(C.getSValBuilder().evalBinOpNN(
-                                  state, BO_LE, resultNL, *strLengthNL, cmpTy)
-                                  .castAs<DefinedOrUnknownSVal>(), true);
+        state = state->assume(
+            C.getSValBuilder()
+                .evalBinOpNN(state, BO_LE, *resultNL, *strLengthNL, cmpTy)
+                .castAs<DefinedOrUnknownSVal>(),
+            true);
       }
 
       if (maxlenValNL) {
-        state = state->assume(C.getSValBuilder().evalBinOpNN(
-                                  state, BO_LE, resultNL, *maxlenValNL, cmpTy)
-                                  .castAs<DefinedOrUnknownSVal>(), true);
+        state = state->assume(
+            C.getSValBuilder()
+                .evalBinOpNN(state, BO_LE, *resultNL, *maxlenValNL, cmpTy)
+                .castAs<DefinedOrUnknownSVal>(),
+            true);
       }
     }
 
diff --git a/clang/test/Analysis/cstring-no-standard-function.c 
b/clang/test/Analysis/cstring-no-standard-function.c
new file mode 100644
index 0000000000000..0ddb2c7696726
--- /dev/null
+++ b/clang/test/Analysis/cstring-no-standard-function.c
@@ -0,0 +1,14 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring -verify %s
+
+// expected-no-diagnostics
+
+typedef __SIZE_TYPE__ size_t;
+
+extern char* strnlen(const char*, size_t);
+char** q;
+
+void f(const char *s)
+{
+  extern char a[8];
+  q[0] = strnlen(a, 7); // no crash
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to