public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-1563] Convert label_text to C++11 move semantics
@ 2022-07-07 19:56 David Malcolm
  0 siblings, 0 replies; only message in thread
From: David Malcolm @ 2022-07-07 19:56 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a8dce13c076019688f6d6aaaa338a2911022b336

commit r13-1563-ga8dce13c076019688f6d6aaaa338a2911022b336
Author: David Malcolm <dmalcolm@redhat.com>
Date:   Thu Jul 7 15:50:26 2022 -0400

    Convert label_text to C++11 move semantics
    
    libcpp's class label_text stores a char * for a string and a flag saying
    whether it owns the buffer.  I added this class before we could use
    C++11, and so to avoid lots of copying it required an explicit call
    to label_text::maybe_free to potentially free the buffer.
    
    Now that we can use C++11, this patch removes label_text::maybe_free in
    favor of doing the cleanup in the destructor, and using C++ move
    semantics to avoid any copying.  This allows lots of messy cleanup code
    to be eliminated in favor of implicit destruction (mostly in the
    analyzer).
    
    No functional change intended.
    
    gcc/analyzer/ChangeLog:
            * call-info.cc (call_info::print): Update for removal of
            label_text::maybe_free in favor of automatic memory management.
            * checker-path.cc (checker_event::dump): Likewise.
            (checker_event::prepare_for_emission): Likewise.
            (state_change_event::get_desc): Likewise.
            (superedge_event::should_filter_p): Likewise.
            (start_cfg_edge_event::get_desc): Likewise.
            (warning_event::get_desc): Likewise.
            (checker_path::dump): Likewise.
            (checker_path::debug): Likewise.
            * diagnostic-manager.cc
            (diagnostic_manager::prune_for_sm_diagnostic): Likewise.
            (diagnostic_manager::prune_interproc_events): Likewise.
            * program-state.cc (sm_state_map::to_json): Likewise.
            * region.cc (region::to_json): Likewise.
            * sm-malloc.cc (inform_nonnull_attribute): Likewise.
            * store.cc (binding_map::to_json): Likewise.
            (store::to_json): Likewise.
            * svalue.cc (svalue::to_json): Likewise.
    
    gcc/c-family/ChangeLog:
            * c-format.cc (range_label_for_format_type_mismatch::get_text):
            Update for removal of label_text::maybe_free in favor of automatic
            memory management.
    
    gcc/ChangeLog:
            * diagnostic-format-json.cc (json_from_location_range): Update for
            removal of label_text::maybe_free in favor of automatic memory
            management.
            * diagnostic-format-sarif.cc
            (sarif_builder::make_location_object): Likewise.
            * diagnostic-show-locus.cc (struct pod_label_text): New.
            (class line_label): Convert m_text from label_text to pod_label_text.
            (layout::print_any_labels): Move "text" to the line_label.
            * tree-diagnostic-path.cc (path_label::get_text): Update for
            removal of label_text::maybe_free in favor of automatic memory
            management.
            (event_range::print): Likewise.
            (default_tree_diagnostic_path_printer): Likewise.
            (default_tree_make_json_for_path): Likewise.
    
    libcpp/ChangeLog:
            * include/line-map.h: Include <utility>.
            (class label_text): Delete maybe_free method in favor of a
            destructor.  Add move ctor and assignment operator.  Add deletion
            of the copy ctor and copy-assignment operator.  Rename field
            m_caller_owned to m_owned.  Add std::move where necessary; add
            moved_from member function.
    
    Signed-off-by: David Malcolm <dmalcolm@redhat.com>

Diff:
---
 gcc/analyzer/call-info.cc          |  1 -
 gcc/analyzer/checker-path.cc       | 97 +++++++++++++-------------------------
 gcc/analyzer/diagnostic-manager.cc |  8 ----
 gcc/analyzer/program-state.cc      |  1 -
 gcc/analyzer/region.cc             |  1 -
 gcc/analyzer/sm-malloc.cc          |  3 --
 gcc/analyzer/store.cc              |  3 --
 gcc/analyzer/svalue.cc             |  1 -
 gcc/c-family/c-format.cc           |  1 -
 gcc/diagnostic-format-json.cc      |  4 +-
 gcc/diagnostic-format-sarif.cc     |  1 -
 gcc/diagnostic-show-locus.cc       | 35 ++++++++++++--
 gcc/tree-diagnostic-path.cc        |  4 --
 libcpp/include/line-map.h          | 46 ++++++++++++++----
 14 files changed, 101 insertions(+), 105 deletions(-)

