mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-31 11:50:57 +08:00
re PR driver/36312 (should refuse to overwrite input file with output file)
gcc/testsuite/ChangeLog: 2014-11-11 Anthony Brandon <anthony.brandon@gmail.com> Manuel López-Ibáñez <manu@gcc.gnu.org> PR driver/36312 * gcc.misc-tests/output.exp: New test case for identical input and output files. include/ChangeLog: 2014-11-11 Anthony Brandon <anthony.brandon@gmail.com> Manuel López-Ibáñez <manu@gcc.gnu.org> PR driver/36312 * filenames.h: Add prototype for canonical_filename_eq. gcc/ChangeLog: 2014-11-11 Anthony Brandon <anthony.brandon@gmail.com> Manuel López-Ibáñez <manu@gcc.gnu.org> PR driver/36312 * diagnostic-core.h: Add prototype for fatal_error. * diagnostic.c (fatal_error): New function fatal_error. * gcc.c (store_arg): Remove have_o_argbuf_index. (process_command): Check if input and output files are the same. * toplev.c (init_asm_output): Check if input and output files are the same. libiberty/ChangeLog: 2014-11-11 Anthony Brandon <anthony.brandon@gmail.com> Manuel López-Ibáñez <manu@gcc.gnu.org> PR driver/36312 * filename_cmp.c (canonical_filename_eq): New function to check if file names are the same. * functions.texi: Updated with documentation for new function. Co-Authored-By: Manuel López-Ibáñez <manu@gcc.gnu.org> From-SVN: r217391
This commit is contained in:
parent
3aa34c1d8f
commit
3d00119cfb
@ -1,3 +1,14 @@
|
||||
2014-11-11 Anthony Brandon <anthony.brandon@gmail.com>
|
||||
Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR driver/36312
|
||||
* diagnostic-core.h: Add prototype for fatal_error.
|
||||
* diagnostic.c (fatal_error): New function fatal_error.
|
||||
* gcc.c (store_arg): Remove have_o_argbuf_index.
|
||||
(process_command): Check if input and output files are the same.
|
||||
* toplev.c (init_asm_output): Check if input and output files are
|
||||
the same.
|
||||
|
||||
2014-11-11 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* reorg.c (fill_slots_from_thread): Do not copy frame-related insns.
|
||||
|
@ -68,6 +68,8 @@ extern void error_n (location_t, int, const char *, const char *, ...)
|
||||
extern void error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
||||
extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
|
||||
ATTRIBUTE_NORETURN;
|
||||
extern void fatal_error (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3)
|
||||
ATTRIBUTE_NORETURN;
|
||||
/* Pass one of the OPT_W* from options.h as the second parameter. */
|
||||
extern bool pedwarn (location_t, int, const char *, ...)
|
||||
ATTRIBUTE_GCC_DIAG(3,4);
|
||||
|
@ -1163,6 +1163,23 @@ fatal_error (const char *gmsgid, ...)
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* An error which is severe enough that we make no attempt to
|
||||
continue. Do not use this for internal consistency checks; that's
|
||||
internal_error. Use of this function should be rare. */
|
||||
void
|
||||
fatal_error (location_t loc, const char *gmsgid, ...)
|
||||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, loc, DK_FATAL);
|
||||
report_diagnostic (&diagnostic);
|
||||
va_end (ap);
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* An internal consistency check has failed. We make no attempt to
|
||||
continue. Note that unless there is debugging value to be had from
|
||||
a more specific message, or some other good reason, you should use
|
||||
|
21
gcc/gcc.c
21
gcc/gcc.c
@ -1702,17 +1702,15 @@ typedef const char *const_char_p; /* For DEF_VEC_P. */
|
||||
|
||||
static vec<const_char_p> argbuf;
|
||||
|
||||
/* Position in the argbuf vector containing the name of the output file
|
||||
(the value associated with the "-o" flag). */
|
||||
|
||||
static int have_o_argbuf_index = 0;
|
||||
|
||||
/* Were the options -c, -S or -E passed. */
|
||||
static int have_c = 0;
|
||||
|
||||
/* Was the option -o passed. */
|
||||
static int have_o = 0;
|
||||
|
||||
/* Pointer to output file name passed in with -o. */
|
||||
static const char *output_file = 0;
|
||||
|
||||
/* This is the list of suffixes and codes (%g/%u/%U/%j) and the associated
|
||||
temp file. If the HOST_BIT_BUCKET is used for %j, no entry is made for
|
||||
it here. */
|
||||
@ -1762,8 +1760,6 @@ store_arg (const char *arg, int delete_always, int delete_failure)
|
||||
{
|
||||
argbuf.safe_push (arg);
|
||||
|
||||
if (strcmp (arg, "-o") == 0)
|
||||
have_o_argbuf_index = argbuf.length ();
|
||||
if (delete_always || delete_failure)
|
||||
{
|
||||
const char *p;
|
||||
@ -3713,6 +3709,7 @@ driver_handle_option (struct gcc_options *opts,
|
||||
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
|
||||
arg = convert_filename (arg, ! have_c, 0);
|
||||
#endif
|
||||
output_file = arg;
|
||||
/* Save the output name in case -save-temps=obj was used. */
|
||||
save_temps_prefix = xstrdup (arg);
|
||||
/* On some systems, ld cannot handle "-o" without a space. So
|
||||
@ -4052,6 +4049,16 @@ process_command (unsigned int decoded_options_count,
|
||||
CL_DRIVER, &handlers, global_dc);
|
||||
}
|
||||
|
||||
if (output_file && strcmp (output_file, "-"))
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n_infiles; i++)
|
||||
if ((!infiles[i].language || infiles[i].language[0] != '*')
|
||||
&& canonical_filename_eq (infiles[i].name, output_file))
|
||||
fatal_error ("input file %qs is the same as output file",
|
||||
output_file);
|
||||
}
|
||||
|
||||
/* If -save-temps=obj and -o name, create the prefix to use for %b.
|
||||
Otherwise just make -save-temps=obj the same as -save-temps=cwd. */
|
||||
if (save_temps_flag == SAVE_TEMPS_OBJ && save_temps_prefix != NULL)
|
||||
|
@ -1,3 +1,10 @@
|
||||
2014-11-11 Anthony Brandon <anthony.brandon@gmail.com>
|
||||
Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR driver/36312
|
||||
* gcc.misc-tests/output.exp: New test case for identical input and
|
||||
output files.
|
||||
|
||||
2014-11-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR fortran/44054
|
||||
|
66
gcc/testsuite/gcc.misc-tests/output.exp
Normal file
66
gcc/testsuite/gcc.misc-tests/output.exp
Normal file
@ -0,0 +1,66 @@
|
||||
# Copyright (C) 2005-2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Run GCC with the input file also specified as output file. Check that the
|
||||
# compiler prints an error message and does not overwrite the input file.
|
||||
|
||||
load_lib gcc-defs.exp
|
||||
load_lib target-supports.exp
|
||||
|
||||
# These tests don't run runtest_file_p consistently if it
|
||||
# doesn't return the same values, so disable parallelization
|
||||
# of this *.exp file. The first parallel runtest to reach
|
||||
# this will run all the tests serially.
|
||||
if ![gcc_parallel_test_run_p output] {
|
||||
return
|
||||
}
|
||||
|
||||
# I'm not sure if this is needed here. It was in options.exp.
|
||||
gcc_parallel_test_enable 0
|
||||
|
||||
proc check_gcc_overwrite_input {} {
|
||||
set filename test-[pid]
|
||||
set fd [open $filename.c w]
|
||||
puts $fd "int main (void) \{ return 0; \}"
|
||||
close $fd
|
||||
remote_download host $filename.c
|
||||
set test "input overwrite test"
|
||||
set compiler cc1
|
||||
set gcc_output [gcc_target_compile $filename.c $filename.c executable ""]
|
||||
|
||||
# Is this right, or do I need to use something like remote_upload?
|
||||
set fd [open $filename.c r]
|
||||
set file_data [read $fd]
|
||||
close $fd
|
||||
remote_file build delete $filename.c
|
||||
|
||||
# check if the contents of the input file has changed
|
||||
if {!($file_data eq "int main (void) \{ return 0; \}\n")} {
|
||||
fail "$test (input overwritten)"
|
||||
return
|
||||
}
|
||||
|
||||
# check if the error message was printed
|
||||
if {![regexp -- "same as output" $gcc_output]} {
|
||||
fail "$test (no error printed)"
|
||||
return
|
||||
}
|
||||
pass $test
|
||||
}
|
||||
|
||||
check_gcc_overwrite_input
|
||||
|
||||
gcc_parallel_test_enable 1
|
11
gcc/toplev.c
11
gcc/toplev.c
@ -942,10 +942,17 @@ init_asm_output (const char *name)
|
||||
}
|
||||
if (!strcmp (asm_file_name, "-"))
|
||||
asm_out_file = stdout;
|
||||
else
|
||||
else if (!canonical_filename_eq (asm_file_name, name))
|
||||
asm_out_file = fopen (asm_file_name, "w");
|
||||
else
|
||||
/* Use fatal_error (UNKOWN_LOCATION) instead of just fatal_error to
|
||||
prevent gcc from printing the first line in the current file. */
|
||||
fatal_error (UNKNOWN_LOCATION,
|
||||
"input file %qs is the same as output file",
|
||||
asm_file_name);
|
||||
if (asm_out_file == 0)
|
||||
fatal_error ("can%'t open %s for writing: %m", asm_file_name);
|
||||
fatal_error (UNKNOWN_LOCATION,
|
||||
"can%'t open %qs for writing: %m", asm_file_name);
|
||||
}
|
||||
|
||||
if (!flag_syntax_only)
|
||||
|
@ -1,3 +1,9 @@
|
||||
2014-11-11 Anthony Brandon <anthony.brandon@gmail.com>
|
||||
Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR driver/36312
|
||||
* filenames.h: Add prototype for canonical_filename_eq.
|
||||
|
||||
2014-11-11 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* ChangeLog.jit: New.
|
||||
|
@ -90,6 +90,8 @@ extern hashval_t filename_hash (const void *s);
|
||||
|
||||
extern int filename_eq (const void *s1, const void *s2);
|
||||
|
||||
extern int canonical_filename_eq (const char *a, const char *b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,3 +1,11 @@
|
||||
2014-11-11 Anthony Brandon <anthony.brandon@gmail.com>
|
||||
Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR driver/36312
|
||||
* filename_cmp.c (canonical_filename_eq): New function to check if
|
||||
file names are the same.
|
||||
* functions.texi: Updated with documentation for new function.
|
||||
|
||||
2014-11-11 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* ChangeLog.jit: New.
|
||||
|
@ -24,8 +24,13 @@
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "filenames.h"
|
||||
#include "safe-ctype.h"
|
||||
#include "libiberty.h"
|
||||
|
||||
/*
|
||||
|
||||
@ -190,3 +195,27 @@ filename_eq (const void *s1, const void *s2)
|
||||
/* The casts are for -Wc++-compat. */
|
||||
return filename_cmp ((const char *) s1, (const char *) s2) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@deftypefn Extension int canonical_filename_eq (const char *@var{a}, const char *@var{b})
|
||||
|
||||
Return non-zero if file names @var{a} and @var{b} are equivalent.
|
||||
This function compares the canonical versions of the filenames as returned by
|
||||
@code{lrealpath()}, so that so that different file names pointing to the same
|
||||
underlying file are treated as being identical.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
canonical_filename_eq (const char * a, const char * b)
|
||||
{
|
||||
char * ca = lrealpath(a);
|
||||
char * cb = lrealpath(b);
|
||||
int res = filename_eq (ca, cb);
|
||||
free (ca);
|
||||
free (cb);
|
||||
return res;
|
||||
}
|
||||
|
@ -125,6 +125,16 @@ Uses @code{malloc} to allocate storage for @var{nelem} objects of
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@c filename_cmp.c:201
|
||||
@deftypefn Extension int canonical_filename_eq (const char *@var{a}, const char *@var{b})
|
||||
|
||||
Return non-zero if file names @var{a} and @var{b} are equivalent.
|
||||
This function compares the canonical versions of the filenames as returned by
|
||||
@code{lrealpath()}, so that so that different file names pointing to the same
|
||||
underlying file are treated as being identical.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@c choose-temp.c:45
|
||||
@deftypefn Extension char* choose_temp_base (void)
|
||||
|
||||
@ -286,7 +296,7 @@ value 1). If @var{valu} is zero, zero is returned.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@c filename_cmp.c:32
|
||||
@c filename_cmp.c:37
|
||||
@deftypefn Extension int filename_cmp (const char *@var{s1}, const char *@var{s2})
|
||||
|
||||
Return zero if the two file names @var{s1} and @var{s2} are equivalent.
|
||||
@ -303,7 +313,7 @@ and backward slashes are equal.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@c filename_cmp.c:178
|
||||
@c filename_cmp.c:183
|
||||
@deftypefn Extension int filename_eq (const void *@var{s1}, const void *@var{s2})
|
||||
|
||||
Return non-zero if file names @var{s1} and @var{s2} are equivalent.
|
||||
@ -311,7 +321,7 @@ This function is for use with hashtab.c hash tables.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@c filename_cmp.c:147
|
||||
@c filename_cmp.c:152
|
||||
@deftypefn Extension hashval_t filename_hash (const void *@var{s})
|
||||
|
||||
Return the hash value for file name @var{s} that will be compared
|
||||
@ -320,7 +330,7 @@ This function is for use with hashtab.c hash tables.
|
||||
|
||||
@end deftypefn
|
||||
|
||||
@c filename_cmp.c:89
|
||||
@c filename_cmp.c:94
|
||||
@deftypefn Extension int filename_ncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n})
|
||||
|
||||
Return zero if the two file names @var{s1} and @var{s2} are equivalent
|
||||
|
Loading…
x
Reference in New Issue
Block a user