analyzer: fix ICE with OFFSET_TYPE [PR 93899]
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 24 Feb 2020 17:12:28 +0000 (12:12 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Mon, 24 Feb 2020 23:28:35 +0000 (18:28 -0500)
PR analyzer/93899 reports an ICE within make_region_for_type when
handling a param of type OFFSET_TYPE within
exploded_graph::add_function_entry.

This patch fixes the ICE by further generalizing the "give up on this
tree code" logic from
  r10-6667-gf76a88ebf089871dcce215aa0cb1956ccc060895
     for PR analyzer/93388 and
  r10-6695-g2e6233935c77b56a68e939c629702f960b8e6fb2
     for PR analyzer/93778
by replacing the gcc_unreachable in make_region_for_type with a return
of NULL, and handling this in add_region_for_type by notifying the ctxt.

Doing so means that numerous places that create regions now need to have
a context passed to them, so most of the patch is churn involved in
passing a context around to where it's needed.

gcc/analyzer/ChangeLog:
PR analyzer/93899
* engine.cc
(impl_region_model_context::impl_region_model_context): Add logger
param.
* engine.cc (exploded_graph::add_function_entry): Create an
impl_region_model_context and pass it to the push_frame call.
Bail if the resulting state is invalid.
(exploded_graph::build_initial_worklist): Likewise.
(exploded_graph::build_initial_worklist): Handle the case where
add_function_entry fails.
* exploded-graph.h
(impl_region_model_context::impl_region_model_context): Add logger
param.
* region-model.cc (map_region::get_or_create): Add ctxt param and
pass it to add_region_for_type.
(map_region::can_merge_p): Pass NULL as a ctxt to call to
get_or_create.
(array_region::get_element): Pass ctxt to call to get_or_create.
(array_region::get_or_create): Add ctxt param and pass it to
add_region_for_type.
(root_region::push_frame): Pass ctxt to get_or_create calls.
(region_model::get_lvalue_1): Likewise.
(region_model::make_region_for_unexpected_tree_code): Assert that
ctxt is non-NULL.
(region_model::get_rvalue_1): Pass ctxt to get_svalue_for_fndecl
and get_svalue_for_label calls.
(region_model::get_svalue_for_fndecl): Add ctxt param and pass it
to get_region_for_fndecl.
(region_model::get_region_for_fndecl): Add ctxt param and pass it
to get_or_create.
(region_model::get_svalue_for_label): Add ctxt param and pass it
to get_region_for_label.
(region_model::get_region_for_label): Add ctxt param and pass it
to get_region_for_fndecl and get_or_create.
(region_model::get_field_region): Add ctxt param and pass it to
get_or_create_view and get_or_create.
(make_region_for_type): Replace gcc_unreachable with return NULL.
(region_model::add_region_for_type): Add ctxt param.  Handle a
return of NULL from make_region_for_type by calling
make_region_for_unexpected_tree_code.
(region_model::get_or_create_mem_ref): Pass ctxt to calls to
get_or_create_view.
(region_model::get_or_create_view): Add ctxt param and pass it to
add_region_for_type.
(selftest::test_state_merging): Pass ctxt to get_or_create_view.
* region-model.h (region_model::get_or_create): Add ctxt param.
(region_model::add_region_for_type): Likewise.
(region_model::get_svalue_for_fndecl): Likewise.
(region_model::get_svalue_for_label): Likewise.
(region_model::get_region_for_fndecl): Likewise.
(region_model::get_region_for_label): Likewise.
(region_model::get_field_region): Likewise.
(region_model::get_or_create_view): Likewise.

gcc/testsuite/ChangeLog:
PR analyzer/93899
* g++.dg/analyzer/pr93899.C: New test.

gcc/analyzer/ChangeLog
gcc/analyzer/engine.cc
gcc/analyzer/exploded-graph.h
gcc/analyzer/region-model.cc
gcc/analyzer/region-model.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/analyzer/pr93899.C [new file with mode: 0644]

index bc70e88e814c446f4f819bb540d1c1b87320a455..0882ec6ac3abbc0b0cf45f4912bd23da86b42f02 100644 (file)
@@ -1,3 +1,59 @@
+2020-02-24  David Malcolm  <dmalcolm@redhat.com>
+
+       PR analyzer/93899
+       * engine.cc
+       (impl_region_model_context::impl_region_model_context): Add logger
+       param.
+       * engine.cc (exploded_graph::add_function_entry): Create an
+       impl_region_model_context and pass it to the push_frame call.
+       Bail if the resulting state is invalid.
+       (exploded_graph::build_initial_worklist): Likewise.
+       (exploded_graph::build_initial_worklist): Handle the case where
+       add_function_entry fails.
+       * exploded-graph.h
+       (impl_region_model_context::impl_region_model_context): Add logger
+       param.
+       * region-model.cc (map_region::get_or_create): Add ctxt param and
+       pass it to add_region_for_type.
+       (map_region::can_merge_p): Pass NULL as a ctxt to call to
+       get_or_create.
+       (array_region::get_element): Pass ctxt to call to get_or_create.
+       (array_region::get_or_create): Add ctxt param and pass it to
+       add_region_for_type.
+       (root_region::push_frame): Pass ctxt to get_or_create calls.
+       (region_model::get_lvalue_1): Likewise.
+       (region_model::make_region_for_unexpected_tree_code): Assert that
+       ctxt is non-NULL.
+       (region_model::get_rvalue_1): Pass ctxt to get_svalue_for_fndecl
+       and get_svalue_for_label calls.
+       (region_model::get_svalue_for_fndecl): Add ctxt param and pass it
+       to get_region_for_fndecl.
+       (region_model::get_region_for_fndecl): Add ctxt param and pass it
+       to get_or_create.
+       (region_model::get_svalue_for_label): Add ctxt param and pass it
+       to get_region_for_label.
+       (region_model::get_region_for_label): Add ctxt param and pass it
+       to get_region_for_fndecl and get_or_create.
+       (region_model::get_field_region): Add ctxt param and pass it to
+       get_or_create_view and get_or_create.
+       (make_region_for_type): Replace gcc_unreachable with return NULL.
+       (region_model::add_region_for_type): Add ctxt param.  Handle a
+       return of NULL from make_region_for_type by calling
+       make_region_for_unexpected_tree_code.
+       (region_model::get_or_create_mem_ref): Pass ctxt to calls to
+       get_or_create_view.
+       (region_model::get_or_create_view): Add ctxt param and pass it to
+       add_region_for_type.
+       (selftest::test_state_merging): Pass ctxt to get_or_create_view.
+       * region-model.h (region_model::get_or_create): Add ctxt param.
+       (region_model::add_region_for_type): Likewise.
+       (region_model::get_svalue_for_fndecl): Likewise.
+       (region_model::get_svalue_for_label): Likewise.
+       (region_model::get_region_for_fndecl): Likewise.
+       (region_model::get_region_for_label): Likewise.
+       (region_model::get_field_region): Likewise.
+       (region_model::get_or_create_view): Likewise.
+
 2020-02-24  David Malcolm  <dmalcolm@redhat.com>
 
        * checker-path.cc (superedge_event::should_filter_p): Update
index de6bf1d394fd63c6d44cf69e26fc58c8ebee6489..7f8a4223eed94e1e64eea9c12ef32fbd0cb0d578 100644 (file)
@@ -90,8 +90,9 @@ impl_region_model_context (exploded_graph &eg,
 impl_region_model_context::
 impl_region_model_context (program_state *state,
                           state_change *change,
-                          const extrinsic_state &ext_state)
-: m_eg (NULL), m_logger (NULL), m_enode_for_diag (NULL),
+                          const extrinsic_state &ext_state,
+                          logger *logger)
+: m_eg (NULL), m_logger (logger), m_enode_for_diag (NULL),
   m_old_state (NULL),
   m_new_state (state),
   m_change (change),
@@ -1829,7 +1830,11 @@ exploded_graph::add_function_entry (function *fun)
 {
   program_point point = program_point::from_function_entry (m_sg, fun);
   program_state state (m_ext_state);
-  state.m_region_model->push_frame (fun, NULL, NULL);
+  impl_region_model_context ctxt (&state, NULL, m_ext_state, get_logger ());
+  state.m_region_model->push_frame (fun, NULL, &ctxt);
+
+  if (!state.m_valid)
+    return NULL;
 
   exploded_node *enode = get_or_create_node (point, state, NULL);
   /* We should never fail to add such a node.  */
@@ -2150,8 +2155,13 @@ exploded_graph::build_initial_worklist ()
       continue;
     exploded_node *enode = add_function_entry (fun);
     if (logger)
-      logger->log ("created EN %i for %qE entrypoint",
-                  enode->m_index, fun->decl);
+      {
+       if (enode)
+         logger->log ("created EN %i for %qE entrypoint",
+                      enode->m_index, fun->decl);
+       else
+         logger->log ("did not create enode for %qE entrypoint", fun->decl);
+      }
   }
 }
 
