This fixes PR48217, the failure to decode '\\'' from COLLECT_GCC_OPTIONS
in lto-wrapper.

LTO bootstrap & regtest running on x86_64-unknown-linux-gnu.

Richard.

2011-11-02  Richard Guenther  <rguent...@suse.de>

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

Index: trunk/gcc/lto-wrapper.c
===================================================================
*** trunk.orig/gcc/lto-wrapper.c        2011-11-02 16:07:20.000000000 +0100
--- trunk/gcc/lto-wrapper.c     2011-11-02 16:48:15.000000000 +0100
*************** get_options_from_collect_gcc_options (co
*** 300,338 ****
                                      struct cl_decoded_option 
**decoded_options,
                                      unsigned int *decoded_options_count)
  {
    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;
    argv_storage = xstrdup (collect_gcc_options);
!   for (i = 1, j = 0; argv_storage[j] != '\0'; ++j)
      {
        if (argv_storage[j] == '\'')
        {
!         argv[i++] = &argv_storage[++j];
!         while (argv_storage[j] != '\'')
!           ++j;
!         argv_storage[j] = '\0';
        }
      }
!   argv[i] = NULL;
  
    decode_cmdline_options_to_array (argc, (const char **)argv,
                                   lang_mask,
                                   decoded_options, decoded_options_count);
!   free (argv);
  }
  
  /* Append OPTION to the options array DECODED_OPTIONS with size
--- 300,347 ----
                                      struct cl_decoded_option 
**decoded_options,
                                      unsigned int *decoded_options_count)
  {
+   struct obstack argv_obstack;
    char *argv_storage;
    const char **argv;
!   int j, k, argc;
  
    argv_storage = xstrdup (collect_gcc_options);
!   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] == '\'')
        {
!         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';
        }
      }
! 
!   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);
!   obstack_free (&argv_obstack, NULL);
  }
  
  /* Append OPTION to the options array DECODED_OPTIONS with size

Reply via email to