Skip to content

Commit 3db749a

Browse files
authored
[clang][analyzer] Improve 'errno' modeling of 'mkdtemp' (#76671)
1 parent 665d1a0 commit 3db749a

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2507,10 +2507,13 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
25072507
.ArgConstraint(NotNull(ArgNo(0))));
25082508

25092509
// char *mkdtemp(char *template);
2510-
// FIXME: Improve for errno modeling.
25112510
addToFunctionSummaryMap(
25122511
"mkdtemp", Signature(ArgTypes{CharPtrTy}, RetType{CharPtrTy}),
2513-
Summary(NoEvalCall).ArgConstraint(NotNull(ArgNo(0))));
2512+
Summary(NoEvalCall)
2513+
.Case({ReturnValueCondition(BO_EQ, ArgNo(0))},
2514+
ErrnoMustNotBeChecked, GenericSuccessMsg)
2515+
.Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2516+
.ArgConstraint(NotNull(ArgNo(0))));
25142517

25152518
// char *getcwd(char *buf, size_t size);
25162519
// FIXME: Improve for errno modeling.

clang/test/Analysis/errno-stdlibraryfunctions.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@
77
// RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true
88

99
#include "Inputs/errno_var.h"
10+
#include "Inputs/std-c-library-functions-POSIX.h"
1011

11-
typedef typeof(sizeof(int)) size_t;
12-
typedef __typeof(sizeof(int)) off_t;
13-
typedef size_t ssize_t;
14-
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
15-
off_t lseek(int fildes, off_t offset, int whence);
12+
#define NULL ((void *) 0)
1613

1714
void clang_analyzer_warnIfReached();
1815
void clang_analyzer_eval(int);
@@ -54,3 +51,26 @@ int errno_lseek(int fildes, off_t offset) {
5451
}
5552
return 0;
5653
}
54+
55+
void errno_mkstemp(char *template) {
56+
int FD = mkstemp(template);
57+
if (FD >= 0) {
58+
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
59+
close(FD);
60+
} else {
61+
clang_analyzer_eval(FD == -1); // expected-warning{{TRUE}}
62+
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
63+
if (errno) {} // no warning
64+
}
65+
}
66+
67+
void errno_mkdtemp(char *template) {
68+
char *Dir = mkdtemp(template);
69+
if (Dir == NULL) {
70+
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
71+
if (errno) {} // no warning
72+
} else {
73+
clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
74+
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
75+
}
76+
}

0 commit comments

Comments
 (0)