analyzer: fix missing -Wanalyzer-use-of-uninitialized-value on special-cased functions [PR106573]
We were missing checks for uninitialized params on calls to functions that the analyzer has hardcoded knowledge of - both for those that are handled just by state machines, and for those that are handled in region-model-impl-calls.cc (for those arguments for which the svalue wasn't accessed in handling the call). Fixed thusly. gcc/analyzer/ChangeLog: PR analyzer/106573 * region-model.cc (region_model::on_call_pre): Ensure that we call get_arg_svalue on all arguments. gcc/testsuite/ChangeLog: PR analyzer/106573 * gcc.dg/analyzer/error-uninit.c: New test. * gcc.dg/analyzer/fd-uninit-1.c: New test. * gcc.dg/analyzer/file-uninit-1.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
a56c1641e9
commit
bddd8d86e3
|
@ -1355,6 +1355,14 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
|
|||
&& gimple_call_internal_fn (call) == IFN_DEFERRED_INIT)
|
||||
return false;
|
||||
|
||||
/* Get svalues for all of the arguments at the callsite, to ensure that we
|
||||
complain about any uninitialized arguments. This might lead to
|
||||
duplicates if any of the handling below also looks up the svalues,
|
||||
but the deduplication code should deal with that. */
|
||||
if (ctxt)
|
||||
for (unsigned arg_idx = 0; arg_idx < cd.num_args (); arg_idx++)
|
||||
cd.get_arg_svalue (arg_idx);
|
||||
|
||||
/* Some of the cases below update the lhs of the call based on the
|
||||
return value, but not all. Provide a default value, which may
|
||||
get overwritten below. */
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/* Verify that we check for uninitialized values passed to functions
|
||||
that we have special-cased region-model handling for. */
|
||||
|
||||
extern void error (int __status, int __errnum, const char *__format, ...)
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||
|
||||
void test_uninit_status (int arg)
|
||||
{
|
||||
int st;
|
||||
error (st, 42, "test: %s", arg); /* { dg-warning "use of uninitialized value 'st'" } */
|
||||
}
|
||||
|
||||
void test_uninit_errnum (int st)
|
||||
{
|
||||
int num;
|
||||
error (st, num, "test"); /* { dg-warning "use of uninitialized value 'num'" } */
|
||||
}
|
||||
|
||||
void test_uninit_fmt (int st)
|
||||
{
|
||||
const char *fmt;
|
||||
error (st, 42, fmt); /* { dg-warning "use of uninitialized value 'fmt'" } */
|
||||
}
|
||||
|
||||
void test_uninit_vargs (int st)
|
||||
{
|
||||
int arg;
|
||||
error (st, 42, "test: %s", arg); /* { dg-warning "use of uninitialized value 'arg'" } */
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/* Verify that we check for uninitialized values passed to functions
|
||||
that we have special-cased state-machine handling for. */
|
||||
|
||||
int dup (int old_fd);
|
||||
int not_dup (int old_fd);
|
||||
|
||||
int
|
||||
test_1 ()
|
||||
{
|
||||
int m;
|
||||
return dup (m); /* { dg-warning "use of uninitialized value 'm'" "uninit" } */
|
||||
/* { dg-bogus "'dup' on possibly invalid file descriptor 'm'" "invalid fd false +ve" { xfail *-*-* } .-1 } */
|
||||
/* XFAIL: probably covered by fix for PR analyzer/106551. */
|
||||
}
|
||||
|
||||
int
|
||||
test_2 ()
|
||||
{
|
||||
int m;
|
||||
return not_dup (m); /* { dg-warning "use of uninitialized value 'm'" } */
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* Verify that we check for uninitialized values passed to functions
|
||||
that we have special-cased state-machine handling for. */
|
||||
|
||||
typedef struct FILE FILE;
|
||||
|
||||
FILE* fopen (const char*, const char*);
|
||||
int fclose (FILE*);
|
||||
int fseek (FILE *, long, int);
|
||||
|
||||
FILE *
|
||||
test_fopen_uninit_path (void)
|
||||
{
|
||||
const char *path;
|
||||
FILE *f = fopen (path, "r"); /* { dg-warning "use of uninitialized value 'path'" } */
|
||||
return f;
|
||||
}
|
||||
|
||||
FILE *
|
||||
test_fopen_uninit_mode (const char *path)
|
||||
{
|
||||
const char *mode;
|
||||
FILE *f = fopen (path, mode); /* { dg-warning "use of uninitialized value 'mode'" } */
|
||||
return f;
|
||||
}
|
||||
|
||||
void
|
||||
test_fclose_uninit (void)
|
||||
{
|
||||
FILE *f;
|
||||
fclose (f); /* { dg-warning "use of uninitialized value 'f'" } */
|
||||
}
|
||||
|
||||
int
|
||||
test_fseek_uninit_stream (void)
|
||||
{
|
||||
FILE *stream;
|
||||
return fseek (stream, 0, 0); /* { dg-warning "use of uninitialized value 'stream'" } */
|
||||
}
|
||||
|
||||
int
|
||||
test_fseek_uninit_offset (FILE *stream, int whence)
|
||||
{
|
||||
long offset;
|
||||
return fseek (stream, offset, whence); /* { dg-warning "use of uninitialized value 'offset'" } */
|
||||
}
|
||||
|
||||
int
|
||||
test_fseek_uninit_whence (FILE *stream, long offset)
|
||||
{
|
||||
int whence;
|
||||
return fseek (stream, offset, whence); /* { dg-warning "use of uninitialized value 'whence'" } */
|
||||
}
|
Loading…
Reference in New Issue