index a851dd929c9d4fd186c5d5caf571081674671911..7c2612d7b85eeaf9e44fdefcffdecbbcdb0682be 100644 (file)
@@ -43,7 +43,8 @@ class impl_region_model_context : public region_model_context
 
   impl_region_model_context (program_state *state,
                             state_change *change,
-                            const extrinsic_state &ext_state);
+                            const extrinsic_state &ext_state,
+                            logger *logger = NULL);
 
   void warn (pending_diagnostic *d) FINAL OVERRIDE;
 
index d061552da379292728238d4964b29420e41da7f4..a71884d7b118699ca38de3a210064305cb29a1b5 100644 (file)
@@ -1660,20 +1660,22 @@ map_region::dump_child_label (const region_model &model,
    If it doesn't already exist, create a child map_region, using TYPE for
    its type.
    Return the region_id of the child (whether pre-existing, or
-   newly-created).  */
+   newly-created).
+   Notify CTXT if we don't know how to handle TYPE.  */
 
 region_id
 map_region::get_or_create (region_model *model,
                           region_id this_rid,
                           tree key,
-                          tree type)
+                          tree type,
+                          region_model_context *ctxt)
 {
   gcc_assert (key);
   gcc_assert (valid_key_p (key));
   region_id *slot = m_map.get (key);
   if (slot)
     return *slot;
-  region_id child_rid = model->add_region_for_type (this_rid, type);
+  region_id child_rid = model->add_region_for_type (this_rid, type, ctxt);
   m_map.put (key, child_rid);
   return child_rid;
 }
