2020-03-20 23:20:53 +08:00
|
|
|
// Check the basic reporting/warning and the application of constraints.
|
|
|
|
// RUN: %clang_analyze_cc1 %s \
|
|
|
|
// RUN: -analyzer-checker=core \
|
|
|
|
// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
|
2020-05-27 18:27:32 +08:00
|
|
|
// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
|
[analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints
Summary:
Previously we induced a state split if there were multiple argument
constraints given for a function. This was because we called
`addTransition` inside the for loop.
The fix is to is to store the state and apply the next argument
constraint on that. And once the loop is finished we call `addTransition`.
Reviewers: NoQ, Szelethus, baloghadamsoftware
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, C
Tags: #clang
Differential Revision: https://reviews.llvm.org/D76790
2020-04-02 22:59:02 +08:00
|
|
|
// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \
|
2020-03-20 23:20:53 +08:00
|
|
|
// RUN: -analyzer-checker=debug.ExprInspection \
|
|
|
|
// RUN: -triple x86_64-unknown-linux-gnu \
|
|
|
|
// RUN: -verify=report
|
|
|
|
|
|
|
|
// Check the bugpath related to the reports.
|
|
|
|
// RUN: %clang_analyze_cc1 %s \
|
|
|
|
// RUN: -analyzer-checker=core \
|
|
|
|
// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
|
2020-05-27 18:27:32 +08:00
|
|
|
// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
|
[analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints
Summary:
Previously we induced a state split if there were multiple argument
constraints given for a function. This was because we called
`addTransition` inside the for loop.
The fix is to is to store the state and apply the next argument
constraint on that. And once the loop is finished we call `addTransition`.
Reviewers: NoQ, Szelethus, baloghadamsoftware
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, C
Tags: #clang
Differential Revision: https://reviews.llvm.org/D76790
2020-04-02 22:59:02 +08:00
|
|
|
// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \
|
2020-03-20 23:20:53 +08:00
|
|
|
// RUN: -analyzer-checker=debug.ExprInspection \
|
|
|
|
// RUN: -triple x86_64-unknown-linux-gnu \
|
|
|
|
// RUN: -analyzer-output=text \
|
|
|
|
// RUN: -verify=bugpath
|
|
|
|
|
|
|
|
void clang_analyzer_eval(int);
|
|
|
|
|
|
|
|
int glob;
|
|
|
|
|
|
|
|
#define EOF -1
|
|
|
|
|
|
|
|
int isalnum(int);
|
|
|
|
|
|
|
|
void test_alnum_concrete(int v) {
|
|
|
|
int ret = isalnum(256); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-03-20 23:20:53 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-03-20 23:20:53 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
(void)ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_alnum_symbolic(int x) {
|
|
|
|
int ret = isalnum(x);
|
|
|
|
(void)ret;
|
|
|
|
|
|
|
|
clang_analyzer_eval(EOF <= x && x <= 255); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}} \
|
|
|
|
// bugpath-note{{Left side of '&&' is true}} \
|
|
|
|
// bugpath-note{{'x' is <= 255}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_alnum_symbolic2(int x) {
|
|
|
|
if (x > 255) { // \
|
|
|
|
// bugpath-note{{Assuming 'x' is > 255}} \
|
|
|
|
// bugpath-note{{Taking true branch}}
|
|
|
|
|
|
|
|
int ret = isalnum(x); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-03-20 23:20:53 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-03-20 23:20:53 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
|
|
|
|
(void)ret;
|
|
|
|
}
|
|
|
|
}
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
|
2020-08-12 22:18:42 +08:00
|
|
|
int toupper(int);
|
|
|
|
|
|
|
|
void test_toupper_concrete(int v) {
|
|
|
|
int ret = toupper(256); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
(void)ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_toupper_symbolic(int x) {
|
|
|
|
int ret = toupper(x);
|
|
|
|
(void)ret;
|
|
|
|
|
|
|
|
clang_analyzer_eval(EOF <= x && x <= 255); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}} \
|
|
|
|
// bugpath-note{{Left side of '&&' is true}} \
|
|
|
|
// bugpath-note{{'x' is <= 255}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_toupper_symbolic2(int x) {
|
|
|
|
if (x > 255) { // \
|
|
|
|
// bugpath-note{{Assuming 'x' is > 255}} \
|
|
|
|
// bugpath-note{{Taking true branch}}
|
|
|
|
|
|
|
|
int ret = toupper(x); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
|
|
|
|
(void)ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int tolower(int);
|
|
|
|
|
|
|
|
void test_tolower_concrete(int v) {
|
|
|
|
int ret = tolower(256); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
(void)ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_tolower_symbolic(int x) {
|
|
|
|
int ret = tolower(x);
|
|
|
|
(void)ret;
|
|
|
|
|
|
|
|
clang_analyzer_eval(EOF <= x && x <= 255); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}} \
|
|
|
|
// bugpath-note{{Left side of '&&' is true}} \
|
|
|
|
// bugpath-note{{'x' is <= 255}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_tolower_symbolic2(int x) {
|
|
|
|
if (x > 255) { // \
|
|
|
|
// bugpath-note{{Assuming 'x' is > 255}} \
|
|
|
|
// bugpath-note{{Taking true branch}}
|
|
|
|
|
|
|
|
int ret = tolower(x); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
|
|
|
|
(void)ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int toascii(int);
|
|
|
|
|
|
|
|
void test_toascii_concrete(int v) {
|
|
|
|
int ret = toascii(256); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
(void)ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_toascii_symbolic(int x) {
|
|
|
|
int ret = toascii(x);
|
|
|
|
(void)ret;
|
|
|
|
|
|
|
|
clang_analyzer_eval(EOF <= x && x <= 255); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}} \
|
|
|
|
// bugpath-note{{Left side of '&&' is true}} \
|
|
|
|
// bugpath-note{{'x' is <= 255}}
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_toascii_symbolic2(int x) {
|
|
|
|
if (x > 255) { // \
|
|
|
|
// bugpath-note{{Assuming 'x' is > 255}} \
|
|
|
|
// bugpath-note{{Taking true branch}}
|
|
|
|
|
|
|
|
int ret = toascii(x); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-08-12 22:18:42 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
|
|
|
|
(void)ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
typedef struct FILE FILE;
|
|
|
|
typedef typeof(sizeof(int)) size_t;
|
[analyzer] StdLibraryFunctionsChecker: Add support to lookup types
Summary:
In this patch I am trying to get rid of the `Irrelevant` types from the
signatures of the functions from the standard C library. For that I've
introduced `lookupType()` to be able to lookup arbitrary types in the global
scope. This makes it possible to define the signatures precisely.
Note 1) `fread`'s signature is now fixed to have the proper `FILE *restrict`
type when C99 is the language.
Note 2) There are still existing `Irrelevant` types, but they are all from
POSIX. I am planning to address those together with the missing POSIX functions
(in D79433).
Reviewers: xazax.hun, NoQ, Szelethus, balazske
Subscribers: whisperity, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, steakhal, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D80016
2020-05-15 17:25:40 +08:00
|
|
|
size_t fread(void *restrict, size_t, size_t, FILE *restrict);
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
void test_notnull_concrete(FILE *fp) {
|
|
|
|
fread(0, sizeof(int), 10, fp); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
}
|
|
|
|
void test_notnull_symbolic(FILE *fp, int *buf) {
|
|
|
|
fread(buf, sizeof(int), 10, fp);
|
|
|
|
clang_analyzer_eval(buf != 0); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}} \
|
|
|
|
// bugpath-note{{'buf' is not equal to null}}
|
|
|
|
}
|
|
|
|
void test_notnull_symbolic2(FILE *fp, int *buf) {
|
2020-08-12 22:18:42 +08:00
|
|
|
if (!buf) // bugpath-note{{Assuming 'buf' is null}} \
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
// bugpath-note{{Taking true branch}}
|
|
|
|
fread(buf, sizeof(int), 10, fp); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
[analyzer] StdLibraryFunctionsChecker: Add NotNull Arg Constraint
Reviewers: NoQ, Szelethus, balazske, gamesh411, baloghadamsoftware, steakhal
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D75063
2020-03-21 00:23:23 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
}
|
2020-09-03 19:23:49 +08:00
|
|
|
typedef __WCHAR_TYPE__ wchar_t;
|
|
|
|
// This is one test case for the ARR38-C SEI-CERT rule.
|
|
|
|
void ARR38_C_F(FILE *file) {
|
|
|
|
enum { BUFFER_SIZE = 1024 };
|
|
|
|
wchar_t wbuf[BUFFER_SIZE]; // bugpath-note{{'wbuf' initialized here}}
|
|
|
|
|
2021-04-27 20:57:12 +08:00
|
|
|
const size_t size = sizeof(*wbuf); // bugpath-note{{'size' initialized to}}
|
|
|
|
const size_t nitems = sizeof(wbuf); // bugpath-note{{'nitems' initialized to}}
|
2020-09-03 19:23:49 +08:00
|
|
|
|
|
|
|
// The 3rd parameter should be the number of elements to read, not
|
|
|
|
// the size in bytes.
|
|
|
|
fread(wbuf, size, nitems, file); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-09-03 19:23:49 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-09-03 19:23:49 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
}
|
[analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints
Summary:
Previously we induced a state split if there were multiple argument
constraints given for a function. This was because we called
`addTransition` inside the for loop.
The fix is to is to store the state and apply the next argument
constraint on that. And once the loop is finished we call `addTransition`.
Reviewers: NoQ, Szelethus, baloghadamsoftware
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, C
Tags: #clang
Differential Revision: https://reviews.llvm.org/D76790
2020-04-02 22:59:02 +08:00
|
|
|
|
|
|
|
int __two_constrained_args(int, int);
|
|
|
|
void test_constraints_on_multiple_args(int x, int y) {
|
|
|
|
// State split should not happen here. I.e. x == 1 should not be evaluated
|
|
|
|
// FALSE.
|
|
|
|
__two_constrained_args(x, y);
|
|
|
|
clang_analyzer_eval(x == 1); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}}
|
|
|
|
clang_analyzer_eval(y == 1); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}}
|
|
|
|
}
|
|
|
|
|
|
|
|
int __arg_constrained_twice(int);
|
|
|
|
void test_multiple_constraints_on_same_arg(int x) {
|
|
|
|
__arg_constrained_twice(x);
|
|
|
|
// Check that both constraints are applied and only one branch is there.
|
|
|
|
clang_analyzer_eval(x < 1 || x > 2); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}} \
|
|
|
|
// bugpath-note{{Assuming 'x' is < 1}} \
|
|
|
|
// bugpath-note{{Left side of '||' is true}}
|
|
|
|
}
|
[analyzer] StdLibraryFunctionsChecker: match signature based on FunctionDecl
Summary:
Currently we match the summary signature based on the arguments in the CallExpr.
There are a few problems with this approach.
1) Variadic arguments are handled badly. Consider the below code:
int foo(void *stream, const char *format, ...);
void test_arg_constraint_on_variadic_fun() {
foo(0, "%d%d", 1, 2); // CallExpr
}
Here the call expression holds 4 arguments, whereas the function declaration
has only 2 `ParmVarDecl`s. So there is no way to create a summary that
matches the call expression, because the discrepancy in the number of
arguments causes a mismatch.
2) The call expression does not handle the `restrict` type qualifier.
In C99, fwrite's signature is the following:
size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
However, in a call expression, like below, the type of the argument does not
have the restrict qualifier.
void test_fread_fwrite(FILE *fp, int *buf) {
size_t x = fwrite(buf, sizeof(int), 10, fp);
}
This can result in an unmatches signature, so the summary is not applied.
The solution is to match the summary against the referened callee
`FunctionDecl` that we can query from the `CallExpr`.
Further patches will continue with additional refactoring where I am going to
do a lookup during the checker initialization and the signature match will
happen there. That way, we will not check the signature during every call,
rather we will compare only two `FunctionDecl` pointers.
Reviewers: NoQ, Szelethus, gamesh411, baloghadamsoftware
Subscribers: whisperity, xazax.hun, kristof.beyls, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, steakhal, danielkiss, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77410
2020-04-03 23:01:00 +08:00
|
|
|
|
|
|
|
int __variadic(void *stream, const char *format, ...);
|
|
|
|
void test_arg_constraint_on_variadic_fun() {
|
|
|
|
__variadic(0, "%d%d", 1, 2); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
[analyzer] StdLibraryFunctionsChecker: match signature based on FunctionDecl
Summary:
Currently we match the summary signature based on the arguments in the CallExpr.
There are a few problems with this approach.
1) Variadic arguments are handled badly. Consider the below code:
int foo(void *stream, const char *format, ...);
void test_arg_constraint_on_variadic_fun() {
foo(0, "%d%d", 1, 2); // CallExpr
}
Here the call expression holds 4 arguments, whereas the function declaration
has only 2 `ParmVarDecl`s. So there is no way to create a summary that
matches the call expression, because the discrepancy in the number of
arguments causes a mismatch.
2) The call expression does not handle the `restrict` type qualifier.
In C99, fwrite's signature is the following:
size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
However, in a call expression, like below, the type of the argument does not
have the restrict qualifier.
void test_fread_fwrite(FILE *fp, int *buf) {
size_t x = fwrite(buf, sizeof(int), 10, fp);
}
This can result in an unmatches signature, so the summary is not applied.
The solution is to match the summary against the referened callee
`FunctionDecl` that we can query from the `CallExpr`.
Further patches will continue with additional refactoring where I am going to
do a lookup during the checker initialization and the signature match will
happen there. That way, we will not check the signature during every call,
rather we will compare only two `FunctionDecl` pointers.
Reviewers: NoQ, Szelethus, gamesh411, baloghadamsoftware
Subscribers: whisperity, xazax.hun, kristof.beyls, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, steakhal, danielkiss, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77410
2020-04-03 23:01:00 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
[analyzer] StdLibraryFunctionsChecker: match signature based on FunctionDecl
Summary:
Currently we match the summary signature based on the arguments in the CallExpr.
There are a few problems with this approach.
1) Variadic arguments are handled badly. Consider the below code:
int foo(void *stream, const char *format, ...);
void test_arg_constraint_on_variadic_fun() {
foo(0, "%d%d", 1, 2); // CallExpr
}
Here the call expression holds 4 arguments, whereas the function declaration
has only 2 `ParmVarDecl`s. So there is no way to create a summary that
matches the call expression, because the discrepancy in the number of
arguments causes a mismatch.
2) The call expression does not handle the `restrict` type qualifier.
In C99, fwrite's signature is the following:
size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
However, in a call expression, like below, the type of the argument does not
have the restrict qualifier.
void test_fread_fwrite(FILE *fp, int *buf) {
size_t x = fwrite(buf, sizeof(int), 10, fp);
}
This can result in an unmatches signature, so the summary is not applied.
The solution is to match the summary against the referened callee
`FunctionDecl` that we can query from the `CallExpr`.
Further patches will continue with additional refactoring where I am going to
do a lookup during the checker initialization and the signature match will
happen there. That way, we will not check the signature during every call,
rather we will compare only two `FunctionDecl` pointers.
Reviewers: NoQ, Szelethus, gamesh411, baloghadamsoftware
Subscribers: whisperity, xazax.hun, kristof.beyls, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, Charusso, steakhal, danielkiss, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77410
2020-04-03 23:01:00 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
}
|
[analyzer] ApiModeling: Add buffer size arg constraint
Summary:
Introducing a new argument constraint to confine buffer sizes. It is typical in
C APIs that a parameter represents a buffer and another param holds the size of
the buffer (or the size of the data we want to handle from the buffer).
Reviewers: NoQ, Szelethus, Charusso, steakhal
Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77066
2020-03-30 23:47:48 +08:00
|
|
|
|
|
|
|
int __buf_size_arg_constraint(const void *, size_t);
|
|
|
|
void test_buf_size_concrete() {
|
|
|
|
char buf[3]; // bugpath-note{{'buf' initialized here}}
|
|
|
|
__buf_size_arg_constraint(buf, 4); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
[analyzer] ApiModeling: Add buffer size arg constraint
Summary:
Introducing a new argument constraint to confine buffer sizes. It is typical in
C APIs that a parameter represents a buffer and another param holds the size of
the buffer (or the size of the data we want to handle from the buffer).
Reviewers: NoQ, Szelethus, Charusso, steakhal
Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77066
2020-03-30 23:47:48 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
[analyzer] ApiModeling: Add buffer size arg constraint
Summary:
Introducing a new argument constraint to confine buffer sizes. It is typical in
C APIs that a parameter represents a buffer and another param holds the size of
the buffer (or the size of the data we want to handle from the buffer).
Reviewers: NoQ, Szelethus, Charusso, steakhal
Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77066
2020-03-30 23:47:48 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
}
|
|
|
|
void test_buf_size_symbolic(int s) {
|
|
|
|
char buf[3];
|
|
|
|
__buf_size_arg_constraint(buf, s);
|
|
|
|
clang_analyzer_eval(s <= 3); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}} \
|
|
|
|
// bugpath-note{{'s' is <= 3}}
|
|
|
|
}
|
|
|
|
void test_buf_size_symbolic_and_offset(int s) {
|
|
|
|
char buf[3];
|
|
|
|
__buf_size_arg_constraint(buf + 1, s);
|
|
|
|
clang_analyzer_eval(s <= 2); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}} \
|
|
|
|
// bugpath-note{{'s' is <= 2}}
|
|
|
|
}
|
2020-07-22 00:50:43 +08:00
|
|
|
|
[analyzer] ApiModeling: Add buffer size arg constraint with multiplier involved
Summary:
Further develop the buffer size argumentum constraint so it can handle sizes
that we can get by multiplying two variables.
Reviewers: Szelethus, NoQ, steakhal
Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77148
2020-03-31 23:41:10 +08:00
|
|
|
int __buf_size_arg_constraint_mul(const void *, size_t, size_t);
|
|
|
|
void test_buf_size_concrete_with_multiplication() {
|
2020-08-12 22:18:42 +08:00
|
|
|
short buf[3]; // bugpath-note{{'buf' initialized here}}
|
[analyzer] ApiModeling: Add buffer size arg constraint with multiplier involved
Summary:
Further develop the buffer size argumentum constraint so it can handle sizes
that we can get by multiplying two variables.
Reviewers: Szelethus, NoQ, steakhal
Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77148
2020-03-31 23:41:10 +08:00
|
|
|
__buf_size_arg_constraint_mul(buf, 4, sizeof(short)); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
[analyzer] ApiModeling: Add buffer size arg constraint with multiplier involved
Summary:
Further develop the buffer size argumentum constraint so it can handle sizes
that we can get by multiplying two variables.
Reviewers: Szelethus, NoQ, steakhal
Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77148
2020-03-31 23:41:10 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
[analyzer] ApiModeling: Add buffer size arg constraint with multiplier involved
Summary:
Further develop the buffer size argumentum constraint so it can handle sizes
that we can get by multiplying two variables.
Reviewers: Szelethus, NoQ, steakhal
Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, ASDenysPetrov, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77148
2020-03-31 23:41:10 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
}
|
|
|
|
void test_buf_size_symbolic_with_multiplication(size_t s) {
|
|
|
|
short buf[3];
|
|
|
|
__buf_size_arg_constraint_mul(buf, s, sizeof(short));
|
|
|
|
clang_analyzer_eval(s * sizeof(short) <= 6); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}}
|
|
|
|
}
|
|
|
|
void test_buf_size_symbolic_and_offset_with_multiplication(size_t s) {
|
|
|
|
short buf[3];
|
|
|
|
__buf_size_arg_constraint_mul(buf + 1, s, sizeof(short));
|
|
|
|
clang_analyzer_eval(s * sizeof(short) <= 4); // \
|
|
|
|
// report-warning{{TRUE}} \
|
|
|
|
// bugpath-warning{{TRUE}} \
|
|
|
|
// bugpath-note{{TRUE}}
|
|
|
|
}
|
2020-07-22 00:50:43 +08:00
|
|
|
|
|
|
|
// The minimum buffer size for this function is set to 10.
|
|
|
|
int __buf_size_arg_constraint_concrete(const void *);
|
|
|
|
void test_min_buf_size() {
|
|
|
|
char buf[9];// bugpath-note{{'buf' initialized here}}
|
|
|
|
__buf_size_arg_constraint_concrete(buf); // \
|
|
|
|
// report-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// report-note{{}} \
|
2020-07-22 00:50:43 +08:00
|
|
|
// bugpath-warning{{Function argument constraint is not satisfied}} \
|
2021-04-22 21:12:40 +08:00
|
|
|
// bugpath-note{{}} \
|
2020-07-22 00:50:43 +08:00
|
|
|
// bugpath-note{{Function argument constraint is not satisfied}}
|
|
|
|
}
|