diff --git a/gcc/analyzer/call-info.cc b/gcc/analyzer/call-info.cc
index b3ff51e7460..e1142d743a3 100644
--- a/gcc/analyzer/call-info.cc
+++ b/gcc/analyzer/call-info.cc
@@ -76,7 +76,6 @@ call_info::print (pretty_printer *pp) const
 {
   label_text desc (get_desc (pp_show_color (pp)));
   pp_string (pp, desc.m_buffer);
-  desc.maybe_free ();
 }
 
 /* Implementation of custom_edge_info::add_events_to_path vfunc for
diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index 953e192cd55..959ffdd853c 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -196,7 +196,6 @@ checker_event::dump (pretty_printer *pp) const
   label_text event_desc (get_desc (false));
   pp_printf (pp, "\"%s\" (depth %i",
 	     event_desc.m_buffer, m_effective_depth);
-  event_desc.maybe_free ();
 
   if (m_effective_depth != m_original_depth)
     pp_printf (pp, " corrected from %i",
@@ -235,7 +234,6 @@ checker_event::prepare_for_emission (checker_path *,
   m_emission_id = emission_id;
 
   label_text desc = get_desc (false);
-  desc.maybe_free ();
 }
 
 /* class debug_event : public checker_event.  */
@@ -402,9 +400,8 @@ state_change_event::get_desc (bool can_colorize) const
 	      meaning.dump_to_pp (&meaning_pp);
 
 	      /* Append debug version.  */
-	      label_text result;
 	      if (m_origin)
-		result = make_label_text
+		return make_label_text
 		  (can_colorize,
 		   "%s (state of %qE: %qs -> %qs, origin: %qE, meaning: %s)",
 		   custom_desc.m_buffer,
@@ -414,7 +411,7 @@ state_change_event::get_desc (bool can_colorize) const
 		   origin,
 		   pp_formatted_text (&meaning_pp));
 	      else
-		result = make_label_text
+		return make_label_text
 		  (can_colorize,
 		   "%s (state of %qE: %qs -> %qs, NULL origin, meaning: %s)",
 		   custom_desc.m_buffer,
@@ -422,9 +419,6 @@ state_change_event::get_desc (bool can_colorize) const
 		   m_from->get_name (),
 		   m_to->get_name (),
 		   pp_formatted_text (&meaning_pp));
-
-	      custom_desc.maybe_free ();
-	      return result;
 	    }
 	  else
 	    return custom_desc;
@@ -435,28 +429,24 @@ state_change_event::get_desc (bool can_colorize) const
   if (m_sval)
     {
       label_text sval_desc = m_sval->get_desc ();
-      label_text result;
       if (m_origin)
 	{
 	  label_text origin_desc = m_origin->get_desc ();
-	  result = make_label_text
+	  return make_label_text
 	    (can_colorize,
 	     "state of %qs: %qs -> %qs (origin: %qs)",
 	     sval_desc.m_buffer,
 	     m_from->get_name (),
 	     m_to->get_name (),
 	     origin_desc.m_buffer);
-	  origin_desc.maybe_free ();
 	}
       else
-	result = make_label_text
+	return make_label_text
 	  (can_colorize,
 	   "state of %qs: %qs -> %qs (NULL origin)",
 	   sval_desc.m_buffer,
 	   m_from->get_name (),
 	   m_to->get_name ());
-      sval_desc.maybe_free ();
-      return result;
     }
   else
     {
@@ -522,7 +512,6 @@ superedge_event::should_filter_p (int verbosity) const
 	    gcc_assert (desc.m_buffer);
 	    if (desc.m_buffer[0] == '\0')
 	      return true;
-	    desc.maybe_free ();
 	  }
       }
       break;