@@ -1906,7 +1908,8 @@ map_region::can_merge_p (const map_region *map_region_a,
            = merged_map_region->get_or_create (merger->m_merged_model,
                                                merged_rid,
                                                key_a,
-                                               child_region_a->get_type ());
+                                               child_region_a->get_type (),
+                                               NULL);
 
          region *child_merged_region
            = merger->m_merged_model->get_region (child_merged_rid);
@@ -2194,7 +2197,7 @@ region_id
 array_region::get_element (region_model *model,
                           region_id this_rid,
                           svalue_id index_sid,
-                          region_model_context *ctxt ATTRIBUTE_UNUSED)
+                          region_model_context *ctxt)
 {
   tree element_type = TREE_TYPE (get_type ());
   svalue *index_sval = model->get_svalue (index_sid);
@@ -2202,11 +2205,11 @@ array_region::get_element (region_model *model,
     {
       key_t key = key_from_constant (cst_index);
       region_id element_rid
-       = get_or_create (model, this_rid, key, element_type);
+       = get_or_create (model, this_rid, key, element_type, ctxt);
       return element_rid;
    }
 
-  return model->get_or_create_view (this_rid, element_type);
+  return model->get_or_create_view (this_rid, element_type, ctxt);
 }
 
 /* Implementation of region::clone vfunc for array_region.  */
@@ -2323,18 +2326,20 @@ array_region::dump_child_label (const region_model &model,
    If it doesn't already exist, create a child array_region, using TYPE for
    its type.
    Return the region_id of the child (whether pre-existing, or
-   newly-created).  */
+   newly-created).
+   Notify CTXT if we don't know how to handle TYPE.  */
 
 region_id
 array_region::get_or_create (region_model *model,
                             region_id this_rid,
                             key_t key,
-                            tree type)
+                            tree type,
+                            region_model_context *ctxt)
 {
   region_id *slot = m_map.get (key);
   if (slot)
     return *slot;
-  region_id child_rid = model->add_region_for_type (this_rid, type);
+  region_id child_rid = model->add_region_for_type (this_rid, type, ctxt);
   m_map.put (key, child_rid);
   return child_rid;
 }
