This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix -save-temps from clobbering input file@apple.com
At 10:52 PM -0800 11/3/01, Richard Henderson wrote:
>[ Actually "stat", since we don't have open files here. ]
>
>Um, sure, I guess. I just wouldn't expect the strcmp to be the
>normal case -- .S vs .s seems much more likely to me.
>
>> Do you want me to add it?
>
>Please.
Below is my revised patch for -save-temps to stop it from
clobbering the input file. It's the same as before but with
the addition of checking the file stat's st_dev/st_ino if
the strings strings are unequal.
Ira
------------------------------------
2001-11-05 Ira Ruben <ira@apple.com>
Fix to no allow -save-temps to clobber user's source file.
* gcc.c (do_spec_1): For 'g', 'u', 'U' case with save_temps_flag
set, check that user's input file is not overwritten.
Index: gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.263
diff -c -3 -p -r1.263 gcc.c
*** gcc.c 2001/11/04 02:47:36 1.263
--- gcc.c 2001/11/05 18:28:55
*************** do_spec_1 (spec, inswitch, soft_matched_
*** 4350,4362 ****
case 'g':
case 'u':
case 'U':
- if (save_temps_flag)
{
- obstack_grow (&obstack, input_basename, basename_length);
- delete_this_arg = 0;
- }
- else
- {
struct temp_name *t;
int suffix_length;
const char *suffix = p;
--- 4350,4356 ----
*************** do_spec_1 (spec, inswitch, soft_matched_
*** 4383,4388 ****
--- 4377,4431 ----
TARGET_OBJECT_SUFFIX);
}
suffix_length += strlen (TARGET_OBJECT_SUFFIX);
+ }
+
+ /* If the input_filename has the same suffix specified
+ for the %g, %u, or %U, and -save-temps is specified,
+ we could end up using that file as an intermediate
+ thus clobbering the user's source file ( .e.g.,
+ gcc -save-temps foo.s would clobber foo.s with the
+ output of cpp0). So check for this condition and
+ generate a temp file as the intermediate. */
+
+ if (save_temps_flag)
+ {
+ temp_filename_length = basename_length + suffix_length;
+ temp_filename = alloca (temp_filename_length + 1);
+ strncpy ((char *)temp_filename, input_basename,
basename_length);
+ strncpy ((char *)temp_filename + basename_length, suffix,
+ suffix_length);
+ *((char *)temp_filename + temp_filename_length) = '\0';
+ if (strcmp (temp_filename, input_filename) != 0)
+ {
+ static struct stat st_input;
+ static int st_input_set = 0;
+ struct stat st_temp;
+
+ if (st_input_set == 0)
+ {
+ st_input_set = stat (input_filename, &st_input);
+ if (st_input_set >= 0)
+ st_input_set = 1;
+ }
+
+ /* If we have the stat for the input_filename
+ and we can do the stat for the temp_filename
+ then the they could still refer to the same
+ file if st_dev/st_ino's are the same. */
+
+ if (st_input_set != 1
+ || stat (temp_filename, &st_temp) < 0
+ || st_input.st_dev != st_temp.st_dev
+ || st_input.st_ino != st_temp.st_ino)
+ {
+ temp_filename = save_string (temp_filename,
+
temp_filename_length + 1);
+ obstack_grow (&obstack, temp_filename,
+ temp_filename_length);
+ arg_going = 1;
+ break;
+ }
+ }
}
/* See if we already have an association of %g/%u/%U and