@@ -605,56 +594,39 @@ label_text
 start_cfg_edge_event::get_desc (bool can_colorize) const
 {
   bool user_facing = !flag_analyzer_verbose_edges;
-  char *edge_desc = m_sedge->get_description (user_facing);
+  label_text edge_desc
+    = label_text::take (m_sedge->get_description (user_facing));
   if (user_facing)
     {
-      if (edge_desc && strlen (edge_desc) > 0)
+      if (edge_desc.m_buffer && strlen (edge_desc.m_buffer) > 0)
 	{
 	  label_text cond_desc = maybe_describe_condition (can_colorize);
 	  label_text result;
 	  if (cond_desc.m_buffer)
-	    {
-	      result = make_label_text (can_colorize,
-					"following %qs branch (%s)...",
-					edge_desc, cond_desc.m_buffer);
-	      cond_desc.maybe_free ();
-	    }
+	    return make_label_text (can_colorize,
+				    "following %qs branch (%s)...",
+				    edge_desc.m_buffer, cond_desc.m_buffer);
 	  else
-	    {
-	      result = make_label_text (can_colorize,
-					"following %qs branch...",
-					edge_desc);
-	    }
-	  free (edge_desc);
-	  return result;
+	    return make_label_text (can_colorize,
+				    "following %qs branch...",
+				    edge_desc.m_buffer);
 	}
       else
-	{
-	  free (edge_desc);
-	  return label_text::borrow ("");
-	}
+	return label_text::borrow ("");
     }
   else
     {
-      if (strlen (edge_desc) > 0)
-	{
-	  label_text result
-	    = make_label_text (can_colorize,
-			       "taking %qs edge SN:%i -> SN:%i",
-			       edge_desc,
-			       m_sedge->m_src->m_index,
-			       m_sedge->m_dest->m_index);
-	  free (edge_desc);
-	  return result;
-	}
+      if (strlen (edge_desc.m_buffer) > 0)
+	return make_label_text (can_colorize,
+				"taking %qs edge SN:%i -> SN:%i",
+				edge_desc.m_buffer,
+				m_sedge->m_src->m_index,
+				m_sedge->m_dest->m_index);
       else
-	{
-	  free (edge_desc);
-	  return make_label_text (can_colorize,
-				  "taking edge SN:%i -> SN:%i",
-				  m_sedge->m_src->m_index,
-				  m_sedge->m_dest->m_index);
-	}
+	return make_label_text (can_colorize,
+				"taking edge SN:%i -> SN:%i",
+				m_sedge->m_src->m_index,
+				m_sedge->m_dest->m_index);
     }
 }
 
@@ -1138,19 +1110,16 @@ warning_event::get_desc (bool can_colorize) const
 	{
 	  if (m_sm && flag_analyzer_verbose_state_changes)
 	    {
-	      label_text result;
 	      if (var)
-		result = make_label_text (can_colorize,
-					  "%s (%qE is in state %qs)",
-					  ev_desc.m_buffer,
-					  var, m_state->get_name ());
+		return make_label_text (can_colorize,
+					"%s (%qE is in state %qs)",
+					ev_desc.m_buffer,
+					var, m_state->get_name ());
 	      else
-		result = make_label_text (can_colorize,
-					  "%s (in global state %qs)",
-					  ev_desc.m_buffer,
-					  m_state->get_name ());
-	      ev_desc.maybe_free ();
-	      return result;
+		return make_label_text (can_colorize,
+					"%s (in global state %qs)",
+					ev_desc.m_buffer,
+					m_state->get_name ());
 	    }
 	  else
 	    return ev_desc;
@@ -1196,7 +1165,6 @@ checker_path::dump (pretty_printer *pp) const
 	pp_string (pp, ", ");
       label_text event_desc (e->get_desc (false));
       pp_printf (pp, "\"%s\"", event_desc.m_buffer);
-      event_desc.maybe_free ();
     }
   pp_character (pp, ']');
 }
@@ -1237,7 +1205,6 @@ checker_path::debug () const
 	       i,
 	       event_kind_to_string (m_events[i]->m_kind),
 	       event_desc.m_buffer);
-      event_desc.maybe_free ();
     }
 }
 
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index 4adfda1af65..083f66bd739 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -2298,7 +2298,6 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
 		  log ("considering event %i (%s), with sval: %qs, state: %qs",
 		       idx, event_kind_to_string (base_event->m_kind),
 		       sval_desc.m_buffer, state->get_name ());
-		  sval_desc.maybe_free ();
 		}
 	      else
 		log ("considering event %i (%s), with global state: %qs",
@@ -2366,8 +2365,6 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
 			     " switching var of interest from %qs to %qs",
 			     idx, sval_desc.m_buffer,
 			     origin_sval_desc.m_buffer);
