Skip to content

Commit 1c29d22

Browse files
committed
improved function modeling
1 parent 1820af2 commit 1c29d22

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,7 +2236,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
22362236
.Case({ReturnValueCondition(WithinRange, {{0, UCharRangeMax}})},
22372237
ErrnoMustNotBeChecked, GenericSuccessMsg)
22382238
.Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
2239-
ErrnoNEZeroIrrelevant, GenericFailureMsg)
2239+
ErrnoIrrelevant, GenericFailureMsg)
22402240
.ArgConstraint(NotNull(ArgNo(0))));
22412241

22422242
// int fputc(int c, FILE *stream);
@@ -2245,13 +2245,15 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
22452245
{"putc", "fputc"},
22462246
Signature(ArgTypes{IntTy, FilePtrTy}, RetType{IntTy}),
22472247
Summary(NoEvalCall)
2248-
.Case({ReturnValueCondition(BO_EQ, ArgNo(0))},
2248+
.Case({ArgumentCondition(0, WithinRange, Range(0, UCharRangeMax)),
2249+
ReturnValueCondition(BO_EQ, ArgNo(0))},
2250+
ErrnoMustNotBeChecked, GenericSuccessMsg)
2251+
.Case({ArgumentCondition(0, OutOfRange, Range(0, UCharRangeMax)),
2252+
ReturnValueCondition(WithinRange, Range(0, UCharRangeMax))},
22492253
ErrnoMustNotBeChecked, GenericSuccessMsg)
22502254
.Case({ReturnValueCondition(WithinRange, SingleValue(EOFv))},
22512255
ErrnoNEZeroIrrelevant, GenericFailureMsg)
2252-
.ArgConstraint(NotNull(ArgNo(1)))
2253-
.ArgConstraint(
2254-
ArgumentCondition(0, WithinRange, {{0, UCharRangeMax}})));
2256+
.ArgConstraint(NotNull(ArgNo(1))));
22552257

22562258
// char *fgets(char *restrict s, int n, FILE *restrict stream);
22572259
addToFunctionSummaryMap(
@@ -2261,9 +2263,11 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
22612263
Summary(NoEvalCall)
22622264
.Case({ReturnValueCondition(BO_EQ, ArgNo(0))},
22632265
ErrnoMustNotBeChecked, GenericSuccessMsg)
2264-
.Case({IsNull(Ret)}, ErrnoNEZeroIrrelevant, GenericFailureMsg)
2266+
.Case({IsNull(Ret)}, ErrnoIrrelevant, GenericFailureMsg)
22652267
.ArgConstraint(NotNull(ArgNo(0)))
22662268
.ArgConstraint(ArgumentCondition(1, WithinRange, Range(0, IntMax)))
2269+
.ArgConstraint(
2270+
BufferSize(/*Buffer=*/ArgNo(0), /*BufSize=*/ArgNo(1)))
22672271
.ArgConstraint(NotNull(ArgNo(2))));
22682272

22692273
// int fputs(const char *restrict s, FILE *restrict stream);

clang/test/Analysis/stream-noopen.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ void test_fgetc(FILE *F) {
6464
if (errno) {} // expected-warning {{undefined}}
6565
} else {
6666
clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}}
67+
// expected-warning@-1 {{FALSE}}
6768
}
6869
clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}}
6970
clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}}
@@ -92,9 +93,18 @@ void test_fgets(char *Buf, int N, FILE *F) {
9293
} else {
9394
clang_analyzer_eval(Ret == 0); // expected-warning {{TRUE}}
9495
clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}}
96+
// expected-warning@-1 {{FALSE}}
9597
}
9698
clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}}
9799
clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}}
100+
101+
char Buf1[10];
102+
Ret = fgets(Buf1, 11, F); // expected-warning {{The 1st argument to 'fgets' is a buffer with size 10}}
103+
}
104+
105+
void test_fgets_bufsize(FILE *F) {
106+
char Buf[10];
107+
fgets(Buf, 11, F); // expected-warning {{The 1st argument to 'fgets' is a buffer with size 10}}
98108
}
99109

100110
void test_fputs(char *Buf, FILE *F) {

0 commit comments

Comments
 (0)