@@ -2890,7 +2895,7 @@ root_region::push_frame (region_model *model, function *fun,
          svalue_id arg_sid = (*arg_sids)[idx];
          region_id parm_rid
            = region->get_or_create (model, frame_rid, iter_parm,
-                                    TREE_TYPE (iter_parm));
+                                    TREE_TYPE (iter_parm), ctxt);
          model->set_value (parm_rid, arg_sid, ctxt);
 
          /* Also do it for default SSA name (sharing the same unknown
@@ -2900,7 +2905,7 @@ root_region::push_frame (region_model *model, function *fun,
            {
              region_id defssa_rid
                = region->get_or_create (model, frame_rid, parm_default_ssa,
-                                        TREE_TYPE (iter_parm));
+                                        TREE_TYPE (iter_parm), ctxt);
              model->set_value (defssa_rid, arg_sid, ctxt);
            }
        }
@@ -2917,7 +2922,7 @@ root_region::push_frame (region_model *model, function *fun,
        {
          region_id parm_rid
            = region->get_or_create (model, frame_rid, iter_parm,
-                                    TREE_TYPE (iter_parm));
+                                    TREE_TYPE (iter_parm), ctxt);
          svalue_id parm_sid
            = model->set_to_new_unknown_value (parm_rid, TREE_TYPE (iter_parm),
                                               ctxt);
@@ -2929,7 +2934,7 @@ root_region::push_frame (region_model *model, function *fun,
            {
              region_id defssa_rid
                = region->get_or_create (model, frame_rid, parm_default_ssa,
-                                        TREE_TYPE (iter_parm));
+                                        TREE_TYPE (iter_parm), ctxt);
              model->get_region (defssa_rid)->set_value (*model, defssa_rid,
                                                         parm_sid, ctxt);
            }
@@ -4665,7 +4670,8 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt)
       {
        /* For now, create a view, as if a cast, ignoring the bit positions.  */
        tree obj = TREE_OPERAND (expr, 0);
-       return get_or_create_view (get_lvalue (obj, ctxt), TREE_TYPE (expr));
+       return get_or_create_view (get_lvalue (obj, ctxt), TREE_TYPE (expr),
+                                  ctxt);
       };
       break;
 
@@ -4688,7 +4694,7 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt)
            = get_root_region ()->ensure_globals_region (this);
          map_region *globals = get_region<map_region> (globals_rid);
          region_id var_rid = globals->get_or_create (this, globals_rid, expr,
-                                                     TREE_TYPE (expr));
+                                                     TREE_TYPE (expr), ctxt);
          return var_rid;
        }
 
@@ -4710,7 +4716,7 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt)
        frame_region *frame = get_region <frame_region> (frame_rid);
        gcc_assert (frame);
        region_id child_rid = frame->get_or_create (this, frame_rid, expr,
-                                                   TREE_TYPE (expr));
+                                                   TREE_TYPE (expr), ctxt);
        return child_rid;
       }
 
@@ -4726,15 +4732,15 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt)
                                                       dump_location_t ());
        region_id obj_rid = get_lvalue (obj, ctxt);
        region_id struct_or_union_rid
-         = get_or_create_view (obj_rid, TREE_TYPE (obj));
-       return get_field_region (struct_or_union_rid, field);
+         = get_or_create_view (obj_rid, TREE_TYPE (obj), ctxt);
+       return get_field_region (struct_or_union_rid, field, ctxt);
       }
       break;
 
     case CONST_DECL:
       {
        tree cst_type = TREE_TYPE (expr);
-       region_id cst_rid = add_region_for_type (m_root_rid, cst_type);
+       region_id cst_rid = add_region_for_type (m_root_rid, cst_type, ctxt);
        if (tree value = DECL_INITIAL (expr))
          {
            svalue_id sid = get_rvalue (value, ctxt);
@@ -4758,7 +4764,8 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt)
     case VIEW_CONVERT_EXPR:
       {
        tree obj = TREE_OPERAND (expr, 0);
-       return get_or_create_view (get_lvalue (obj, ctxt), TREE_TYPE (expr));
+       return get_or_create_view (get_lvalue (obj, ctxt), TREE_TYPE (expr),
+                                  ctxt);
       };
       break;
     }
