https://github.com/luamfb updated https://github.com/llvm/llvm-project/pull/68368
>From 1f0249fdb0cf7b1799eb9e532bfbb4a3ffe983b0 Mon Sep 17 00:00:00 2001 From: luamfb <mcmfbarb...@gmail.com> Date: Thu, 5 Oct 2023 21:50:10 -0300 Subject: [PATCH 1/2] [analyzer] Compute length of string literal initializers (#66990) --- .../StaticAnalyzer/Checkers/CStringChecker.cpp | 17 ++++++++++++++++- clang/test/Analysis/string.c | 11 +++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index f1539f2733298d9..b3b15c35450acdc 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -930,9 +930,24 @@ 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->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); + } + } + } + // Otherwise, fallback to this. + return getCStringLengthForRegion(C, state, Ex, MR, hypothetical); + } 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..8da905b33145562 100644 --- a/clang/test/Analysis/string.c +++ b/clang/test/Analysis/string.c @@ -97,6 +97,17 @@ 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"; + +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}} +} + size_t strlen_null(void) { return strlen(0); // expected-warning{{Null pointer passed as 1st argument to string length function}} } >From 2c7c045243492648f08e2ec1017ae3d1b8b00136 Mon Sep 17 00:00:00 2001 From: luamfb <mcmfbarb...@gmail.com> Date: Mon, 9 Oct 2023 22:00:14 -0300 Subject: [PATCH 2/2] fixup! [analyzer] Compute length of string literal initializers (#66990) --- .../StaticAnalyzer/Checkers/CStringChecker.cpp | 17 ++++++++--------- clang/test/Analysis/string.c | 7 +++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index b3b15c35450acdc..b1bc98e93a27995 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -933,18 +933,17 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state, 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->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); + 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); } } } - // Otherwise, fallback to this. - return getCStringLengthForRegion(C, state, Ex, MR, hypothetical); + [[fallthrough]]; } case MemRegion::SymbolicRegionKind: case MemRegion::AllocaRegionKind: diff --git a/clang/test/Analysis/string.c b/clang/test/Analysis/string.c index 8da905b33145562..c226b6221e3cf59 100644 --- a/clang/test/Analysis/string.c +++ b/clang/test/Analysis/string.c @@ -99,6 +99,8 @@ void strlen_constant2(char x) { 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"; void strlen_global_constant_ptr(void) { clang_analyzer_eval(strlen(global_str_ptr) == 4); // expected-warning{{TRUE}} @@ -108,6 +110,11 @@ 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}} +} + size_t strlen_null(void) { return strlen(0); // expected-warning{{Null pointer passed as 1st argument to string length function}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits