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 --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 ();
+}
-- 
2.21.0

Reply via email to