diff mbox series

[committed] analyzer: fix ICE copying struct [PR 94816]

Message ID 20200428175301.31620-1-dmalcolm@redhat.com
State New
Headers show
Series [committed] analyzer: fix ICE copying struct [PR 94816] | expand

Commit Message

David Malcolm April 28, 2020, 5:53 p.m. UTC
PR analyzer/94816 reports an ICE when attempting to copy a struct
containing a field for which add_region_for_type for fails (on
an OFFSET_TYPE): the region for the src field comes from
make_region_for_unexpected_tree_code which gives it a NULL type, and
then the copy calls add_region_for_type which unconditionally
dereferences the NULL type.

This patch fixes the ICE by checking for NULL types in
add_region_for_type.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to master as r10-8015-g5eae0ac76dcb6aac1d1d6c4edd8852e0035792e4
 
gcc/analyzer/ChangeLog:
	PR analyzer/94816
	* engine.cc (impl_region_model_context::on_unexpected_tree_code):
	Handle NULL tree.
	* region-model.cc (region_model::add_region_for_type): Handle
	NULL type.
	* region-model.h
	(test_region_model_context::on_unexpected_tree_code): Handle NULL
	tree.

gcc/testsuite/ChangeLog:
	PR analyzer/94816
	* g++.dg/analyzer/pr94816.C: New test.
---
 gcc/analyzer/engine.cc                  |  2 +-
 gcc/analyzer/region-model.cc            |  9 ++++++---
 gcc/analyzer/region-model.h             |  2 +-
 gcc/testsuite/g++.dg/analyzer/pr94816.C | 13 +++++++++++++
 4 files changed, 21 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/analyzer/pr94816.C
diff mbox series

Patch

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 880e70fb2ba..c73d493a3d8 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -699,7 +699,7 @@  impl_region_model_context::on_unexpected_tree_code (tree t,
   logger * const logger = get_logger ();
   if (logger)
     logger->log ("unhandled tree code: %qs in %qs at %s:%i",
-		 get_tree_code_name (TREE_CODE (t)),
+		 t ? get_tree_code_name (TREE_CODE (t)) : "(null)",
 		 loc.get_impl_location ().m_function,
 		 loc.get_impl_location ().m_file,
 		 loc.get_impl_location ().m_line);
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 22049a34d29..0794be9a583 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -6448,10 +6448,13 @@  region_id
 region_model::add_region_for_type (region_id parent_rid, tree type,
 				   region_model_context *ctxt)
 {
-  gcc_assert (TYPE_P (type));
+  if (type)
+    {
+      gcc_assert (TYPE_P (type));
 
-  if (region *new_region = make_region_for_type (parent_rid, type))
-    return add_region (new_region);
+      if (region *new_region = make_region_for_type (parent_rid, type))
+	return add_region (new_region);
+    }
 
   /* If we can't handle TYPE, return a placeholder region, and stop
      exploring this path.  */
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index ad3dd1d13ef..6d427c4c654 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -2205,7 +2205,7 @@  public:
     FINAL OVERRIDE
   {
     internal_error ("unhandled tree code: %qs",
-		    get_tree_code_name (TREE_CODE (t)));
+		    t ? get_tree_code_name (TREE_CODE (t)) : "(null)");
   }
 
 private:
diff --git a/gcc/testsuite/g++.dg/analyzer/pr94816.C b/gcc/testsuite/g++.dg/analyzer/pr94816.C
new file mode 100644
index 00000000000..e241a44e376
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/pr94816.C
@@ -0,0 +1,13 @@ 
+/* { dg-additional-options "-O" } */
+
+struct jr;
+
+struct ch {
+  int jr::*rx;
+};
+
+ch
+ad ()
+{
+  return ch ();
+}