aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-01-31 12:05:03 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-01-31 14:29:09 -0500
commitf1c807e887d43551bca0acc16a438d880cfaf7c9 (patch)
tree78125ffde4cfce1245e23917660489a9d1561df7 /gcc
parent455f58ec50465aed9d92dc31d68708a05e499388 (diff)
downloadgcc-f1c807e887d43551bca0acc16a438d880cfaf7c9.zip
gcc-f1c807e887d43551bca0acc16a438d880cfaf7c9.tar.gz
gcc-f1c807e887d43551bca0acc16a438d880cfaf7c9.tar.bz2
analyzer: fix ICE getting void return value (PR 93379)
PR analyzer/93379 reports an ICE within region_model::update_for_return_superedge when writing the returned svalue_id to the lhs of the call_stmt The root cause is that this analyzer code assumed that for any call with a non-NULL gimple_call_lhs, the called fndecl would have non-void return type, and thus that a non-null svalue_id would be returned from region_model::pop_frame. This isn't the case e.g. for a call with conflicting types where the callee returns void but the caller assumes int. This patch fixes the ICE by moving the check for null result so that it also guards setting the lhs. gcc/analyzer/ChangeLog: PR analyzer/93379 * region-model.cc (region_model::update_for_return_superedge): Move check for null result so that it also guards setting the lhs. gcc/testsuite/ChangeLog: PR analyzer/93379 * gcc.dg/analyzer/torture/pr93379-2.c: New test. * gcc.dg/analyzer/torture/pr93379.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/analyzer/ChangeLog7
-rw-r--r--gcc/analyzer/region-model.cc5
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/torture/pr93379-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/torture/pr93379.c2
5 files changed, 30 insertions, 1 deletions
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 8806a77..fa791f7 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,5 +1,12 @@
2020-01-31 David Malcolm <dmalcolm@redhat.com>
+ PR analyzer/93379
+ * region-model.cc (region_model::update_for_return_superedge):
+ Move check for null result so that it also guards setting the
+ lhs.
+
+2020-01-31 David Malcolm <dmalcolm@redhat.com>
+
PR analyzer/93438
* region-model.cc (stack_region::can_merge_p): Split into a two
pass approach, creating all stack regions first, then populating
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index f116c0a..d43aef3 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -5694,12 +5694,15 @@ region_model::update_for_return_superedge (const return_superedge &return_edge,
svalue_id result_sid = pop_frame (true, &stats, ctxt);
// TODO: do something with the stats?
+ if (result_sid.null_p ())
+ return;
+
/* Set the result of the call, within the caller frame. */
const gcall *call_stmt = return_edge.get_call_stmt ();
tree lhs = gimple_call_lhs (call_stmt);
if (lhs)
set_value (get_lvalue (lhs, ctxt), result_sid, ctxt);
- else if (!result_sid.null_p ())
+ else
{
/* This could be a leak; try purging again, but this time,
don't special-case the result_sid. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f8051b44..cce52ea 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2020-01-31 David Malcolm <dmalcolm@redhat.com>
+ PR analyzer/93379
+ * gcc.dg/analyzer/torture/pr93379-2.c: New test.
+ * gcc.dg/analyzer/torture/pr93379.c: New test.
+
+2020-01-31 David Malcolm <dmalcolm@redhat.com>
+
PR analyzer/93438
* gcc.dg/analyzer/torture/pr93438.c: New test.
* gcc.dg/analyzer/torture/pr93438-2.c: New test.
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/pr93379-2.c b/gcc/testsuite/gcc.dg/analyzer/torture/pr93379-2.c
new file mode 100644
index 0000000..6e533db
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/pr93379-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-implicit-function-declaration" } */
+
+void foo (void)
+{
+ int i = actually_returns_void ();
+}
+
+void actually_returns_void (void) /* { dg-warning "conflicting types" } */
+{
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/pr93379.c b/gcc/testsuite/gcc.dg/analyzer/torture/pr93379.c
new file mode 100644
index 0000000..01465cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/pr93379.c
@@ -0,0 +1,2 @@
+/* { dg-do compile } */
+#include "../../torture/pr57330.c"