[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/benshi001 closed https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/balazske approved this pull request. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
@@ -2211,6 +2221,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + balazske wrote: We can keep the current form. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
@@ -2211,6 +2221,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + benshi001 wrote: @balazske What is your opinion? I think we can keep current form: 1. Negative but non -1 return values are not mentioned in the POSIX document. 2. Negative return values are not supported on real world linux&MacOS. There may be negative but non -1 return values on other platforms, however we currently choose a conservative way as current form. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/steakhal approved this pull request. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
@@ -2211,6 +2221,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + steakhal wrote: Okay. Thanks for digging into this. Consider this thread resolved. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
@@ -2211,6 +2221,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + balazske wrote: The POSIX documentation does not tell if it is possible to get negative value from `fclose` other than -1. Because -1 is reserved for indication of error, it should not be a regular return value (if yes, there should be mentioned that `errno` is not changed at success, to make detection of error possible). If negative non-error return value is allowed, it can not be -1. It looks like that negative return values from the process appear as positive values like in the example above. The returned value is not the value passed to `exit`, that can be extracted by `WEXITSTATUS` (see `waitpid`). https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/benshi001 updated https://github.com/llvm/llvm-project/pull/78895 >From 382ae9d692df575f47c203c9fff2036c42c4833b Mon Sep 17 00:00:00 2001 From: Ben Shi Date: Sun, 21 Jan 2024 18:29:06 +0800 Subject: [PATCH 1/2] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker --- .../Checkers/StdLibraryFunctionsChecker.cpp | 34 +++ .../Analysis/Inputs/system-header-simulator.h | 2 ++ .../Analysis/std-c-library-functions-POSIX.c | 4 +-- clang/test/Analysis/stream-errno.c| 25 ++ 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index 61bf3c8528be2b..be26f5521c8d76 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -2204,6 +2204,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint(NotNull(ArgNo(1))) .ArgConstraint(NotNull(ArgNo(2; +// FILE *popen(const char *command, const char *type); +addToFunctionSummaryMap( +"popen", +Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), +Summary(NoEvalCall) +.Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0))) +.ArgConstraint(NotNull(ArgNo(1; + // int fclose(FILE *stream); addToFunctionSummaryMap( "fclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), @@ -2212,6 +,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .Case(ReturnsEOF, ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + // int ungetc(int c, FILE *stream); addToFunctionSummaryMap( "ungetc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}), @@ -2827,21 +2846,6 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax; -// FILE *popen(const char *command, const char *type); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"popen", -Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), -Summary(NoEvalCall) -.ArgConstraint(NotNull(ArgNo(0))) -.ArgConstraint(NotNull(ArgNo(1; - -// int pclose(FILE *stream); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), -Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0; - // int close(int fildes); addToFunctionSummaryMap( "close", Signature(ArgTypes{IntTy}, RetType{IntTy}), diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h index 96072741a8abc1..15986984802c0e 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -48,7 +48,9 @@ FILE *fopen(const char *restrict path, const char *restrict mode); FILE *fdopen(int fd, const char *mode); FILE *tmpfile(void); FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream); +FILE *popen(const char *command, const char *mode); int fclose(FILE *fp); +int pclose(FILE *stream); size_t fread(void *restrict, size_t, size_t, FILE *restrict); size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict); int fgetc(FILE *stream); diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c index 51b136d9ba3567..03aa8e2e00a75d 100644 --- a/clang/test/Analysis/std-c-library-functions-POSIX.c +++ b/clang/test/Analysis/std-c-library-functions-POSIX.c @@ -20,7 +20,9 @@ // CHECK: Loaded summary for: FILE *fdopen(int fd, const char *mode) // CHECK: Loaded summary for: FILE *tmpfile(void) // CHECK: Loaded summary for: FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream) +// CHECK: Loaded summary for: FILE *popen(const char *command, const char *type) // CHECK: Loaded summary for: int fclose(FILE *stream) +// CHECK: Loaded summary for: int pclose(FILE *stream) // CHECK: Loaded summary for: int fseek(FILE *
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/benshi001 edited https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
@@ -2211,6 +2221,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + benshi001 wrote: I have tried if the return value can be negative on both linux and MacOS, it seems `pclose` always returns positive values on success, even if the child process called `exit(-3)`. Here are my test cases, ``` // father.c, gcc father.c -o father #include #include int main() { FILE *fp = popen("/tmp/child.out", "w"); if (fp) { int r = pclose(fp); printf("%d\n", r); } return 0; } ``` ``` // child.c, gcc child.c -o child #include #include int main() { exit(-3); return -3; } ``` And actually the `child` returns `64768(253 << 8)` to the father. So I think my current conditions are OK. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
@@ -2211,6 +2221,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + steakhal wrote: Quoting manpage: `on success, returns the exit status of the command`, consequently, this might be negative on success. I believe the manpage for `exit(3)` should tell us what values can we expect as exit codes. > The exit() function causes normal process termination and the least significant byte of status (i.e., status & 0xFF) is returned to the parent (see [wait(2)](https://man7.org/linux/man-pages/man2/wait.2.html)). So, I believe any value could be an exit code, that is representable by a signed char (if CHAR_BITS == 8, then [-128,127]) Also add tests for the range for the result of the `pclose`. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/steakhal edited https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/steakhal requested changes to this pull request. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
@@ -51,6 +51,17 @@ void check_freopen(void) { if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}} } +void check_popen(void) { + FILE *F = popen("xxx", "r"); + if (!F) { +clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} +if (errno) {}// no-warning + } else { +if (errno) {} // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}} +pclose(F); + } +} + benshi001 wrote: I have put these tests to `errno-stdlibraryfunctions.c`, which seems better, since tests in `std-c-library-functions-POSIX.c` do not involve `errno`. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/benshi001 updated https://github.com/llvm/llvm-project/pull/78895 >From f2d64a755adc8393d4670d370f6b9a64e368a43b Mon Sep 17 00:00:00 2001 From: Ben Shi Date: Sun, 21 Jan 2024 18:29:06 +0800 Subject: [PATCH 1/2] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker --- .../Checkers/StdLibraryFunctionsChecker.cpp | 34 +++ .../Analysis/Inputs/system-header-simulator.h | 2 ++ .../Analysis/std-c-library-functions-POSIX.c | 4 +-- clang/test/Analysis/stream-errno.c| 25 ++ 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index d0eb5091444f6b6..722fafa457c240b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -2202,6 +2202,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint(NotNull(ArgNo(1))) .ArgConstraint(NotNull(ArgNo(2; +// FILE *popen(const char *command, const char *type); +addToFunctionSummaryMap( +"popen", +Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), +Summary(NoEvalCall) +.Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0))) +.ArgConstraint(NotNull(ArgNo(1; + // int fclose(FILE *stream); addToFunctionSummaryMap( "fclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), @@ -2211,6 +2221,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + // int ungetc(int c, FILE *stream); addToFunctionSummaryMap( "ungetc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}), @@ -2827,21 +2846,6 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax; -// FILE *popen(const char *command, const char *type); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"popen", -Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), -Summary(NoEvalCall) -.ArgConstraint(NotNull(ArgNo(0))) -.ArgConstraint(NotNull(ArgNo(1; - -// int pclose(FILE *stream); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), -Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0; - // int close(int fildes); addToFunctionSummaryMap( "close", Signature(ArgTypes{IntTy}, RetType{IntTy}), diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h index f8e3e546a7aed5e..c41f22fef388e19 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -47,7 +47,9 @@ FILE *fopen(const char *restrict path, const char *restrict mode); FILE *fdopen(int fd, const char *mode); FILE *tmpfile(void); FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream); +FILE *popen(const char *command, const char *mode); int fclose(FILE *fp); +int pclose(FILE *stream); size_t fread(void *restrict, size_t, size_t, FILE *restrict); size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict); int fgetc(FILE *stream); diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c index 51b136d9ba35673..03aa8e2e00a75dd 100644 --- a/clang/test/Analysis/std-c-library-functions-POSIX.c +++ b/clang/test/Analysis/std-c-library-functions-POSIX.c @@ -20,7 +20,9 @@ // CHECK: Loaded summary for: FILE *fdopen(int fd, const char *mode) // CHECK: Loaded summary for: FILE *tmpfile(void) // CHECK: Loaded summary for: FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream) +// CHECK: Loaded summary for: FILE *popen(const char *command, const char *type) // CHECK: Loaded summary for: int fclose(FILE *stream) +// CHECK: Loaded summary for: int pclose(FILE *stream) // CHECK: Loaded summary for: int fseek(FILE *stream
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/balazske edited https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
@@ -51,6 +51,17 @@ void check_freopen(void) { if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}} } +void check_popen(void) { + FILE *F = popen("xxx", "r"); + if (!F) { +clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} +if (errno) {}// no-warning + } else { +if (errno) {} // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}} +pclose(F); + } +} + balazske wrote: I like more if these new tests go into file **std-c-library-functions-POSIX.c**, unless the functions will be added to `StreamChecker` too. It looks like that the API has the same usage for files returned by `popen`, so `popen` (and `pclose`) can be added to `StreamChecker`. https://github.com/llvm/llvm-project/pull/78895 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/benshi001 updated https://github.com/llvm/llvm-project/pull/78895 >From f2d64a755adc8393d4670d370f6b9a64e368a43b Mon Sep 17 00:00:00 2001 From: Ben Shi Date: Sun, 21 Jan 2024 18:29:06 +0800 Subject: [PATCH] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker --- .../Checkers/StdLibraryFunctionsChecker.cpp | 34 +++ .../Analysis/Inputs/system-header-simulator.h | 2 ++ .../Analysis/std-c-library-functions-POSIX.c | 4 +-- clang/test/Analysis/stream-errno.c| 25 ++ 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index d0eb5091444f6b6..722fafa457c240b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -2202,6 +2202,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint(NotNull(ArgNo(1))) .ArgConstraint(NotNull(ArgNo(2; +// FILE *popen(const char *command, const char *type); +addToFunctionSummaryMap( +"popen", +Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), +Summary(NoEvalCall) +.Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0))) +.ArgConstraint(NotNull(ArgNo(1; + // int fclose(FILE *stream); addToFunctionSummaryMap( "fclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), @@ -2211,6 +2221,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + // int ungetc(int c, FILE *stream); addToFunctionSummaryMap( "ungetc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}), @@ -2827,21 +2846,6 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax; -// FILE *popen(const char *command, const char *type); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"popen", -Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), -Summary(NoEvalCall) -.ArgConstraint(NotNull(ArgNo(0))) -.ArgConstraint(NotNull(ArgNo(1; - -// int pclose(FILE *stream); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), -Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0; - // int close(int fildes); addToFunctionSummaryMap( "close", Signature(ArgTypes{IntTy}, RetType{IntTy}), diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h index f8e3e546a7aed5e..c41f22fef388e19 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -47,7 +47,9 @@ FILE *fopen(const char *restrict path, const char *restrict mode); FILE *fdopen(int fd, const char *mode); FILE *tmpfile(void); FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream); +FILE *popen(const char *command, const char *mode); int fclose(FILE *fp); +int pclose(FILE *stream); size_t fread(void *restrict, size_t, size_t, FILE *restrict); size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict); int fgetc(FILE *stream); diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c index 51b136d9ba35673..03aa8e2e00a75dd 100644 --- a/clang/test/Analysis/std-c-library-functions-POSIX.c +++ b/clang/test/Analysis/std-c-library-functions-POSIX.c @@ -20,7 +20,9 @@ // CHECK: Loaded summary for: FILE *fdopen(int fd, const char *mode) // CHECK: Loaded summary for: FILE *tmpfile(void) // CHECK: Loaded summary for: FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream) +// CHECK: Loaded summary for: FILE *popen(const char *command, const char *type) // CHECK: Loaded summary for: int fclose(FILE *stream) +// CHECK: Loaded summary for: int pclose(FILE *stream) // CHECK: Loaded summary for: int fseek(FILE *stream, lo
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
llvmbot wrote: @llvm/pr-subscribers-clang-static-analyzer-1 Author: Ben Shi (benshi001) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/78895.diff 4 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+20-15) - (modified) clang/test/Analysis/Inputs/system-header-simulator.h (+2) - (modified) clang/test/Analysis/std-c-library-functions-POSIX.c (+2-2) - (modified) clang/test/Analysis/stream-errno.c (+25) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index d0eb5091444f6b..4053a829bd7a7d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -2202,6 +2202,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint(NotNull(ArgNo(1))) .ArgConstraint(NotNull(ArgNo(2; +// FILE *popen(const char *command, const char *type); +addToFunctionSummaryMap( +"popen", +Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), +Summary(NoEvalCall) +.Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0))) +.ArgConstraint(NotNull(ArgNo(1; + // int fclose(FILE *stream); addToFunctionSummaryMap( "fclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), @@ -2211,6 +2221,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case({ReturnValueCondition(WithinRange, SingleValue(-1))}, + ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + // int ungetc(int c, FILE *stream); addToFunctionSummaryMap( "ungetc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}), @@ -2827,21 +2847,6 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax; -// FILE *popen(const char *command, const char *type); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"popen", -Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), -Summary(NoEvalCall) -.ArgConstraint(NotNull(ArgNo(0))) -.ArgConstraint(NotNull(ArgNo(1; - -// int pclose(FILE *stream); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), -Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0; - // int close(int fildes); addToFunctionSummaryMap( "close", Signature(ArgTypes{IntTy}, RetType{IntTy}), diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h index f8e3e546a7aed5..c41f22fef388e1 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -47,7 +47,9 @@ FILE *fopen(const char *restrict path, const char *restrict mode); FILE *fdopen(int fd, const char *mode); FILE *tmpfile(void); FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream); +FILE *popen(const char *command, const char *mode); int fclose(FILE *fp); +int pclose(FILE *stream); size_t fread(void *restrict, size_t, size_t, FILE *restrict); size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict); int fgetc(FILE *stream); diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c index 51b136d9ba3567..03aa8e2e00a75d 100644 --- a/clang/test/Analysis/std-c-library-functions-POSIX.c +++ b/clang/test/Analysis/std-c-library-functions-POSIX.c @@ -20,7 +20,9 @@ // CHECK: Loaded summary for: FILE *fdopen(int fd, const char *mode) // CHECK: Loaded summary for: FILE *tmpfile(void) // CHECK: Loaded summary for: FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream) +// CHECK: Loaded summary for: FILE *popen(const char *command, const char *type) // CHECK: Loaded summary for: int fclose(FILE *stream) +// CHECK: Loaded summary for: int pclose(FILE *stream) // CHECK: Loaded summary for: int fseek(FILE *stream, long offset, int whence) // CHECK: Loaded summary for: int fseeko(FILE *strea
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Ben Shi (benshi001) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/78895.diff 4 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+20-15) - (modified) clang/test/Analysis/Inputs/system-header-simulator.h (+2) - (modified) clang/test/Analysis/std-c-library-functions-POSIX.c (+2-2) - (modified) clang/test/Analysis/stream-errno.c (+25) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index d0eb5091444f6b..4053a829bd7a7d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -2202,6 +2202,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint(NotNull(ArgNo(1))) .ArgConstraint(NotNull(ArgNo(2; +// FILE *popen(const char *command, const char *type); +addToFunctionSummaryMap( +"popen", +Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), +Summary(NoEvalCall) +.Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0))) +.ArgConstraint(NotNull(ArgNo(1; + // int fclose(FILE *stream); addToFunctionSummaryMap( "fclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), @@ -2211,6 +2221,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case({ReturnValueCondition(WithinRange, SingleValue(-1))}, + ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + // int ungetc(int c, FILE *stream); addToFunctionSummaryMap( "ungetc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}), @@ -2827,21 +2847,6 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax; -// FILE *popen(const char *command, const char *type); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"popen", -Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), -Summary(NoEvalCall) -.ArgConstraint(NotNull(ArgNo(0))) -.ArgConstraint(NotNull(ArgNo(1; - -// int pclose(FILE *stream); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), -Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0; - // int close(int fildes); addToFunctionSummaryMap( "close", Signature(ArgTypes{IntTy}, RetType{IntTy}), diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h index f8e3e546a7aed5..c41f22fef388e1 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -47,7 +47,9 @@ FILE *fopen(const char *restrict path, const char *restrict mode); FILE *fdopen(int fd, const char *mode); FILE *tmpfile(void); FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream); +FILE *popen(const char *command, const char *mode); int fclose(FILE *fp); +int pclose(FILE *stream); size_t fread(void *restrict, size_t, size_t, FILE *restrict); size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict); int fgetc(FILE *stream); diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c index 51b136d9ba3567..03aa8e2e00a75d 100644 --- a/clang/test/Analysis/std-c-library-functions-POSIX.c +++ b/clang/test/Analysis/std-c-library-functions-POSIX.c @@ -20,7 +20,9 @@ // CHECK: Loaded summary for: FILE *fdopen(int fd, const char *mode) // CHECK: Loaded summary for: FILE *tmpfile(void) // CHECK: Loaded summary for: FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream) +// CHECK: Loaded summary for: FILE *popen(const char *command, const char *type) // CHECK: Loaded summary for: int fclose(FILE *stream) +// CHECK: Loaded summary for: int pclose(FILE *stream) // CHECK: Loaded summary for: int fseek(FILE *stream, long offset, int whence) // CHECK: Loaded summary for: int fseeko(FILE *stream, off_t offset, i
[clang] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker (PR #78895)
https://github.com/benshi001 created https://github.com/llvm/llvm-project/pull/78895 None >From b093d705ee949227ec0f7fe23bb65d43c7f9e51f Mon Sep 17 00:00:00 2001 From: Ben Shi Date: Sun, 21 Jan 2024 18:29:06 +0800 Subject: [PATCH] [clang][analyzer] Improve modeling of 'popen' and 'pclose' in StdLibraryFunctionsChecker --- .../Checkers/StdLibraryFunctionsChecker.cpp | 35 +++ .../Analysis/Inputs/system-header-simulator.h | 2 ++ .../Analysis/std-c-library-functions-POSIX.c | 4 +-- clang/test/Analysis/stream-errno.c| 25 + 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index d0eb5091444f6b..4053a829bd7a7d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -2202,6 +2202,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint(NotNull(ArgNo(1))) .ArgConstraint(NotNull(ArgNo(2; +// FILE *popen(const char *command, const char *type); +addToFunctionSummaryMap( +"popen", +Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), +Summary(NoEvalCall) +.Case({NotNull(Ret)}, ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0))) +.ArgConstraint(NotNull(ArgNo(1; + // int fclose(FILE *stream); addToFunctionSummaryMap( "fclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), @@ -2211,6 +2221,16 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(NotNull(ArgNo(0; +// int pclose(FILE *stream); +addToFunctionSummaryMap( +"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), +Summary(NoEvalCall) +.Case({ReturnValueCondition(WithinRange, {{0, IntMax}})}, + ErrnoMustNotBeChecked, GenericSuccessMsg) +.Case({ReturnValueCondition(WithinRange, SingleValue(-1))}, + ErrnoNEZeroIrrelevant, GenericFailureMsg) +.ArgConstraint(NotNull(ArgNo(0; + // int ungetc(int c, FILE *stream); addToFunctionSummaryMap( "ungetc", Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}), @@ -2827,21 +2847,6 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( .ArgConstraint( ArgumentCondition(0, WithinRange, Range(0, IntMax; -// FILE *popen(const char *command, const char *type); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"popen", -Signature(ArgTypes{ConstCharPtrTy, ConstCharPtrTy}, RetType{FilePtrTy}), -Summary(NoEvalCall) -.ArgConstraint(NotNull(ArgNo(0))) -.ArgConstraint(NotNull(ArgNo(1; - -// int pclose(FILE *stream); -// FIXME: Improve for errno modeling. -addToFunctionSummaryMap( -"pclose", Signature(ArgTypes{FilePtrTy}, RetType{IntTy}), -Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0; - // int close(int fildes); addToFunctionSummaryMap( "close", Signature(ArgTypes{IntTy}, RetType{IntTy}), diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h index f8e3e546a7aed5..c41f22fef388e1 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -47,7 +47,9 @@ FILE *fopen(const char *restrict path, const char *restrict mode); FILE *fdopen(int fd, const char *mode); FILE *tmpfile(void); FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream); +FILE *popen(const char *command, const char *mode); int fclose(FILE *fp); +int pclose(FILE *stream); size_t fread(void *restrict, size_t, size_t, FILE *restrict); size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict); int fgetc(FILE *stream); diff --git a/clang/test/Analysis/std-c-library-functions-POSIX.c b/clang/test/Analysis/std-c-library-functions-POSIX.c index 51b136d9ba3567..03aa8e2e00a75d 100644 --- a/clang/test/Analysis/std-c-library-functions-POSIX.c +++ b/clang/test/Analysis/std-c-library-functions-POSIX.c @@ -20,7 +20,9 @@ // CHECK: Loaded summary for: FILE *fdopen(int fd, const char *mode) // CHECK: Loaded summary for: FILE *tmpfile(void) // CHECK: Loaded summary for: FILE *freopen(const char *restrict pathname, const char *restrict mode, FILE *restrict stream) +// CHECK: Loaded summary for: FILE *popen(const char *command, const char *type) // CHECK: Loaded summary for: int fclose(FILE *stream) +// CHECK: Loaded summary for: int pclose(FILE *stream) /