balazske created this revision. Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, gamesh411, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, xazax.hun. Herald added a reviewer: Szelethus. Herald added a reviewer: NoQ. Herald added a project: All. balazske requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The modeling of send, recv, sendmsg, recvmsg, sendto, recvfrom is changed: These functions do return 0, except is the message length is 0. (In sendmsg, recvmsg the length is not checkable but it is more likely that a message with 0 length is invalid for these functions.) Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D155715 Files: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions-POSIX.c
Index: clang/test/Analysis/std-c-library-functions-POSIX.c =================================================================== --- clang/test/Analysis/std-c-library-functions-POSIX.c +++ clang/test/Analysis/std-c-library-functions-POSIX.c @@ -141,6 +141,8 @@ #include "Inputs/std-c-library-functions-POSIX.h" +void clang_analyzer_eval(int); + void test_open(void) { open(0, 0); // \ // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}} @@ -150,3 +152,56 @@ open(0, 0, 0); // \ // expected-warning{{The 1st argument to 'open' is NULL but should not be NULL}} } + +void test_recvfrom(int socket, void *restrict buffer, size_t length, int flags, + struct sockaddr *restrict address, + socklen_t *restrict address_len) { + ssize_t Ret = recvfrom(socket, buffer, length, flags, address, address_len); + if (Ret == 0) + clang_analyzer_eval(length == 0); // expected-warning{{TRUE}} + if (Ret > 0) + clang_analyzer_eval(length > 0); // expected-warning{{TRUE}} + if (Ret == -1) + clang_analyzer_eval(length == 0); // expected-warning{{UNKNOWN}} +} + +void test_sendto(int socket, const void *message, size_t length, int flags, + const struct sockaddr *dest_addr, socklen_t dest_len) { + ssize_t Ret = sendto(socket, message, length, flags, dest_addr, dest_len); + if (Ret == 0) + clang_analyzer_eval(length == 0); // expected-warning{{TRUE}} + if (Ret > 0) + clang_analyzer_eval(length > 0); // expected-warning{{TRUE}} + if (Ret == -1) + clang_analyzer_eval(length == 0); // expected-warning{{UNKNOWN}} +} + +void test_recv(int sockfd, void *buf, size_t len, int flags) { + ssize_t Ret = recv(sockfd, buf, len, flags); + if (Ret == 0) + clang_analyzer_eval(len == 0); // expected-warning{{TRUE}} + if (Ret > 0) + clang_analyzer_eval(len > 0); // expected-warning{{TRUE}} + if (Ret == -1) + clang_analyzer_eval(len == 0); // expected-warning{{UNKNOWN}} +} + +void test_send(int sockfd, void *buf, size_t len, int flags) { + ssize_t Ret = send(sockfd, buf, len, flags); + if (Ret == 0) + clang_analyzer_eval(len == 0); // expected-warning{{TRUE}} + if (Ret > 0) + clang_analyzer_eval(len > 0); // expected-warning{{TRUE}} + if (Ret == -1) + clang_analyzer_eval(len == 0); // expected-warning{{UNKNOWN}} +} + +void test_recvmsg(int sockfd, struct msghdr *msg, int flags) { + ssize_t Ret = recvmsg(sockfd, msg, flags); + clang_analyzer_eval(Ret != 0); // expected-warning{{TRUE}} +} + +void test_sendmsg(int sockfd, const struct msghdr *msg, int flags) { + ssize_t Ret = sendmsg(sockfd, msg, flags); + clang_analyzer_eval(Ret != 0); // expected-warning{{TRUE}} +} Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -3096,7 +3096,10 @@ auto Recvfrom = Summary(NoEvalCall) .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), - ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))}, + ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))}, + ErrnoMustNotBeChecked, GenericSuccessMsg) + .Case({ReturnValueCondition(WithinRange, SingleValue(0)), + ArgumentCondition(2, WithinRange, SingleValue(0))}, ErrnoMustNotBeChecked, GenericSuccessMsg) .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) @@ -3123,7 +3126,10 @@ auto Sendto = Summary(NoEvalCall) .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), - ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))}, + ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))}, + ErrnoMustNotBeChecked, GenericSuccessMsg) + .Case({ReturnValueCondition(WithinRange, SingleValue(0)), + ArgumentCondition(2, WithinRange, SingleValue(0))}, ErrnoMustNotBeChecked, GenericSuccessMsg) .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) @@ -3161,7 +3167,10 @@ RetType{Ssize_tTy}), Summary(NoEvalCall) .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), - ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))}, + ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))}, + ErrnoMustNotBeChecked, GenericSuccessMsg) + .Case({ReturnValueCondition(WithinRange, SingleValue(0)), + ArgumentCondition(2, WithinRange, SingleValue(0))}, ErrnoMustNotBeChecked, GenericSuccessMsg) .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax))) @@ -3179,7 +3188,7 @@ Signature(ArgTypes{IntTy, StructMsghdrPtrTy, IntTy}, RetType{Ssize_tTy}), Summary(NoEvalCall) - .Case({ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))}, + .Case({ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))}, ErrnoMustNotBeChecked, GenericSuccessMsg) .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint( @@ -3191,7 +3200,7 @@ Signature(ArgTypes{IntTy, ConstStructMsghdrPtrTy, IntTy}, RetType{Ssize_tTy}), Summary(NoEvalCall) - .Case({ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))}, + .Case({ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))}, ErrnoMustNotBeChecked, GenericSuccessMsg) .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint( @@ -3233,7 +3242,10 @@ RetType{Ssize_tTy}), Summary(NoEvalCall) .Case({ReturnValueCondition(LessThanOrEq, ArgNo(2)), - ReturnValueCondition(WithinRange, Range(0, Ssize_tMax))}, + ReturnValueCondition(WithinRange, Range(1, Ssize_tMax))}, + ErrnoMustNotBeChecked, GenericSuccessMsg) + .Case({ReturnValueCondition(WithinRange, SingleValue(0)), + ArgumentCondition(2, WithinRange, SingleValue(0))}, ErrnoMustNotBeChecked, GenericSuccessMsg) .Case(ReturnsMinusOne, ErrnoNEZeroIrrelevant, GenericFailureMsg) .ArgConstraint(ArgumentCondition(0, WithinRange, Range(0, IntMax)))
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits