This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR50876


This should fix PR50876, failure to properly separate switches
and their arguments from the LTO driver.  It also corrects one
issue with counting arguments (causing us to drop the last
switch or switch argument).  It also re-writes the code to use
an obstack for accumulating argv for the invoked drivers
instead of trying to allocate the right amount of space upfront.

LTO Bootstrap and regtest running on x86_64-unknown-linux-gnu,
I'll commit this tomorrow if that succeeded.

Richard.

2010-10-28  Richard Guenther  <rguenther@suse.de>

	PR driver/50876
	* lto-wrapper.c (get_options_from_collect_gcc_options):
	Properly count arguments.
	(run_gcc): Use an obstack to collect argv, properly separate
	switches and their arguments.

Index: gcc/lto-wrapper.c
===================================================================
*** gcc/lto-wrapper.c	(revision 180563)
--- gcc/lto-wrapper.c	(working copy)
*************** get_options_from_collect_gcc_options (co
*** 296,303 ****
    const char **argv;
    int i, j, argc;
  
!   /* Count arguments.  */
!   argc = 0;
    for (j = 0; collect_gcc_options[j] != '\0'; ++j)
      if (collect_gcc_options[j] == '\'')
        ++argc;
--- 296,303 ----
    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;
*************** run_gcc (unsigned argc, char *argv[])
*** 344,349 ****
--- 344,351 ----
    bool no_partition = false;
    struct cl_decoded_option *decoded_options;
    unsigned int decoded_options_count;
+   struct obstack argv_obstack;
+   int new_head_argc;
  
    /* Get the driver and options.  */
    collect_gcc = getenv ("COLLECT_GCC");
*************** run_gcc (unsigned argc, char *argv[])
*** 358,369 ****
  					&decoded_options_count);
  
    /* Initalize the common arguments for the driver.  */
!   new_argv = (const char **) xmalloc ((15 + decoded_options_count + argc)
! 				      * sizeof (char *));
!   argv_ptr = new_argv;
!   *argv_ptr++ = collect_gcc;
!   *argv_ptr++ = "-xlto";
!   *argv_ptr++ = "-c";
    for (j = 1; j < decoded_options_count; ++j)
      {
        struct cl_decoded_option *option = &decoded_options[j];
--- 360,369 ----
  					&decoded_options_count);
  
    /* Initalize the common arguments for the driver.  */
!   obstack_init (&argv_obstack);
!   obstack_ptr_grow (&argv_obstack, collect_gcc);
!   obstack_ptr_grow (&argv_obstack, "-xlto");
!   obstack_ptr_grow (&argv_obstack, "-c");
    for (j = 1; j < decoded_options_count; ++j)
      {
        struct cl_decoded_option *option = &decoded_options[j];
*************** run_gcc (unsigned argc, char *argv[])
*** 416,422 ****
  	}
  
        /* Pass the option on.  */
!       *argv_ptr++ = option->orig_option_with_args_text;
      }
  
    if (no_partition)
--- 416,423 ----
  	}
  
        /* Pass the option on.  */
!       for (i = 0; i < option->canonical_option_num_elements; ++i)
! 	obstack_ptr_grow (&argv_obstack, option->canonical_option[i]);
      }
  
    if (no_partition)
*************** run_gcc (unsigned argc, char *argv[])
*** 446,467 ****
  	}
        if (!bit_bucket)
  	{
! 	  *argv_ptr++ = "-dumpdir";
! 	  *argv_ptr++ = output_dir;
  	}
  
!       *argv_ptr++ = "-dumpbase";
      }
!   else
!     argv_ptr--;
  
    if (lto_mode == LTO_MODE_LTO)
      {
        flto_out = make_temp_file (".lto.o");
        if (linker_output)
! 	argv_ptr[0] = linker_output;
!       argv_ptr[1] = "-o";
!       argv_ptr[2] = flto_out;
      }
    else 
      {
--- 447,469 ----
  	}
        if (!bit_bucket)
  	{
! 	  obstack_ptr_grow (&argv_obstack, "-dumpdir");
! 	  obstack_ptr_grow (&argv_obstack, output_dir);
  	}
  
!       obstack_ptr_grow (&argv_obstack, "-dumpbase");
      }
! 
!   /* Remember at which point we can scrub args to re-use the commons.  */
!   new_head_argc = obstack_object_size (&argv_obstack) / sizeof (void *);
  
    if (lto_mode == LTO_MODE_LTO)
      {
        flto_out = make_temp_file (".lto.o");
        if (linker_output)
! 	obstack_ptr_grow (&argv_obstack, linker_output);
!       obstack_ptr_grow (&argv_obstack, "-o");
!       obstack_ptr_grow (&argv_obstack, flto_out);
      }
    else 
      {
*************** run_gcc (unsigned argc, char *argv[])
*** 475,481 ****
  					     + sizeof (".wpa") + 1);
  	  strcpy (dumpbase, linker_output);
  	  strcat (dumpbase, ".wpa");
! 	  argv_ptr[0] = dumpbase;
  	}
  
        if (linker_output && debug)
--- 477,483 ----
  					     + sizeof (".wpa") + 1);
  	  strcpy (dumpbase, linker_output);
  	  strcat (dumpbase, ".wpa");
! 	  obstack_ptr_grow (&argv_obstack, dumpbase);
  	}
  
        if (linker_output && debug)
*************** run_gcc (unsigned argc, char *argv[])
*** 491,509 ****
  		         (strlen (ltrans_output_file) + list_option_len + 1));
        tmp = list_option_full;
  
!       argv_ptr[1] = tmp;
        strcpy (tmp, list_option);
        tmp += list_option_len;
        strcpy (tmp, ltrans_output_file);
  
!       argv_ptr[2] = "-fwpa";
      }
  
    /* Append the input objects and possible preceeding arguments.  */
    for (i = 1; i < argc; ++i)
!     argv_ptr[2 + i] = argv[i];
!   argv_ptr[2 + i] = NULL;
  
    fork_execute (CONST_CAST (char **, new_argv));
  
    if (lto_mode == LTO_MODE_LTO)
--- 493,513 ----
  		         (strlen (ltrans_output_file) + list_option_len + 1));
        tmp = list_option_full;
  
!       obstack_ptr_grow (&argv_obstack, tmp);
        strcpy (tmp, list_option);
        tmp += list_option_len;
        strcpy (tmp, ltrans_output_file);
  
!       obstack_ptr_grow (&argv_obstack, "-fwpa");
      }
  
    /* Append the input objects and possible preceeding arguments.  */
    for (i = 1; i < argc; ++i)
!     obstack_ptr_grow (&argv_obstack, argv[i]);
!   obstack_ptr_grow (&argv_obstack, NULL);
  
+   new_argv = XOBFINISH (&argv_obstack, const char **);
+   argv_ptr = &new_argv[new_head_argc];
    fork_execute (CONST_CAST (char **, new_argv));
  
    if (lto_mode == LTO_MODE_LTO)
*************** cont:
*** 656,661 ****
--- 660,667 ----
        free (list_option_full);
        obstack_free (&env_obstack, NULL);
      }
+ 
+   obstack_free (&argv_obstack, NULL);
  }
  
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]