From 969d578c2df1fd86ad6a29347ddbaa8ff248df75 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Thu, 3 Nov 2011 13:13:33 +0000
Subject: [PATCH] re PR lto/48217 (lto mishandles quotes in command line
 defines)

2011-11-03  Richard Guenther  <rguenther@suse.de>

	PR lto/48217
	* lto-wrapper.c (get_options_from_collect_gcc_options): Properly
	decode an encoded literal '.

From-SVN: r180822
---
 gcc/ChangeLog     |  6 ++++++
 gcc/lto-wrapper.c | 51 ++++++++++++++++++++++++++++-------------------
 2 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5fbc4bd00417..9dd525eec2e5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-11-03  Richard Guenther  <rguenther@suse.de>
+
+	PR lto/48217
+	* lto-wrapper.c (get_options_from_collect_gcc_options): Properly
+	decode an encoded literal '.
+
 2011-11-03  Tristan Gingold  <gingold@adacore.com>
 
 	* collect2.c (main): Add support of -f (response file) on AIX.
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 1bf7ded2524a..c1480f969b74 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -292,39 +292,48 @@ get_options_from_collect_gcc_options (const char *collect_gcc,
 				      struct cl_decoded_option **decoded_options,
 				      unsigned int *decoded_options_count)
 {
+  struct obstack argv_obstack;
   char *argv_storage;
   const char **argv;
-  int i, j, argc;
-
-  /* Count arguments, account for the program name.  */
-  argc = 2;
-  for (j = 0; collect_gcc_options[j] != '\0'; ++j)
-    if (collect_gcc_options[j] == '\'')
-      ++argc;
-  if (argc % 2 != 0)
-    fatal ("malformed COLLECT_GCC_OPTIONS");
-
-  /* Copy the options to a argv-like array.  */
-  argc /= 2;
-  argv = (const char **) xmalloc ((argc + 2) * sizeof (char *));
-  argv[0] = collect_gcc;
+  int j, k, argc;
+
   argv_storage = xstrdup (collect_gcc_options);
-  for (i = 1, j = 0; argv_storage[j] != '\0'; ++j)
+  obstack_init (&argv_obstack);
+  obstack_ptr_grow (&argv_obstack, collect_gcc);
+
+  for (j = 0, k = 0; argv_storage[j] != '\0'; ++j)
     {
       if (argv_storage[j] == '\'')
 	{
-	  argv[i++] = &argv_storage[++j];
-	  while (argv_storage[j] != '\'')
-	    ++j;
-	  argv_storage[j] = '\0';
+	  obstack_ptr_grow (&argv_obstack, &argv_storage[k]);
+	  ++j;
+	  do
+	    {
+	      if (argv_storage[j] == '\0')
+		fatal ("malformed COLLECT_GCC_OPTIONS");
+	      else if (strncmp (&argv_storage[j], "'\\''", 4) == 0)
+		{
+		  argv_storage[k++] = '\'';
+		  j += 4;
+		}
+	      else if (argv_storage[j] == '\'')
+		break;
+	      else
+		argv_storage[k++] = argv_storage[j++];
+	    }
+	  while (1);
+	  argv_storage[k++] = '\0';
 	}
     }
-  argv[i] = NULL;
+
+  obstack_ptr_grow (&argv_obstack, NULL);
+  argc = obstack_object_size (&argv_obstack) / sizeof (void *) - 1;
+  argv = XOBFINISH (&argv_obstack, const char **);
 
   decode_cmdline_options_to_array (argc, (const char **)argv,
 				   lang_mask,
 				   decoded_options, decoded_options_count);
-  free (argv);
+  obstack_free (&argv_obstack, NULL);
 }
 
 
-- 
GitLab