aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-09-16 13:12:39 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2020-09-16 18:56:50 -0400
commite097c9ab83192fc2f738ec6426a275282e9a51ea (patch)
treef50440aa428bda9f922ee6871aec460eb9043031
parent3f4b15f52f4d5f202a7f27bdbb41a8fff218d323 (diff)
downloadgcc-e097c9ab83192fc2f738ec6426a275282e9a51ea.zip
gcc-e097c9ab83192fc2f738ec6426a275282e9a51ea.tar.gz
gcc-e097c9ab83192fc2f738ec6426a275282e9a51ea.tar.bz2
analyzer: getchar has no side-effects
Seen whilst debugging another issue, where the analyzer was assuming conservatively that a call to getchar could clobber a global. This is handled for most of the other stdio functions by the list in sm-file.cc gcc/analyzer/ChangeLog: * region-model.cc (region_model::on_call_pre): Treat getchar as having no side-effects. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/getchar-1.c: New test.
-rw-r--r--gcc/analyzer/region-model.cc5
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/getchar-1.c19
2 files changed, 24 insertions, 0 deletions
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index d53272e..1312391 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -732,6 +732,11 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt)
return impl_call_calloc (cd);
else if (is_named_call_p (callee_fndecl, "alloca", call, 1))
return impl_call_alloca (cd);
+ else if (is_named_call_p (callee_fndecl, "getchar", call, 0))
+ {
+ /* No side-effects (tracking stream state is out-of-scope
+ for the analyzer). */
+ }
else if (is_named_call_p (callee_fndecl, "memset", call, 3))
{
impl_call_memset (cd);
diff --git a/gcc/testsuite/gcc.dg/analyzer/getchar-1.c b/gcc/testsuite/gcc.dg/analyzer/getchar-1.c
new file mode 100644
index 0000000..25595e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/getchar-1.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include "analyzer-decls.h"
+
+int test_1 (void)
+{
+ int c = getchar ();
+ return c;
+}
+
+int glob_2;
+int test_2 (void)
+{
+ int c;
+ glob_2 = 42;
+ __analyzer_eval (glob_2 == 42); /* { dg-warning "TRUE" } */
+ c = getchar ();
+ __analyzer_eval (glob_2 == 42); /* { dg-warning "TRUE" } */
+ return c;
+}