[gcc r11-7156] analyzer: support "_IO_"-prefixed variants of FILE * fns [PR98575]
David Malcolm
dmalcolm@gcc.gnu.org
Tue Feb 9 20:54:59 GMT 2021
https://gcc.gnu.org/g:790a8e8942b3f5a896ab5897cd209de1d9c382ae
commit r11-7156-g790a8e8942b3f5a896ab5897cd209de1d9c382ae
Author: David Malcolm <dmalcolm@redhat.com>
Date: Tue Feb 9 15:54:14 2021 -0500
analyzer: support "_IO_"-prefixed variants of FILE * fns [PR98575]
PR analyzer/98575 describes an unexpected -Wanalyzer-malloc-leak false
positive from gcc.dg/analyzer/pr94851-1.c on glibc < 2.28.
The issue is that a getchar call gets inlined into a call to _IO_getc,
and "_IO_getc" is not in the set of FILE * functions the analyzer
"knows about". This exposes a bug in memory leak detection on code
paths in which an unknown function has been called.
The memory leak bug is fixed in the prior commit, but for good
measure this patch special-cases the "_IO_"-prefixed names in glibc
so that the analyzer can reuse its knowledge about the unprefixed
variants.
gcc/analyzer/ChangeLog:
PR analyzer/98575
* sm-file.cc (is_file_using_fn_p): Support "_IO_"-prefixed
variants.
gcc/testsuite/ChangeLog:
PR analyzer/98575
* gcc.dg/analyzer/file-1.c (test_5): New.
* gcc.dg/analyzer/file-3.c: New test.
Diff:
---
gcc/analyzer/sm-file.cc | 11 ++++++++++-
gcc/testsuite/gcc.dg/analyzer/file-1.c | 7 +++++++
gcc/testsuite/gcc.dg/analyzer/file-3.c | 18 ++++++++++++++++++
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc
index aaa7ab28775..48ef4aa2334 100644
--- a/gcc/analyzer/sm-file.cc
+++ b/gcc/analyzer/sm-file.cc
@@ -307,7 +307,16 @@ static bool
is_file_using_fn_p (tree fndecl)
{
function_set fs = get_file_using_fns ();
- return fs.contains_decl_p (fndecl);
+ if (fs.contains_decl_p (fndecl))
+ return true;
+
+ /* Also support variants of these names prefixed with "_IO_". */
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
+ if (strncmp (name, "_IO_", 4) == 0)
+ if (fs.contains_name_p (name + 4))
+ return true;
+
+ return false;
}
/* Implementation of state_machine::on_stmt vfunc for fileptr_state_machine. */
diff --git a/gcc/testsuite/gcc.dg/analyzer/file-1.c b/gcc/testsuite/gcc.dg/analyzer/file-1.c
index f2b77b9db66..f9afa88f1e8 100644
--- a/gcc/testsuite/gcc.dg/analyzer/file-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/file-1.c
@@ -47,3 +47,10 @@ test_4 (const char *path)
return; /* { dg-warning "leak of FILE 'f'" } */
}
+
+void
+test_5 (const char *path)
+{
+ FILE *f = fopen (path, "r"); /* { dg-message "opened here" } */
+ return; /* { dg-warning "leak of FILE 'f'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/file-3.c b/gcc/testsuite/gcc.dg/analyzer/file-3.c
new file mode 100644
index 00000000000..8f93a986deb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/file-3.c
@@ -0,0 +1,18 @@
+typedef struct _IO_FILE FILE;
+extern struct _IO_FILE *stderr;
+
+extern FILE *fopen (const char *__restrict __filename,
+ const char *__restrict __modes);
+extern int _IO_getc (FILE *stream);
+
+void
+test_1 (const char *path)
+{
+ FILE *f = fopen (path, "r"); /* { dg-message "opened here" } */
+
+ /* Implementation of getc in glibc < 2.28.
+ Verify that we know that this doesn't close the file. */
+ _IO_getc (f);
+
+ return; /* { dg-warning "leak of FILE 'f'" } */
+}
More information about the Gcc-cvs
mailing list