@@ -4776,6 +4783,7 @@ region_model::make_region_for_unexpected_tree_code (region_model_context *ctxt,
                                                    tree t,
                                                    const dump_location_t &loc)
 {
+  gcc_assert (ctxt);
   region_id new_rid
     = add_region (new symbolic_region (m_root_rid, NULL_TREE, false));
   ctxt->on_unexpected_tree_code (t, loc);
@@ -4840,9 +4848,9 @@ region_model::get_rvalue_1 (path_var pv, region_model_context *ctxt)
        tree expr = pv.m_tree;
        tree op0 = TREE_OPERAND (expr, 0);
        if (TREE_CODE (op0) == FUNCTION_DECL)
-         return get_svalue_for_fndecl (TREE_TYPE (expr), op0);
+         return get_svalue_for_fndecl (TREE_TYPE (expr), op0, ctxt);
        else if (TREE_CODE (op0) == LABEL_DECL)
-         return get_svalue_for_label (TREE_TYPE (expr), op0);
+         return get_svalue_for_label (TREE_TYPE (expr), op0, ctxt);
        region_id expr_rid = get_lvalue (op0, ctxt);
        return get_or_create_ptr_svalue (TREE_TYPE (expr), expr_rid);
       }
@@ -4945,10 +4953,11 @@ region_model::get_or_create_constant_svalue (tree cst_expr)
    creating the function_region if necessary.  */
 
 svalue_id
-region_model::get_svalue_for_fndecl (tree ptr_type, tree fndecl)
+region_model::get_svalue_for_fndecl (tree ptr_type, tree fndecl,
+                                    region_model_context *ctxt)
 {
   gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
-  region_id function_rid = get_region_for_fndecl (fndecl);
+  region_id function_rid = get_region_for_fndecl (fndecl, ctxt);
   return get_or_create_ptr_svalue (ptr_type, function_rid);
 }
 
@@ -4956,24 +4965,27 @@ region_model::get_svalue_for_fndecl (tree ptr_type, tree fndecl)
    creating it if necessary.  */
 
 region_id
-region_model::get_region_for_fndecl (tree fndecl)
+region_model::get_region_for_fndecl (tree fndecl,
+                                    region_model_context *ctxt)
 {
   gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
 
   region_id code_rid = get_root_region ()->ensure_code_region (this);
   code_region *code = get_root_region ()->get_code_region (this);
 
-  return code->get_or_create (this, code_rid, fndecl, TREE_TYPE (fndecl));
+  return code->get_or_create (this, code_rid, fndecl, TREE_TYPE (fndecl),
+                             ctxt);
 }
 
 /* Return an svalue_id for a region_svalue for LABEL,
    creating the label_region if necessary.  */
 
 svalue_id
-region_model::get_svalue_for_label (tree ptr_type, tree label)
+region_model::get_svalue_for_label (tree ptr_type, tree label,
+                                   region_model_context *ctxt)
 {
   gcc_assert (TREE_CODE (label) == LABEL_DECL);
-  region_id label_rid = get_region_for_label (label);
+  region_id label_rid = get_region_for_label (label, ctxt);
   return get_or_create_ptr_svalue (ptr_type, label_rid);
 }
 
@@ -4981,16 +4993,18 @@ region_model::get_svalue_for_label (tree ptr_type, tree label)
    creating it if necessary.  */
 
 region_id
-region_model::get_region_for_label (tree label)
+region_model::get_region_for_label (tree label,
+                                   region_model_context *ctxt)
 {
   gcc_assert (TREE_CODE (label) == LABEL_DECL);
 
   tree fndecl = DECL_CONTEXT (label);
   gcc_assert (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL);
 
-  region_id func_rid = get_region_for_fndecl (fndecl);
+  region_id func_rid = get_region_for_fndecl (fndecl, ctxt);
   function_region *func_reg = get_region <function_region> (func_rid);
-  return func_reg->get_or_create (this, func_rid, label, TREE_TYPE (label));
+  return func_reg->get_or_create (this, func_rid, label, TREE_TYPE (label),
+                                 ctxt);
 }
 
 /* Build a cast of SRC_EXPR to DST_TYPE, or return NULL_TREE.
@@ -5124,7 +5138,8 @@ region_model::maybe_cast (tree dst_type, svalue_id sid,
    return the child region's region_id.  */
 
 region_id
-region_model::get_field_region (region_id struct_or_union_rid, tree field)
+region_model::get_field_region (region_id struct_or_union_rid, tree field,
+                               region_model_context *ctxt)
 {
   struct_or_union_region *sou_reg
     = get_region<struct_or_union_region> (struct_or_union_rid);
@@ -5141,7 +5156,7 @@ region_model::get_field_region (region_id struct_or_union_rid, tree field)
       /* Union.
         Get a view of the union as a whole, with the type of the field.  */
       region_id view_rid
-       = get_or_create_view (struct_or_union_rid, field_type_with_quals);
+       = get_or_create_view (struct_or_union_rid, field_type_with_quals, ctxt);
       return view_rid;
     }
   else
