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