From dc3577989d23572bc6f695e791eeaad33cfe8f6a Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Wed, 27 Feb 2013 08:28:09 +0100
Subject: [PATCH] opts.h: Include obstack.h.

	* opts.h: Include obstack.h.
	(opts_concat): New prototype.
	(opts_obstack): New declaration.
	* opts.c (opts_concat): New function.
	(opts_obstack): New variable.
	(init_options_struct): Call gcc_init_obstack on opts_obstack.
	(finish_options): Use opts_concat instead of concat
	and XOBNEWVEC instead of XNEWVEC.
	* opts-common.c (generate_canonical_option, decode_cmdline_option,
	generate_option): Likewise.
	* Makefile.in (OPTS_H): Depend on $(OBSTACK_H).
	* lto-wrapper.c (main): Call gcc_init_obstack on opts_obstack.

From-SVN: r196305
---
 gcc/ChangeLog     | 13 +++++++++++++
 gcc/Makefile.in   |  2 +-
 gcc/lto-wrapper.c |  2 ++
 gcc/opts-common.c | 15 +++++++--------
 gcc/opts.c        | 45 +++++++++++++++++++++++++++++++++++++++++----
 gcc/opts.h        |  7 +++++++
 6 files changed, 71 insertions(+), 13 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c9d00d6298bd..e7f05869e8d6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,18 @@
 2013-02-27  Jakub Jelinek  <jakub@redhat.com>
 
+	* opts.h: Include obstack.h.
+	(opts_concat): New prototype.
+	(opts_obstack): New declaration.
+	* opts.c (opts_concat): New function.
+	(opts_obstack): New variable.
+	(init_options_struct): Call gcc_init_obstack on opts_obstack.
+	(finish_options): Use opts_concat instead of concat
+	and XOBNEWVEC instead of XNEWVEC.
+	* opts-common.c (generate_canonical_option, decode_cmdline_option,
+	generate_option): Likewise.
+	* Makefile.in (OPTS_H): Depend on $(OBSTACK_H).
+	* lto-wrapper.c (main): Call gcc_init_obstack on opts_obstack.
+
 	PR target/56455
 	* stmt.c (expand_switch_as_decision_tree_p): If flag_pic
 	and ASM_OUTPUT_ADDR_DIFF_ELT isn't defined, return true.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 557ab08fbfad..0cdfa51e73ec 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -919,7 +919,7 @@ PREDICT_H = predict.h predict.def
 CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \
 	$(srcdir)/../libcpp/include/cpplib.h
 INPUT_H = $(srcdir)/../libcpp/include/line-map.h input.h