@@ -5149,7 +5164,7 @@ region_model::get_field_region (region_id struct_or_union_rid, tree field)
       /* Struct.  */
       region_id child_rid
        = sou_reg->get_or_create (this, struct_or_union_rid, field,
-                                 field_type_with_quals);
+                                 field_type_with_quals, ctxt);
       return child_rid;
     }
 }
@@ -6061,7 +6076,8 @@ region_model::get_region (region_id rid) const
 }
 
 /* Make a region of an appropriate subclass for TYPE,
-   with parent PARENT_RID.  */
+   with parent PARENT_RID, or return NULL for types we don't yet know
+   how to handle.  */
 
 static region *
 make_region_for_type (region_id parent_rid, tree type)
@@ -6091,18 +6107,24 @@ make_region_for_type (region_id parent_rid, tree type)
   if (VOID_TYPE_P (type))
     return new symbolic_region (parent_rid, type, false);
 
-  gcc_unreachable ();
+  return NULL;
 }
 
 /* Add a region with type TYPE and parent PARENT_RID.  */
 
 region_id
-region_model::add_region_for_type (region_id parent_rid, tree type)
+region_model::add_region_for_type (region_id parent_rid, tree type,
+                                  region_model_context *ctxt)
 {
   gcc_assert (TYPE_P (type));
 
-  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.  */
+  return make_region_for_unexpected_tree_code (ctxt, type,
+                                              dump_location_t ());
 }
 
 /* Helper class for region_model::purge_unused_svalues.  */
@@ -6581,7 +6603,7 @@ region_model::get_or_create_mem_ref (tree type,
       if (zerop (cst_sval->get_constant ()))
        {
          /* Handle the zero offset case.  */
-         return get_or_create_view (raw_rid, type);
+         return get_or_create_view (raw_rid, type, ctxt);
        }
 
       /* If we're already within an array of the correct type,
@@ -6622,7 +6644,7 @@ region_model::get_or_create_mem_ref (tree type,
                  region_id element_rid
                    = parent_array->get_element (this, raw_rid, index_sid,
                                                 ctxt);
-                 return get_or_create_view (element_rid, type);
+                 return get_or_create_view (element_rid, type, ctxt);
                }
            }
        }
@@ -6630,7 +6652,7 @@ region_model::get_or_create_mem_ref (tree type,
 
   tree array_type = build_array_type (TREE_TYPE (ptr_type),
                                      integer_type_node);
-  region_id array_view_rid = get_or_create_view (raw_rid, array_type);
+  region_id array_view_rid = get_or_create_view (raw_rid, array_type, ctxt);
   array_region *array_reg = get_region <array_region> (array_view_rid);
 
   svalue_id index_sid
@@ -6639,7 +6661,7 @@ region_model::get_or_create_mem_ref (tree type,
   region_id element_rid
     = array_reg->get_element (this, array_view_rid, index_sid, ctxt);
 
-  return get_or_create_view (element_rid, type);
+  return get_or_create_view (element_rid, type, ctxt);
 }
 
 /* Get a region of type TYPE for PTR_SID + OFFSET_SID.
@@ -6664,7 +6686,8 @@ region_model::get_or_create_pointer_plus_expr (tree type,
    Return the id of the view (or RAW_ID if it of the same type).  */
 
 region_id
-region_model::get_or_create_view (region_id raw_rid, tree type)
+region_model::get_or_create_view (region_id raw_rid, tree type,
+                                 region_model_context *ctxt)
 {
   region *raw_region = get_region (raw_rid);
 
@@ -6679,7 +6702,7 @@ region_model::get_or_create_view (region_id raw_rid, tree type)
 
       /* Otherwise, make one (adding it to the region_model and
         to the viewed region).  */
-      region_id view_rid = add_region_for_type (raw_rid, type);
+      region_id view_rid = add_region_for_type (raw_rid, type, ctxt);
       raw_region->add_view (view_rid, this);
       // TODO: something to signify that this is a "view"
       return view_rid;
@@ -8102,7 +8125,8 @@ test_state_merging ()
     region_model model0;
 
     region_id x_rid = model0.get_lvalue (x, &ctxt);
-    region_id x_as_ptr = model0.get_or_create_view (x_rid, ptr_type_node);
+    region_id x_as_ptr = model0.get_or_create_view (x_rid, ptr_type_node,
+                                                   &ctxt);
     model0.set_value (x_as_ptr, model0.get_rvalue (addr_of_y, &ctxt), &ctxt);
 
     region_model model1 (model0);
index 3b2b43b595fb69cd4cc2f0ac81bdbf089b389ac8..c185eb18d0b82f0f4aaa21b23aa0e646ccc26df4 100644 (file)
@@ -978,7 +978,8 @@ public:
 
   region_id get_or_create (region_model *model,
                           region_id this_rid,
-                          tree expr, tree type);
+                          tree expr, tree type,
+                          region_model_context *ctxt);
   void unbind (tree expr);
   region_id *get (tree expr);
 
@@ -1374,7 +1375,8 @@ public:
 
   region_id get_or_create (region_model *model,
                           region_id this_rid,
-                          key_t key, tree type);
+                          key_t key, tree type,
+                          region_model_context *ctxt);
 //  void unbind (int expr);
   region_id *get (key_t key);
 
