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.2...@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.2...@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.2...@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.2...@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.2...@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.2...@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)) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits