[clang] [analyzer] Fix crash when modelling 'getline' function in checkers (PR #145229)

Baranov Victor via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 24 11:06:33 PDT 2025


https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/145229

>From ba9f1edfc2ea1fb1e41366721ccbf795ec998707 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Mon, 23 Jun 2025 23:55:57 +0300
Subject: [PATCH 1/6] [clang][analyzer] fix crash when modelling 'getline'
 function in checkers

---
 clang/docs/ReleaseNotes.rst                   |   3 +
 .../StaticAnalyzer/Checkers/MallocChecker.cpp |  13 +-
 .../Checkers/UnixAPIChecker.cpp               |  39 ++++--
 .../getline-unixapi-invalid-signatures.c      | 127 ++++++++++++++++++
 4 files changed, 169 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/Analysis/getline-unixapi-invalid-signatures.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 12816eed2e8b5..b6f6dce29a87b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1060,6 +1060,9 @@ impact the linker behaviour like the other `-static-*` flags.
 Crash and bug fixes
 ^^^^^^^^^^^^^^^^^^^
 
+- Fixed a crash in ``UnixAPIMisuseChecker`` and ``MallocChecker`` when analyzing
+  code with non-standard ``getline`` or ``getdelim`` function signatures.
+
 Improvements
 ^^^^^^^^^^^^
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 35e98a5e2719a..cf9837a378430 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1518,10 +1518,15 @@ void MallocChecker::checkGetdelim(ProgramStateRef State, const CallEvent &Call,
   if (!CE)
     return;
 
-  const auto LinePtr =
-      getPointeeVal(Call.getArgSVal(0), State)->getAs<DefinedSVal>();
-  const auto Size =
-      getPointeeVal(Call.getArgSVal(1), State)->getAs<DefinedSVal>();
+  auto LinePtrOpt = getPointeeVal(Call.getArgSVal(0), State);
+  if (!LinePtrOpt)
+    return;
+  const auto LinePtr = LinePtrOpt->getAs<DefinedSVal>();
+
+  auto SizeOpt = getPointeeVal(Call.getArgSVal(1), State);
+  if (!SizeOpt)
+    return;
+  const auto Size = SizeOpt->getAs<DefinedSVal>();
   if (!LinePtr || !Size || !LinePtr->getAsRegion())
     return;
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index 79d10d99e11d0..77bc9e92e3520 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -332,13 +332,21 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect(
 
   // We have a pointer to a pointer to the buffer, and a pointer to the size.
   // We want what they point at.
-  auto LinePtrSVal = getPointeeVal(LinePtrPtrSVal, State)->getAs<DefinedSVal>();
+  auto LinePtrValOpt = getPointeeVal(LinePtrPtrSVal, State);
+  if (!LinePtrValOpt)
+    return nullptr;
+
+  auto LinePtrSVal = LinePtrValOpt->getAs<DefinedSVal>();
   auto NSVal = getPointeeVal(SizePtrSVal, State);
   if (!LinePtrSVal || !NSVal || NSVal->isUnknown())
     return nullptr;
 
   assert(LinePtrPtrExpr && SizePtrExpr);
 
+  // Add defensive check to ensure we can handle the assume operation
+  if (!LinePtrSVal->getAs<DefinedSVal>())
+    return nullptr;
+
   const auto [LinePtrNotNull, LinePtrNull] = State->assume(*LinePtrSVal);
   if (LinePtrNotNull && !LinePtrNull) {
     // If `*lineptr` is not null, but `*n` is undefined, there is UB.
@@ -350,9 +358,16 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect(
     // If it is defined, and known, its size must be less than or equal to
     // the buffer size.
     auto NDefSVal = NSVal->getAs<DefinedSVal>();
+    if (!NDefSVal)
+      return LinePtrNotNull;
+
     auto &SVB = C.getSValBuilder();
-    auto LineBufSize =
-        getDynamicExtent(LinePtrNotNull, LinePtrSVal->getAsRegion(), SVB);
+
+    const MemRegion *LinePtrRegion = LinePtrSVal->getAsRegion();
+    if (!LinePtrRegion)
+      return LinePtrNotNull;
+
+    auto LineBufSize = getDynamicExtent(LinePtrNotNull, LinePtrRegion, SVB);
     auto LineBufSizeGtN = SVB.evalBinOp(LinePtrNotNull, BO_GE, LineBufSize,
                                         *NDefSVal, SVB.getConditionType())
                               .getAs<DefinedOrUnknownSVal>();
@@ -370,23 +385,29 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect(
 void UnixAPIMisuseChecker::CheckGetDelim(CheckerContext &C,
                                          const CallEvent &Call) const {
   ProgramStateRef State = C.getState();
+  if (Call.getNumArgs() < 2)
+    return;
+
+  const Expr *Arg0 = Call.getArgExpr(0);
+  const Expr *Arg1 = Call.getArgExpr(1);
+
+  if (!Arg0->getType()->isPointerType() || !Arg1->getType()->isPointerType())
+    return;
 
   // The parameter `n` must not be NULL.
   SVal SizePtrSval = Call.getArgSVal(1);
-  State = EnsurePtrNotNull(SizePtrSval, Call.getArgExpr(1), C, State, "Size");
+  State = EnsurePtrNotNull(SizePtrSval, Arg1, C, State, "Size");
   if (!State)
     return;
 
   // The parameter `lineptr` must not be NULL.
   SVal LinePtrPtrSVal = Call.getArgSVal(0);
-  State =
-      EnsurePtrNotNull(LinePtrPtrSVal, Call.getArgExpr(0), C, State, "Line");
+  State = EnsurePtrNotNull(LinePtrPtrSVal, Arg0, C, State, "Line");
   if (!State)
     return;
 
-  State = EnsureGetdelimBufferAndSizeCorrect(LinePtrPtrSVal, SizePtrSval,
-                                             Call.getArgExpr(0),
-                                             Call.getArgExpr(1), C, State);
+  State = EnsureGetdelimBufferAndSizeCorrect(LinePtrPtrSVal, SizePtrSval, Arg0,
+                                             Arg1, C, State);
   if (!State)
     return;
 
diff --git a/clang/test/Analysis/getline-unixapi-invalid-signatures.c b/clang/test/Analysis/getline-unixapi-invalid-signatures.c
new file mode 100644
index 0000000000000..c906625b47634
--- /dev/null
+++ b/clang/test/Analysis/getline-unixapi-invalid-signatures.c
@@ -0,0 +1,127 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s -DTEST_CORRECT
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s -DTEST_GETLINE_1
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s -DTEST_GETLINE_2
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s -DTEST_GETLINE_3
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s -DTEST_GETLINE_4
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s -DTEST_GETLINE_5
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s -DTEST_GETLINE_GH144884
+
+// emulator of "system-header-simulator.h" because of redefinition of 'getline' function
+typedef struct _FILE FILE;
+typedef __typeof(sizeof(int)) size_t;
+typedef long ssize_t;
+#define NULL 0
+
+int fclose(FILE *fp);
+FILE *tmpfile(void);
+
+#ifdef TEST_CORRECT
+ssize_t getline(char **lineptr, size_t *n, FILE *stream);
+ssize_t getdelim(char **lineptr, size_t *n, int delimiter, FILE *stream);
+
+void test_correct() {
+  FILE *F1 = tmpfile();
+  if (!F1)
+    return;
+  char *buffer = NULL;
+  getline(&buffer, NULL, F1); // expected-warning {{Size pointer might be NULL}}
+  fclose(F1);
+}
+
+void test_delim_correct() {
+  FILE *F1 = tmpfile();
+  if (!F1)
+    return;
+  char *buffer = NULL;
+  getdelim(&buffer, NULL, ',', F1); // expected-warning {{Size pointer might be NULL}}
+  fclose(F1);
+}
+#endif
+
+#ifdef TEST_GETLINE_1
+// expected-no-diagnostics
+ssize_t getline(int lineptr);
+
+void test() {
+  FILE *F1 = tmpfile();
+  if (!F1)
+    return;
+  int buffer = 0;
+  getline(buffer);
+  fclose(F1);
+}
+#endif
+
+#ifdef TEST_GETLINE_2
+ssize_t getline(char **lineptr, size_t *n);
+
+void test() {
+  FILE *F1 = tmpfile();
+  if (!F1)
+    return;
+  char *buffer = NULL;
+  getline(&buffer, NULL); // expected-warning {{Size pointer might be NULL}}
+  fclose(F1);
+}
+#endif
+
+#ifdef TEST_GETLINE_3
+// expected-no-diagnostics
+ssize_t getline(char **lineptr, size_t n, FILE *stream);
+
+void test() {
+  FILE *F1 = tmpfile();
+  if (!F1)
+    return;
+  char *buffer = NULL;
+  getline(&buffer, 0, F1);
+  fclose(F1);
+}
+#endif
+
+#ifdef TEST_GETLINE_4
+ssize_t getline(char **lineptr, size_t *n, int stream);
+ssize_t getdelim(char **lineptr, size_t *n, int delimiter, int stream);
+
+void test() {
+  FILE *F1 = tmpfile();
+  if (!F1)
+    return;
+  char *buffer = NULL;
+  getline(&buffer, NULL, 1); // expected-warning {{Size pointer might be NULL}}
+  fclose(F1);
+}
+
+void test_delim() {
+  FILE *F1 = tmpfile();
+  if (!F1)
+    return;
+  char *buffer = NULL;
+  getdelim(&buffer, NULL, ',', 1); // expected-warning {{Size pointer might be NULL}}
+  fclose(F1);
+}
+#endif
+
+#ifdef TEST_GETLINE_5
+ssize_t getdelim(char **lineptr, size_t *n, const char* delimiter, FILE *stream);
+
+void test_delim() {
+  FILE *F1 = tmpfile();
+  if (!F1)
+    return;
+  char *buffer = NULL;
+  getdelim(&buffer, NULL, ",", F1); // expected-warning {{Size pointer might be NULL}}
+  fclose(F1);
+}
+#endif
+
+#ifdef TEST_GETLINE_GH144884
+// expected-no-diagnostics
+struct AW_string {};
+void getline(int *, struct AW_string);
+void top() {
+  struct AW_string line;
+  int getline_file_info;
+  getline(&getline_file_info, line);
+}
+#endif

>From f871058da1b656c5f44e8cb0961fd0db54263811 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Tue, 24 Jun 2025 16:32:22 +0300
Subject: [PATCH 2/6] fix pr comments

---
 .../StaticAnalyzer/Checkers/MallocChecker.cpp | 15 ++++++------
 .../Checkers/UnixAPIChecker.cpp               | 23 +++++++------------
 2 files changed, 15 insertions(+), 23 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index cf9837a378430..783c35654fb44 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1518,19 +1518,18 @@ void MallocChecker::checkGetdelim(ProgramStateRef State, const CallEvent &Call,
   if (!CE)
     return;
 
-  auto LinePtrOpt = getPointeeVal(Call.getArgSVal(0), State);
-  if (!LinePtrOpt)
+  const auto LinePtrOpt = getPointeeVal(Call.getArgSVal(0), State);
+  const auto SizeOpt = getPointeeVal(Call.getArgSVal(1), State);
+  if (!LinePtrOpt || !SizeOpt)
     return;
-  const auto LinePtr = LinePtrOpt->getAs<DefinedSVal>();
 
-  auto SizeOpt = getPointeeVal(Call.getArgSVal(1), State);
-  if (!SizeOpt)
-    return;
+  const auto LinePtr = LinePtrOpt->getAs<DefinedSVal>();
   const auto Size = SizeOpt->getAs<DefinedSVal>();
-  if (!LinePtr || !Size || !LinePtr->getAsRegion())
+  const MemRegion *LinePtrReg = LinePtr->getAsRegion();
+  if (!LinePtr || !Size || !LinePtrReg)
     return;
 
-  State = setDynamicExtent(State, LinePtr->getAsRegion(), *Size);
+  State = setDynamicExtent(State, LinePtrReg, *Size);
   C.addTransition(MallocUpdateRefState(C, CE, State,
                                        AllocationFamily(AF_Malloc), *LinePtr));
 }
diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index 77bc9e92e3520..81fff566aac66 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -128,7 +128,7 @@ ProgramStateRef UnixAPIMisuseChecker::EnsurePtrNotNull(
     const StringRef PtrDescr,
     std::optional<std::reference_wrapper<const BugType>> BT) const {
   const auto Ptr = PtrVal.getAs<DefinedSVal>();
-  if (!Ptr)
+  if (!Ptr || !PtrExpr->getType()->isPointerType())
     return State;
 
   const auto [PtrNotNull, PtrNull] = State->assume(*Ptr);
@@ -343,10 +343,6 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect(
 
   assert(LinePtrPtrExpr && SizePtrExpr);
 
-  // Add defensive check to ensure we can handle the assume operation
-  if (!LinePtrSVal->getAs<DefinedSVal>())
-    return nullptr;
-
   const auto [LinePtrNotNull, LinePtrNull] = State->assume(*LinePtrSVal);
   if (LinePtrNotNull && !LinePtrNull) {
     // If `*lineptr` is not null, but `*n` is undefined, there is UB.
@@ -384,30 +380,27 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect(
 
 void UnixAPIMisuseChecker::CheckGetDelim(CheckerContext &C,
                                          const CallEvent &Call) const {
-  ProgramStateRef State = C.getState();
   if (Call.getNumArgs() < 2)
     return;
 
-  const Expr *Arg0 = Call.getArgExpr(0);
-  const Expr *Arg1 = Call.getArgExpr(1);
-
-  if (!Arg0->getType()->isPointerType() || !Arg1->getType()->isPointerType())
-    return;
+  ProgramStateRef State = C.getState();
 
   // The parameter `n` must not be NULL.
   SVal SizePtrSval = Call.getArgSVal(1);
-  State = EnsurePtrNotNull(SizePtrSval, Arg1, C, State, "Size");
+  State = EnsurePtrNotNull(SizePtrSval, Call.getArgExpr(1), C, State, "Size");
   if (!State)
     return;
 
   // The parameter `lineptr` must not be NULL.
   SVal LinePtrPtrSVal = Call.getArgSVal(0);
-  State = EnsurePtrNotNull(LinePtrPtrSVal, Arg0, C, State, "Line");
+  State =
+      EnsurePtrNotNull(LinePtrPtrSVal, Call.getArgExpr(0), C, State, "Line");
   if (!State)
     return;
 
-  State = EnsureGetdelimBufferAndSizeCorrect(LinePtrPtrSVal, SizePtrSval, Arg0,
-                                             Arg1, C, State);
+  State = EnsureGetdelimBufferAndSizeCorrect(LinePtrPtrSVal, SizePtrSval,
+                                             Call.getArgExpr(0),
+                                             Call.getArgExpr(1), C, State);
   if (!State)
     return;
 

>From 4bda0598b0516f5822eb94188bb39aaf3f2863c7 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Tue, 24 Jun 2025 16:43:33 +0300
Subject: [PATCH 3/6] add 'const' where appropriate

---
 clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index 81fff566aac66..b0cd81fe85f18 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -332,12 +332,12 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect(
 
   // We have a pointer to a pointer to the buffer, and a pointer to the size.
   // We want what they point at.
-  auto LinePtrValOpt = getPointeeVal(LinePtrPtrSVal, State);
+  const auto LinePtrValOpt = getPointeeVal(LinePtrPtrSVal, State);
   if (!LinePtrValOpt)
     return nullptr;
 
-  auto LinePtrSVal = LinePtrValOpt->getAs<DefinedSVal>();
-  auto NSVal = getPointeeVal(SizePtrSVal, State);
+  const auto LinePtrSVal = LinePtrValOpt->getAs<DefinedSVal>();
+  const auto NSVal = getPointeeVal(SizePtrSVal, State);
   if (!LinePtrSVal || !NSVal || NSVal->isUnknown())
     return nullptr;
 

>From b55d5170d851dbee25a9bb2f7a5e963e51854a17 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Tue, 24 Jun 2025 18:54:49 +0300
Subject: [PATCH 4/6] fix pr comments from steakhal

---
 clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp  | 5 +++--
 clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp | 8 ++++----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 783c35654fb44..fe0e2df548bcf 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1520,13 +1520,14 @@ void MallocChecker::checkGetdelim(ProgramStateRef State, const CallEvent &Call,
 
   const auto LinePtrOpt = getPointeeVal(Call.getArgSVal(0), State);
   const auto SizeOpt = getPointeeVal(Call.getArgSVal(1), State);
-  if (!LinePtrOpt || !SizeOpt)
+  if (!LinePtrOpt || !SizeOpt || LinePtrOpt->isUnknownOrUndef() ||
+      SizeOpt->isUnknownOrUndef())
     return;
 
   const auto LinePtr = LinePtrOpt->getAs<DefinedSVal>();
   const auto Size = SizeOpt->getAs<DefinedSVal>();
   const MemRegion *LinePtrReg = LinePtr->getAsRegion();
-  if (!LinePtr || !Size || !LinePtrReg)
+  if (!LinePtrReg)
     return;
 
   State = setDynamicExtent(State, LinePtrReg, *Size);
diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index b0cd81fe85f18..ce5887d56b181 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -83,7 +83,7 @@ class UnixAPIMisuseChecker : public Checker<check::PreCall> {
 
   void CheckOpen(CheckerContext &C, const CallEvent &Call) const;
   void CheckOpenAt(CheckerContext &C, const CallEvent &Call) const;
-  void CheckGetDelim(CheckerContext &C, const CallEvent &Call) const;
+  void CheckGetDelimOrGetline(CheckerContext &C, const CallEvent &Call) const;
   void CheckPthreadOnce(CheckerContext &C, const CallEvent &Call) const;
 
   void CheckOpenVariant(CheckerContext &C, const CallEvent &Call,
@@ -177,7 +177,7 @@ void UnixAPIMisuseChecker::checkPreCall(const CallEvent &Call,
     CheckPthreadOnce(C, Call);
 
   else if (is_contained({"getdelim", "getline"}, FName))
-    CheckGetDelim(C, Call);
+    CheckGetDelimOrGetline(C, Call);
 }
 void UnixAPIMisuseChecker::ReportOpenBug(CheckerContext &C,
                                          ProgramStateRef State,
@@ -378,8 +378,8 @@ ProgramStateRef UnixAPIMisuseChecker::EnsureGetdelimBufferAndSizeCorrect(
   return State;
 }
 
-void UnixAPIMisuseChecker::CheckGetDelim(CheckerContext &C,
-                                         const CallEvent &Call) const {
+void UnixAPIMisuseChecker::CheckGetDelimOrGetline(CheckerContext &C,
+                                                  const CallEvent &Call) const {
   if (Call.getNumArgs() < 2)
     return;
 

>From f6c8601ad49c5a767924029572f2adabd996625d Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Tue, 24 Jun 2025 18:55:03 +0300
Subject: [PATCH 5/6] improve release notes

---
 clang/docs/ReleaseNotes.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b6f6dce29a87b..576abcfe8aa4f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1061,7 +1061,7 @@ Crash and bug fixes
 ^^^^^^^^^^^^^^^^^^^
 
 - Fixed a crash in ``UnixAPIMisuseChecker`` and ``MallocChecker`` when analyzing
-  code with non-standard ``getline`` or ``getdelim`` function signatures.
+  code with non-standard ``getline`` or ``getdelim`` function signatures. (#GH144884)
 
 Improvements
 ^^^^^^^^^^^^

>From ac2da96fb7d4d549cf532398b95a3b41791ec4ff Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Tue, 24 Jun 2025 21:06:09 +0300
Subject: [PATCH 6/6] change name 'getdelim' to 'GetDelimOrGetLine'

---
 .../StaticAnalyzer/Checkers/MallocChecker.cpp | 23 +++++++++++--------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index fe0e2df548bcf..fa6e8e4146804 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -430,8 +430,8 @@ class MallocChecker
   CHECK_FN(checkGMemdup)
   CHECK_FN(checkGMallocN)
   CHECK_FN(checkGMallocN0)
-  CHECK_FN(preGetdelim)
-  CHECK_FN(checkGetdelim)
+  CHECK_FN(preGetDelimOrGetLine)
+  CHECK_FN(checkGetDelimOrGetLine)
   CHECK_FN(checkReallocN)
   CHECK_FN(checkOwnershipAttr)
 
@@ -445,15 +445,16 @@ class MallocChecker
   const CallDescriptionMap<CheckFn> PreFnMap{
       // NOTE: the following CallDescription also matches the C++ standard
       // library function std::getline(); the callback will filter it out.
-      {{CDM::CLibrary, {"getline"}, 3}, &MallocChecker::preGetdelim},
-      {{CDM::CLibrary, {"getdelim"}, 4}, &MallocChecker::preGetdelim},
+      {{CDM::CLibrary, {"getline"}, 3}, &MallocChecker::preGetDelimOrGetLine},
+      {{CDM::CLibrary, {"getdelim"}, 4}, &MallocChecker::preGetDelimOrGetLine},
   };
 
   const CallDescriptionMap<CheckFn> PostFnMap{
       // NOTE: the following CallDescription also matches the C++ standard
       // library function std::getline(); the callback will filter it out.
-      {{CDM::CLibrary, {"getline"}, 3}, &MallocChecker::checkGetdelim},
-      {{CDM::CLibrary, {"getdelim"}, 4}, &MallocChecker::checkGetdelim},
+      {{CDM::CLibrary, {"getline"}, 3}, &MallocChecker::checkGetDelimOrGetLine},
+      {{CDM::CLibrary, {"getdelim"}, 4},
+       &MallocChecker::checkGetDelimOrGetLine},
   };
 
   const CallDescriptionMap<CheckFn> FreeingMemFnMap{
@@ -1482,8 +1483,9 @@ static bool isFromStdNamespace(const CallEvent &Call) {
   return FD->isInStdNamespace();
 }
 
-void MallocChecker::preGetdelim(ProgramStateRef State, const CallEvent &Call,
-                                CheckerContext &C) const {
+void MallocChecker::preGetDelimOrGetLine(ProgramStateRef State,
+                                         const CallEvent &Call,
+                                         CheckerContext &C) const {
   // Discard calls to the C++ standard library function std::getline(), which
   // is completely unrelated to the POSIX getline() that we're checking.
   if (isFromStdNamespace(Call))
@@ -1505,8 +1507,9 @@ void MallocChecker::preGetdelim(ProgramStateRef State, const CallEvent &Call,
     C.addTransition(State);
 }
 
-void MallocChecker::checkGetdelim(ProgramStateRef State, const CallEvent &Call,
-                                  CheckerContext &C) const {
+void MallocChecker::checkGetDelimOrGetLine(ProgramStateRef State,
+                                           const CallEvent &Call,
+                                           CheckerContext &C) const {
   // Discard calls to the C++ standard library function std::getline(), which
   // is completely unrelated to the POSIX getline() that we're checking.
   if (isFromStdNamespace(Call))



More information about the cfe-commits mailing list