-			sval_desc.maybe_free ();
-			origin_sval_desc.maybe_free ();
 		      }
 		    sval = state_change->m_origin;
 		  }
@@ -2395,7 +2392,6 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
 			else
 			  log ("filtering event %i: state change to %qs",
 			       idx, change_sval_desc.m_buffer);
-			change_sval_desc.maybe_free ();
 		      }
 		    else
 		      log ("filtering event %i: global state change", idx);
@@ -2465,7 +2461,6 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
 			 " recording critical state for %qs at call"
 			 " from %qE in callee to %qE in caller",
 			 idx, sval_desc.m_buffer, callee_var, caller_var);
-		    sval_desc.maybe_free ();
 		  }
 		if (expr.param_p ())
 		  event->record_critical_state (caller_var, state);
@@ -2509,7 +2504,6 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
 			     " recording critical state for %qs at return"
 			     " from %qE in caller to %qE in callee",
 			     idx, sval_desc.m_buffer, callee_var, callee_var);
-			sval_desc.maybe_free ();
 		      }
 		    if (expr.return_value_p ())
 		      event->record_critical_state (callee_var, state);
@@ -2593,7 +2587,6 @@ diagnostic_manager::prune_interproc_events (checker_path *path) const
 		  log ("filtering events %i-%i:"
 		       " irrelevant call/entry/return: %s",
 		       idx, idx + 2, desc.m_buffer);
-		  desc.maybe_free ();
 		}
 	      path->delete_event (idx + 2);
 	      path->delete_event (idx + 1);
@@ -2616,7 +2609,6 @@ diagnostic_manager::prune_interproc_events (checker_path *path) const
 		  log ("filtering events %i-%i:"
 		       " irrelevant call/return: %s",
 		       idx, idx + 1, desc.m_buffer);
-		  desc.maybe_free ();
 		}
 	      path->delete_event (idx + 1);
 	      path->delete_event (idx);
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 295c6aeb185..90a56e3fba4 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -301,7 +301,6 @@ sm_state_map::to_json () const
 
       label_text sval_desc = sval->get_desc ();
       map_obj->set (sval_desc.m_buffer, e.m_state->to_json ());
-      sval_desc.maybe_free ();
 
       /* This doesn't yet JSONify e.m_origin.  */
     }
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index a8286231d30..5b00e6a5f46 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -590,7 +590,6 @@ region::to_json () const
 {
   label_text desc = get_desc (true);
   json::value *reg_js = new json::string (desc.m_buffer);
-  desc.maybe_free ();
   return reg_js;
 }
 
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index 3bd40425919..553fcd80085 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -1008,7 +1008,6 @@ inform_nonnull_attribute (tree fndecl, int arg_idx)
   inform (DECL_SOURCE_LOCATION (fndecl),
 	  "argument %s of %qD must be non-null",
 	  arg_desc.m_buffer, fndecl);
