[clang] 4df7496 - [analyzer] Compute length of string literal initializers (#66990) (#68368)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 10 16:08:23 PDT 2023
Author: luamfb
Date: 2023-10-10T16:08:18-07:00
New Revision: 4df74963ea0f6c8650d5837ab52e3cdcf1dcf016
URL: https://github.com/llvm/llvm-project/commit/4df74963ea0f6c8650d5837ab52e3cdcf1dcf016
DIFF: https://github.com/llvm/llvm-project/commit/4df74963ea0f6c8650d5837ab52e3cdcf1dcf016.diff
LOG: [analyzer] Compute length of string literal initializers (#66990) (#68368)
Fix issue https://github.com/llvm/llvm-project/issues/66990
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
clang/test/Analysis/string.c
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index f1539f2733298d9..b1bc98e93a27995 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -930,9 +930,23 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
const StringLiteral *strLit = cast<StringRegion>(MR)->getStringLiteral();
return svalBuilder.makeIntVal(strLit->getLength(), sizeTy);
}
+ case MemRegion::NonParamVarRegionKind: {
+ // If we have a global constant with a string literal initializer,
+ // compute the initializer's length.
+ const VarDecl *Decl = cast<NonParamVarRegion>(MR)->getDecl();
+ if (Decl->getType().isConstQualified() && Decl->hasGlobalStorage()) {
+ if (const Expr *Init = Decl->getInit()) {
+ if (auto *StrLit = dyn_cast<StringLiteral>(Init)) {
+ SValBuilder &SvalBuilder = C.getSValBuilder();
+ QualType SizeTy = SvalBuilder.getContext().getSizeType();
+ return SvalBuilder.makeIntVal(StrLit->getLength(), SizeTy);
+ }
+ }
+ }
+ [[fallthrough]];
+ }
case MemRegion::SymbolicRegionKind:
case MemRegion::AllocaRegionKind:
- case MemRegion::NonParamVarRegionKind:
case MemRegion::ParamVarRegionKind:
case MemRegion::FieldRegionKind:
case MemRegion::ObjCIvarRegionKind:
diff --git a/clang/test/Analysis/string.c b/clang/test/Analysis/string.c
index d369ee9f7d854a1..d47de9db8228e57 100644
--- a/clang/test/Analysis/string.c
+++ b/clang/test/Analysis/string.c
@@ -97,6 +97,29 @@ void strlen_constant2(char x) {
clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}}
}
+const char *const global_str_ptr = "abcd";
+const char global_str_arr[] = "efgh";
+const char *global_non_const_ptr1 = "ijk";
+char *global_non_const_ptr2 = "lmn";
+char global_non_const_arr[] = "op";
+
+void strlen_global_constant_ptr(void) {
+ clang_analyzer_eval(strlen(global_str_ptr) == 4); // expected-warning{{TRUE}}
+}
+
+void strlen_global_constant_arr(void) {
+ clang_analyzer_eval(strlen(global_str_arr) == 4); // expected-warning{{TRUE}}
+}
+
+void strlen_global_non_const_ptr(void) {
+ clang_analyzer_eval(strlen(global_non_const_ptr1) == 3); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(strlen(global_non_const_ptr2) == 3); // expected-warning{{UNKNOWN}}
+}
+
+void strlen_global_non_const_arr(void) {
+ clang_analyzer_eval(strlen(global_non_const_arr) == 2); // expected-warning{{UNKNOWN}}
+}
+
size_t strlen_null(void) {
return strlen(0); // expected-warning{{Null pointer passed as 1st argument to string length function}}
}
More information about the cfe-commits
mailing list