[clang] [analyzer] Fix assertion failed caused by non standard strnlen function (PR #150222)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 23 06:40:01 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: None (flovent)
<details>
<summary>Changes</summary>
Fix assertion failed and avoid further model non standard `strnlen` like this:
```
char* strnlen(const char*, size_t);
```
Fixes #<!-- -->149757.
---
Full diff: https://github.com/llvm/llvm-project/pull/150222.diff
2 Files Affected:
- (modified) clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (+13-7)
- (added) clang/test/Analysis/cstring-no-standard-function.c (+14)
``````````diff
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
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/150222
More information about the cfe-commits
mailing list