c++: Fix null this pointer [PR 98624]
authorNathan Sidwell <nathan@acm.org>
Thu, 21 Jan 2021 18:37:23 +0000 (10:37 -0800)
committerNathan Sidwell <nathan@acm.org>
Thu, 21 Jan 2021 18:41:35 +0000 (10:41 -0800)
One may not use a null this pointer to invoke a static member
function.  This fixes the remaining ubsan errors found with an
ubsan bootstrap.

PR c++/98624
gcc/cp/
* module.cc (depset::hash::find_dependencies): Add
module arg.
(trees_out::core_vals): Check state before calling
write_location.
(sort_cluster, module_state::write): Adjust
find_dependencies call.

gcc/cp/module.cc

index 7f88e3fea896084fd2aeeaa081f491d517cd97f0..18f5de8724b5d92b277e6630f5d2bb3faa156a97 100644 (file)
@@ -2564,7 +2564,7 @@ public:
     void add_class_entities (vec<tree, va_gc> *);
 
   public:    
-    void find_dependencies ();
+    void find_dependencies (module_state *);
     bool finalize_dependencies ();
     vec<depset *> connect ();
   };
@@ -5895,7 +5895,8 @@ trees_out::core_vals (tree t)
       if (!DECL_TEMPLATE_PARM_P (t))
        WT (t->decl_minimal.context);
 
-      state->write_location (*this, t->decl_minimal.locus);
+      if (state)
+       state->write_location (*this, t->decl_minimal.locus);
     }
 
   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
@@ -5998,7 +5999,8 @@ trees_out::core_vals (tree t)
 
   if (CODE_CONTAINS_STRUCT (code, TS_EXP))
     {
-      state->write_location (*this, t->exp.locus);
+      if (state)
+       state->write_location (*this, t->exp.locus);
 
       /* Walk in forward order, as (for instance) REQUIRES_EXPR has a
          bunch of unscoped parms on its first operand.  It's safer to
@@ -6137,9 +6139,12 @@ trees_out::core_vals (tree t)
 
       /* Miscellaneous common nodes.  */
     case BLOCK:
-      state->write_location (*this, t->block.locus);
-      state->write_location (*this, t->block.end_locus);
-      
+      if (state)
+       {
+         state->write_location (*this, t->block.locus);
+         state->write_location (*this, t->block.end_locus);
+       }
+
       /* DECL_LOCAL_DECL_P decls are first encountered here and
          streamed by value.  */
       chained_decls (t->block.vars);
@@ -6180,7 +6185,8 @@ trees_out::core_vals (tree t)
        /* The ompcode is serialized in start.  */
        if (streaming_p ())
          WU (t->omp_clause.subcode.map_kind);
-       state->write_location (*this, t->omp_clause.locus);
+       if (state)
+         state->write_location (*this, t->omp_clause.locus);
 
        unsigned len = omp_clause_num_ops[OMP_CLAUSE_CODE (t)];
        for (unsigned ix = 0; ix != len; ix++)
@@ -6267,8 +6273,9 @@ trees_out::core_vals (tree t)
       WT (((lang_tree_node *)t)->lambda_expression.extra_scope);
       /* pending_proxies is a parse-time thing.  */
       gcc_assert (!((lang_tree_node *)t)->lambda_expression.pending_proxies);
-      state->write_location
-       (*this, ((lang_tree_node *)t)->lambda_expression.locus);
+      if (state)
+       state->write_location
+         (*this, ((lang_tree_node *)t)->lambda_expression.locus);
       if (streaming_p ())
        {
          WU (((lang_tree_node *)t)->lambda_expression.default_capture_mode);
@@ -6288,8 +6295,9 @@ trees_out::core_vals (tree t)
     case STATIC_ASSERT:
       WT (((lang_tree_node *)t)->static_assertion.condition);
       WT (((lang_tree_node *)t)->static_assertion.message);
-      state->write_location
-       (*this, ((lang_tree_node *)t)->static_assertion.location);
+      if (state)
+       state->write_location
+         (*this, ((lang_tree_node *)t)->static_assertion.location);
       break;
 
     case TEMPLATE_DECL:
@@ -6321,7 +6329,8 @@ trees_out::core_vals (tree t)
                WT (m.binfo);
                WT (m.decl);
                WT (m.diag_decl);
-               state->write_location (*this, m.loc);
+               if (state)
+                 state->write_location (*this, m.loc);
              }
          }
       }
@@ -13156,9 +13165,9 @@ depset::hash::add_mergeable (depset *mergeable)
    entries on the same binding that need walking.  */
 
 void
-depset::hash::find_dependencies ()
+depset::hash::find_dependencies (module_state *module)
 {
-  trees_out walker (NULL, NULL, *this);
+  trees_out walker (NULL, module, *this);
   vec<depset *> unreached;
   unreached.create (worklist.length ());
 
@@ -13544,7 +13553,7 @@ sort_cluster (depset::hash *original, depset *scc[], unsigned size)
   gcc_checking_assert (use_lwm <= bind_lwm);
   dump (dumper::MERGE) && dump ("Ordering %u/%u depsets", use_lwm, size);
 
-  table.find_dependencies ();
+  table.find_dependencies (nullptr);
 
   vec<depset *> order = table.connect ();
   gcc_checking_assert (order.length () == use_lwm);
@@ -17568,7 +17577,7 @@ module_state::write (elf_out *to, cpp_reader *reader)
     }
 
   /* Now join everything up.  */
-  table.find_dependencies ();
+  table.find_dependencies (this);
 
   if (!table.finalize_dependencies ())
     {