aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp7
-rw-r--r--clang/test/Analysis/errno-stdlibraryfunctions.c30
2 files changed, 30 insertions, 7 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 6560fd2..2006865 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -2507,10 +2507,13 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
.ArgConstraint(NotNull(ArgNo(0))));
// char *mkdtemp(char *template);
- // FIXME: Improve for errno modeling.
addToFunctionSummaryMap(
"mkdtemp", Signature(ArgTypes{CharPtrTy}, RetType{CharPtrTy}),
- Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
+ Summary(NoEvalCall)
+ .Case({ReturnValueCondition(BO_EQ, ArgNo(0))},
+ ErrnoMustNotBeChecked, GenericSuccessMsg)
+ .Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
+ .ArgConstraint(NotNull(ArgNo(0))));
// char *getcwd(char *buf, size_t size);
// FIXME: Improve for errno modeling.
diff --git a/clang/test/Analysis/errno-stdlibraryfunctions.c b/clang/test/Analysis/errno-stdlibraryfunctions.c
index dafda76..80e14c4 100644
--- a/clang/test/Analysis/errno-stdlibraryfunctions.c
+++ b/clang/test/Analysis/errno-stdlibraryfunctions.c
@@ -7,12 +7,9 @@
// RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true
#include "Inputs/errno_var.h"
+#include "Inputs/std-c-library-functions-POSIX.h"
-typedef typeof(sizeof(int)) size_t;
-typedef __typeof(sizeof(int)) off_t;
-typedef size_t ssize_t;
-ssize_t send(int sockfd, const void *buf, size_t len, int flags);
-off_t lseek(int fildes, off_t offset, int whence);
+#define NULL ((void *) 0)
void clang_analyzer_warnIfReached();
void clang_analyzer_eval(int);
@@ -54,3 +51,26 @@ int errno_lseek(int fildes, off_t offset) {
}
return 0;
}
+
+void errno_mkstemp(char *template) {
+ int FD = mkstemp(template);
+ if (FD >= 0) {
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ close(FD);
+ } else {
+ clang_analyzer_eval(FD == -1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no warning
+ }
+}
+
+void errno_mkdtemp(char *template) {
+ char *Dir = mkdtemp(template);
+ if (Dir == NULL) {
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no warning
+ } else {
+ clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ }
+}