Skip to content

Commit 7dd2063

Browse files
authored
Improve modeling of 'getcwd' in the StdLibraryFunctionsChecker (#77040)
1. Improve the 'errno' modeling. 2. Improve constraints of the arguments.
1 parent 2b3baff commit 7dd2063

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,9 +1150,10 @@ Improvements
11501150
^^^^^^^^^^^^
11511151

11521152
- Improved the ``unix.StdCLibraryFunctions`` checker by modeling more
1153-
functions like ``send``, ``recv``, ``readlink``, ``fflush``, ``mkdtemp`` and
1154-
``errno`` behavior.
1153+
functions like ``send``, ``recv``, ``readlink``, ``fflush``, ``mkdtemp``,
1154+
``getcwd`` and ``errno`` behavior.
11551155
(`52ac71f92d38 <https://github.com/llvm/llvm-project/commit/52ac71f92d38f75df5cb88e9c090ac5fd5a71548>`_,
1156+
`#77040 <https://github.com/llvm/llvm-project/pull/77040>`_,
11561157
`#76671 <https://github.com/llvm/llvm-project/pull/76671>`_,
11571158
`#71373 <https://github.com/llvm/llvm-project/pull/71373>`_,
11581159
`#76557 <https://github.com/llvm/llvm-project/pull/76557>`_,

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2516,10 +2516,21 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
25162516
.ArgConstraint(NotNull(ArgNo(0))));
25172517

25182518
// char *getcwd(char *buf, size_t size);
2519-
// FIXME: Improve for errno modeling.
25202519
addToFunctionSummaryMap(
25212520
"getcwd", Signature(ArgTypes{CharPtrTy, SizeTy}, RetType{CharPtrTy}),
25222521
Summary(NoEvalCall)
2522+
.Case({ArgumentCondition(1, WithinRange, Range(1, SizeMax)),
2523+
ReturnValueCondition(BO_EQ, ArgNo(0))},
2524+
ErrnoMustNotBeChecked, GenericSuccessMsg)
2525+
.Case({ArgumentCondition(1, WithinRange, SingleValue(0)),
2526+
IsNull(Ret)},
2527+
ErrnoNEZeroIrrelevant, "Assuming that argument 'size' is 0")
2528+
.Case({ArgumentCondition(1, WithinRange, Range(1, SizeMax)),
2529+
IsNull(Ret)},
2530+
ErrnoNEZeroIrrelevant, GenericFailureMsg)
2531+
.ArgConstraint(NotNull(ArgNo(0)))
2532+
.ArgConstraint(
2533+
BufferSize(/*Buffer*/ ArgNo(0), /*BufSize*/ ArgNo(1)))
25232534
.ArgConstraint(
25242535
ArgumentCondition(1, WithinRange, Range(0, SizeMax))));
25252536

clang/test/Analysis/errno-stdlibraryfunctions.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,18 @@ void errno_mkdtemp(char *template) {
7474
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
7575
}
7676
}
77+
78+
void errno_getcwd(char *Buf, size_t Sz) {
79+
char *Path = getcwd(Buf, Sz);
80+
if (Sz == 0) {
81+
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
82+
clang_analyzer_eval(Path == NULL); // expected-warning{{TRUE}}
83+
if (errno) {} // no warning
84+
} else if (Path == NULL) {
85+
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
86+
if (errno) {} // no warning
87+
} else {
88+
clang_analyzer_eval(Path == Buf); // expected-warning{{TRUE}}
89+
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
90+
}
91+
}

0 commit comments

Comments
 (0)