@@ -1719,7 +1721,8 @@ class region_model
 
   region_id add_region (region *r);
 
-  region_id add_region_for_type (region_id parent_rid, tree type);
+  region_id add_region_for_type (region_id parent_rid, tree type,
+                                region_model_context *ctxt);
 
   svalue *get_svalue (svalue_id sval_id) const;
   region *get_region (region_id rid) const;
@@ -1740,16 +1743,19 @@ class region_model
 
   svalue_id get_or_create_ptr_svalue (tree ptr_type, region_id id);
   svalue_id get_or_create_constant_svalue (tree cst_expr);
-  svalue_id get_svalue_for_fndecl (tree ptr_type, tree fndecl);
-  svalue_id get_svalue_for_label (tree ptr_type, tree label);
+  svalue_id get_svalue_for_fndecl (tree ptr_type, tree fndecl,
+                                  region_model_context *ctxt);
+  svalue_id get_svalue_for_label (tree ptr_type, tree label,
+                                 region_model_context *ctxt);
 
-  region_id get_region_for_fndecl (tree fndecl);
-  region_id get_region_for_label (tree label);
+  region_id get_region_for_fndecl (tree fndecl, region_model_context *ctxt);
+  region_id get_region_for_label (tree label, region_model_context *ctxt);
 
   svalue_id maybe_cast (tree type, svalue_id sid, region_model_context *ctxt);
   svalue_id maybe_cast_1 (tree type, svalue_id sid);
 
-  region_id get_field_region (region_id rid, tree field);
+  region_id get_field_region (region_id rid, tree field,
+                             region_model_context *ctxt);
 
   region_id deref_rvalue (svalue_id ptr_sid, region_model_context *ctxt);
   region_id deref_rvalue (tree ptr, region_model_context *ctxt);
@@ -1826,7 +1832,8 @@ class region_model
                                             svalue_id ptr_sid,
                                             svalue_id offset_sid,
                                             region_model_context *ctxt);
-  region_id get_or_create_view (region_id raw_rid, tree type);
+  region_id get_or_create_view (region_id raw_rid, tree type,
+                               region_model_context *ctxt);
 
   tree get_fndecl_for_call (const gcall *call,
                            region_model_context *ctxt);
index fae86eb501e907e91c6d6b87b571e741119e7097..a2844a3b13ab025f7dde71f55a8809e4f263d429 100644 (file)
@@ -1,3 +1,8 @@
+2020-02-24  David Malcolm  <dmalcolm@redhat.com>
+
+       PR analyzer/93899
+       * g++.dg/analyzer/pr93899.C: New test.
+
 2020-02-24  Martin Sebor  <msebor@redhat.com>
 
        PR c++/93804
diff --git a/gcc/testsuite/g++.dg/analyzer/pr93899.C b/gcc/testsuite/g++.dg/analyzer/pr93899.C
new file mode 100644 (file)
index 0000000..12fe0a2
--- /dev/null
@@ -0,0 +1,2 @@
+// { dg-do compile { target c++11 } }
+#include "../abi/mangle55.C"