[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