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:
David Malcolm 2022-08-09 19:58:54 -04:00
parent a56c1641e9
commit bddd8d86e3
4 changed files with 110 additions and 0 deletions

View File

@ -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. */

View File

@ -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'" } */
}

View File

@ -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'" } */
}

View File

@ -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'" } */
}