-  arg_desc.maybe_free ();
   /* Ideally we would use the location of the parm and underline the
      attribute also - but we don't have the location_t values at this point
      in the middle-end.
@@ -1072,7 +1071,6 @@ public:
       result = ev.formatted_print ("argument %s (%qE) could be NULL"
 				   " where non-null expected",
 				   arg_desc.m_buffer, ev.m_expr);
-    arg_desc.maybe_free ();
     return result;
   }
 
@@ -1180,7 +1178,6 @@ public:
       result = ev.formatted_print ("argument %s (%qE) NULL"
 				   " where non-null expected",
 				   arg_desc.m_buffer, ev.m_expr);
-    arg_desc.maybe_free ();
     return result;
   }
 
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 1b7c818051b..d558d477115 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -676,7 +676,6 @@ binding_map::to_json () const
       const svalue *value = *const_cast <map_t &> (m_map).get (key);
       label_text key_desc = key->get_desc ();
       map_obj->set (key_desc.m_buffer, value->to_json ());
-      key_desc.maybe_free ();
     }
 
   return map_obj;
@@ -2405,11 +2404,9 @@ store::to_json () const
 	  label_text base_reg_desc = base_reg->get_desc ();
 	  clusters_in_parent_reg_obj->set (base_reg_desc.m_buffer,
 					   cluster->to_json ());
-	  base_reg_desc.maybe_free ();
 	}
       label_text parent_reg_desc = parent_reg->get_desc ();
       store_obj->set (parent_reg_desc.m_buffer, clusters_in_parent_reg_obj);
-      parent_reg_desc.maybe_free ();
     }
 
   store_obj->set ("called_unknown_fn", new json::literal (m_called_unknown_fn));
diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc
index 7bad3cea31b..78a6eeff05f 100644
--- a/gcc/analyzer/svalue.cc
+++ b/gcc/analyzer/svalue.cc
@@ -97,7 +97,6 @@ svalue::to_json () const
 {
   label_text desc = get_desc (true);
   json::value *sval_js = new json::string (desc.m_buffer);
-  desc.maybe_free ();
   return sval_js;
 }
 
diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc
index 754780446ba..2faed0c1607 100644
--- a/gcc/c-family/c-format.cc
+++ b/gcc/c-family/c-format.cc
@@ -4625,7 +4625,6 @@ class range_label_for_format_type_mismatch
     suffix.fill_buffer (p);
 
     char *result = concat (text.m_buffer, p, NULL);
-    text.maybe_free ();
     return label_text::take (result);
   }
 
diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc
index d1d8d3f2081..872c67e53ed 100644
--- a/gcc/diagnostic-format-json.cc
+++ b/gcc/diagnostic-format-json.cc
@@ -101,11 +101,9 @@ json_from_location_range (diagnostic_context *context,
 
   if (loc_range->m_label)
     {
-      label_text text;
-      text = loc_range->m_label->get_text (range_idx);
+      label_text text (loc_range->m_label->get_text (range_idx));
       if (text.m_buffer)
 	result->set ("label", new json::string (text.m_buffer));
-      text.maybe_free ();
     }
 
   return result;
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc
index a7bb9fb639d..1e4ebc8ad38 100644
--- a/gcc/diagnostic-format-sarif.cc
+++ b/gcc/diagnostic-format-sarif.cc
@@ -584,7 +584,6 @@ sarif_builder::make_location_object (const diagnostic_event &event)
   label_text ev_desc = event.get_desc (false);
   json::object *message_obj = make_message_object (ev_desc.m_buffer);
   location_obj->set ("message", message_obj);
-  ev_desc.maybe_free ();
 
   return location_obj;
 }
diff --git a/gcc/diagnostic-show-locus.cc b/gcc/diagnostic-show-locus.cc
index 6eafe19785f..9cd7794d077 100644
--- a/gcc/diagnostic-show-locus.cc
+++ b/gcc/diagnostic-show-locus.cc
@@ -1867,6 +1867,31 @@ layout::print_annotation_line (linenum_type row, const line_bounds lbounds)
   print_newline ();
 }
 
+/* A version of label_text that can live inside a vec.
+   Requires manual cleanup via maybe_free.  */
+
+struct pod_label_text
+{
+  pod_label_text ()
+  : m_buffer (NULL), m_caller_owned (false)
+  {}
+
+  pod_label_text (label_text &&other)
+  : m_buffer (other.m_buffer), m_caller_owned (other.m_owned)
+  {
+    other.moved_from ();
+  }
+
+  void maybe_free ()
+  {
+    if (m_caller_owned)
+      free (m_buffer);
+  }
+
+  char *m_buffer;
+  bool m_caller_owned;
+};
+
 /* Implementation detail of layout::print_any_labels.
 
    A label within the given row of source.  */
@@ -1878,10 +1903,10 @@ public:
 	      int state_idx, int column,
 	      label_text text)
   : m_state_idx (state_idx), m_column (column),
-    m_text (text), m_label_line (0), m_has_vbar (true)
+    m_text (std::move (text)), m_label_line (0), m_has_vbar (true)
   {
-    const int bytes = strlen (text.m_buffer);
-    m_display_width = cpp_display_width (text.m_buffer, bytes, policy);
+    const int bytes = strlen (m_text.m_buffer);
+    m_display_width = cpp_display_width (m_text.m_buffer, bytes, policy);
   }
 
   /* Sorting is primarily by column, then by state index.  */
@@ -1900,7 +1925,7 @@ public:
 
   int m_state_idx;
   int m_column;
-  label_text m_text;
+  pod_label_text m_text;
   size_t m_display_width;
   int m_label_line;
   bool m_has_vbar;
@@ -1941,7 +1966,7 @@ layout::print_any_labels (linenum_type row)
 	if (text.m_buffer == NULL)
 	  continue;
 