-OPTS_H = $(INPUT_H) $(VEC_H) opts.h
+OPTS_H = $(INPUT_H) $(VEC_H) opts.h $(OBSTACK_H)
 DECNUM_H = $(DECNUM)/decContext.h $(DECNUM)/decDPD.h $(DECNUM)/decNumber.h \
 	$(DECNUMFMT)/decimal32.h $(DECNUMFMT)/decimal64.h \
 	$(DECNUMFMT)/decimal128.h $(DECNUMFMT)/decimal128Local.h
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 529318247e2a..15a34dd69569 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -915,6 +915,8 @@ main (int argc, char *argv[])
 {
   const char *p;
 
+  gcc_obstack_init (&opts_obstack);
+
   p = argv[0] + strlen (argv[0]);
   while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
     --p;
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 1dd872a638c3..95ca5841acce 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -276,7 +276,7 @@ generate_canonical_option (size_t opt_index, const char *arg, int value,
       && !option->cl_reject_negative
       && (opt_text[1] == 'W' || opt_text[1] == 'f' || opt_text[1] == 'm'))
     {
-      char *t = XNEWVEC (char, option->opt_len + 5);
+      char *t = XOBNEWVEC (&opts_obstack, char, option->opt_len + 5);
       t[0] = '-';
       t[1] = opt_text[1];
       t[2] = 'n';
@@ -301,11 +301,9 @@ generate_canonical_option (size_t opt_index, const char *arg, int value,
       else
 	{
 	  gcc_assert (option->flags & CL_JOINED);
-	  decoded->canonical_option[0] = concat (opt_text, arg, NULL);
+	  decoded->canonical_option[0] = opts_concat (opt_text, arg, NULL);
 	  decoded->canonical_option[1] = NULL;
 	  decoded->canonical_option_num_elements = 1;
-	  if (opt_text != option->opt_text)
-	    free (CONST_CAST (char *, opt_text));
 	}
     }
   else
@@ -590,7 +588,7 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
     {
       size_t j;
       size_t len = strlen (arg);
-      char *arg_lower = XNEWVEC (char, len + 1);
+      char *arg_lower = XOBNEWVEC (&opts_obstack, char, len + 1);
 
       for (j = 0; j < len; j++)
 	arg_lower[j] = TOLOWER ((unsigned char) arg[j]);
@@ -670,7 +668,8 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
 	  decoded->canonical_option_num_elements = result;
 	}
     }
-  decoded->orig_option_with_args_text = p = XNEWVEC (char, total_len);
+  decoded->orig_option_with_args_text
+    = p = XOBNEWVEC (&opts_obstack, char, total_len);
   for (i = 0; i < result; i++)
     {
       size_t len = strlen (argv[i]);
@@ -932,8 +931,8 @@ generate_option (size_t opt_index, const char *arg, int value,
 
     case 2:
       decoded->orig_option_with_args_text
-	= concat (decoded->canonical_option[0], " ",
-		  decoded->canonical_option[1], NULL);
+	= opts_concat (decoded->canonical_option[0], " ",
+		       decoded->canonical_option[1], NULL);
       break;
 
     default:
diff --git a/gcc/opts.c b/gcc/opts.c
index bd1b2dcfd352..d569b5e7e90d 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -268,6 +268,40 @@ add_comma_separated_to_vector (void **pvec, const char *arg)
   *pvec = v;
 }
 
+/* Like libiberty concat, but allocate using opts_obstack.  */
+
+char *
+opts_concat (const char *first, ...)
+{
+  char *newstr, *end;
+  size_t length = 0;
+  const char *arg;
+  va_list ap;
+
+  /* First compute the size of the result and get sufficient memory.  */
+  va_start (ap, first);
+  for (arg = first; arg; arg = va_arg (ap, const char *))
+    length += strlen (arg);
+  newstr = XOBNEWVEC (&opts_obstack, char, length + 1);
+  va_end (ap);
+
+  /* Now copy the individual pieces to the result string. */
+  va_start (ap, first);
+  for (arg = first, end = newstr; arg; arg = va_arg (ap, const char *))
+    {
+      length = strlen (arg);
+      memcpy (end, arg, length);
+      end += length;
+    }
+  *end = '\0';
+  va_end (ap);
+  return newstr;
+}
+
+/* Obstack for option strings.  */
+
+struct obstack opts_obstack;
+
 /* Initialize OPTS and OPTS_SET before using them in parsing options.  */
 
 void
@@ -275,6 +309,8 @@ init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
 {
   size_t num_params = get_num_compiler_params ();
 
+  gcc_obstack_init (&opts_obstack);
+
   *opts = global_options_init;
   memset (opts_set, 0, sizeof (*opts_set));
 
@@ -638,8 +674,8 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
 	 directory, typically the directory to contain the object
 	 file.  */
       if (opts->x_dump_dir_name)
-	opts->x_dump_base_name = concat (opts->x_dump_dir_name,
-					 opts->x_dump_base_name, NULL);
+	opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
+					      opts->x_dump_base_name, NULL);
       else if (opts->x_aux_base_name
 	       && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0)
 	{
@@ -649,8 +685,9 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
 	  if (opts->x_aux_base_name != aux_base)
 	    {
 	      int dir_len = aux_base - opts->x_aux_base_name;
-	      char *new_dump_base_name =
-		XNEWVEC (char, strlen (opts->x_dump_base_name) + dir_len + 1);
+	      char *new_dump_base_name
+		= XOBNEWVEC (&opts_obstack, char,
+			     strlen (opts->x_dump_base_name) + dir_len + 1);
 
 	      /* Copy directory component from OPTS->X_AUX_BASE_NAME.  */
 	      memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len);
diff --git a/gcc/opts.h b/gcc/opts.h
index 723c20bfe11d..264f4de7daaf 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "input.h"
 #include "vec.h"
+#include "obstack.h"
 
 /* Specifies how a switch's VAR_VALUE relates to its FLAG_VAR.  */
 enum cl_var_type {
@@ -304,6 +305,12 @@ extern const char **in_fnames;
 
 extern unsigned num_in_fnames;
 
+extern char *opts_concat (const char *first, ...);
+
+/* Obstack for option strings.  */
+
+extern struct obstack opts_obstack;
+
 size_t find_opt (const char *input, unsigned int lang_mask);
 extern int integral_argument (const char *arg);
 extern bool enum_value_to_arg (const struct cl_enum_arg *enum_args,
-- 
GitLab