-	labels.safe_push (line_label (m_policy, i, disp_col, text));
+	labels.safe_push (line_label (m_policy, i, disp_col, std::move (text)));
       }
   }
 
diff --git a/gcc/tree-diagnostic-path.cc b/gcc/tree-diagnostic-path.cc
index ae2f8a2d262..2f297faed34 100644
--- a/gcc/tree-diagnostic-path.cc
+++ b/gcc/tree-diagnostic-path.cc
@@ -66,7 +66,6 @@ class path_label : public range_label
     pp_show_color (&pp) = pp_show_color (global_dc->printer);
     diagnostic_event_id_t event_id (event_idx);
     pp_printf (&pp, "%@ %s", &event_id, event_text.m_buffer);
-    event_text.maybe_free ();
     label_text result = label_text::take (xstrdup (pp_formatted_text (&pp)));
     return result;
   }
@@ -176,7 +175,6 @@ struct event_range
 	    pretty_printer *pp = dc->printer;
 	    pp_printf (pp, " %@: %s", &event_id, event_text.m_buffer);
 	    pp_newline (pp);
-	    event_text.maybe_free ();
 	  }
 	return;
       }
@@ -484,7 +482,6 @@ default_tree_diagnostic_path_printer (diagnostic_context *context,
 	    else
 	      inform (event.get_location (),
 		      "%@ %s", &event_id, event_text.m_buffer);
-	    event_text.maybe_free ();
 	  }
       }
       break;
@@ -523,7 +520,6 @@ default_tree_make_json_for_path (diagnostic_context *context,
 						     event.get_location ()));
       label_text event_text (event.get_desc (false));
       event_obj->set ("description", new json::string (event_text.m_buffer));
-      event_text.maybe_free ();
       if (tree fndecl = event.get_fndecl ())
 	{
 	  const char *function
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 80335721e03..c6379ce25b8 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -22,6 +22,8 @@ along with this program; see the file COPYING3.  If not see
 #ifndef LIBCPP_LINE_MAP_H
 #define LIBCPP_LINE_MAP_H
 
+#include <utility>
+
 #ifndef GTY
 #define GTY(x) /* nothing */
 #endif
@@ -1836,43 +1838,71 @@ class label_text
 {
 public:
   label_text ()
-  : m_buffer (NULL), m_caller_owned (false)
+  : m_buffer (NULL), m_owned (false)
   {}
 
-  void maybe_free ()
+  ~label_text ()
+  {
+    if (m_owned)
+      free (m_buffer);
+  }
+
+  /* Move ctor.  */
+  label_text (label_text &&other)
+  : m_buffer (other.m_buffer), m_owned (other.m_owned)
+  {
+    other.moved_from ();
+  }
+
+  /* Move assignment.  */
+  label_text & operator= (label_text &&other)
   {
-    if (m_caller_owned)
+    if (m_owned)
       free (m_buffer);
+    m_buffer = other.m_buffer;
+    m_owned = other.m_owned;
+    other.moved_from ();
+    return *this;
   }
 
+  /* Delete the copy ctor and copy-assignment operator.  */
+  label_text (const label_text &) = delete;
+  label_text & operator= (const label_text &) = delete;
+
   /* Create a label_text instance that borrows BUFFER from a
      longer-lived owner.  */
   static label_text borrow (const char *buffer)
   {
-    return label_text (const_cast <char *> (buffer), false);
+    return std::move (label_text (const_cast <char *> (buffer), false));
   }
 
   /* Create a label_text instance that takes ownership of BUFFER.  */
   static label_text take (char *buffer)
   {
-    return label_text (buffer, true);
+    return std::move (label_text (buffer, true));
   }
 
   /* Take ownership of the buffer, copying if necessary.  */
   char *take_or_copy ()
   {
-    if (m_caller_owned)
+    if (m_owned)
       return m_buffer;
     else
       return xstrdup (m_buffer);
   }
 
+  void moved_from ()
+  {
+    m_buffer = NULL;
+    m_owned = false;
+  }
+
   char *m_buffer;
-  bool m_caller_owned;
+  bool m_owned;
 
 private:
   label_text (char *buffer, bool owned)
-  : m_buffer (buffer), m_caller_owned (owned)
+  : m_buffer (buffer), m_owned (owned)
   {}
 };


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-07-07 19:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-07 19:56 [gcc r13-1563] Convert label_text to C++11 move semantics David Malcolm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).