Commit 3d00119c by Anthony Brandon Committed by Manuel López-Ibáñez

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
parent 3aa34c1d
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> 2014-11-11 Eric Botcazou <ebotcazou@adacore.com>
* reorg.c (fill_slots_from_thread): Do not copy frame-related insns. * 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 *, ...) ...@@ -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 error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2) extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
ATTRIBUTE_NORETURN; 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. */ /* Pass one of the OPT_W* from options.h as the second parameter. */
extern bool pedwarn (location_t, int, const char *, ...) extern bool pedwarn (location_t, int, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4); ATTRIBUTE_GCC_DIAG(3,4);
......
...@@ -1163,6 +1163,23 @@ fatal_error (const char *gmsgid, ...) ...@@ -1163,6 +1163,23 @@ fatal_error (const char *gmsgid, ...)
gcc_unreachable (); 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 /* An internal consistency check has failed. We make no attempt to
continue. Note that unless there is debugging value to be had from continue. Note that unless there is debugging value to be had from
a more specific message, or some other good reason, you should use a more specific message, or some other good reason, you should use
......
...@@ -1702,17 +1702,15 @@ typedef const char *const_char_p; /* For DEF_VEC_P. */ ...@@ -1702,17 +1702,15 @@ typedef const char *const_char_p; /* For DEF_VEC_P. */
static vec<const_char_p> argbuf; 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. */ /* Were the options -c, -S or -E passed. */
static int have_c = 0; static int have_c = 0;
/* Was the option -o passed. */ /* Was the option -o passed. */
static int have_o = 0; 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 /* 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 temp file. If the HOST_BIT_BUCKET is used for %j, no entry is made for
it here. */ it here. */
...@@ -1762,8 +1760,6 @@ store_arg (const char *arg, int delete_always, int delete_failure) ...@@ -1762,8 +1760,6 @@ store_arg (const char *arg, int delete_always, int delete_failure)
{ {
argbuf.safe_push (arg); argbuf.safe_push (arg);
if (strcmp (arg, "-o") == 0)
have_o_argbuf_index = argbuf.length ();
if (delete_always || delete_failure) if (delete_always || delete_failure)
{ {
const char *p; const char *p;
...@@ -3713,6 +3709,7 @@ driver_handle_option (struct gcc_options *opts, ...@@ -3713,6 +3709,7 @@ driver_handle_option (struct gcc_options *opts,
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX) #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
arg = convert_filename (arg, ! have_c, 0); arg = convert_filename (arg, ! have_c, 0);
#endif #endif
output_file = arg;
/* Save the output name in case -save-temps=obj was used. */ /* Save the output name in case -save-temps=obj was used. */
save_temps_prefix = xstrdup (arg); save_temps_prefix = xstrdup (arg);
/* On some systems, ld cannot handle "-o" without a space. So /* On some systems, ld cannot handle "-o" without a space. So
...@@ -4052,6 +4049,16 @@ process_command (unsigned int decoded_options_count, ...@@ -4052,6 +4049,16 @@ process_command (unsigned int decoded_options_count,
CL_DRIVER, &handlers, global_dc); 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. /* 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. */ Otherwise just make -save-temps=obj the same as -save-temps=cwd. */
if (save_temps_flag == SAVE_TEMPS_OBJ && save_temps_prefix != NULL) if (save_temps_flag == SAVE_TEMPS_OBJ && save_temps_prefix != NULL)
......
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> 2014-11-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR fortran/44054 PR fortran/44054
......
# 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
...@@ -942,10 +942,17 @@ init_asm_output (const char *name) ...@@ -942,10 +942,17 @@ init_asm_output (const char *name)
} }
if (!strcmp (asm_file_name, "-")) if (!strcmp (asm_file_name, "-"))
asm_out_file = stdout; asm_out_file = stdout;
else else if (!canonical_filename_eq (asm_file_name, name))
asm_out_file = fopen (asm_file_name, "w"); 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) 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) if (!flag_syntax_only)
......
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> 2014-11-11 David Malcolm <dmalcolm@redhat.com>
* ChangeLog.jit: New. * ChangeLog.jit: New.
......
...@@ -90,6 +90,8 @@ extern hashval_t filename_hash (const void *s); ...@@ -90,6 +90,8 @@ extern hashval_t filename_hash (const void *s);
extern int filename_eq (const void *s1, const void *s2); extern int filename_eq (const void *s1, const void *s2);
extern int canonical_filename_eq (const char *a, const char *b);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
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> 2014-11-11 David Malcolm <dmalcolm@redhat.com>
* ChangeLog.jit: New. * ChangeLog.jit: New.
......
...@@ -24,8 +24,13 @@ ...@@ -24,8 +24,13 @@
#include <string.h> #include <string.h>
#endif #endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "filenames.h" #include "filenames.h"
#include "safe-ctype.h" #include "safe-ctype.h"
#include "libiberty.h"
/* /*
...@@ -190,3 +195,27 @@ filename_eq (const void *s1, const void *s2) ...@@ -190,3 +195,27 @@ filename_eq (const void *s1, const void *s2)
/* The casts are for -Wc++-compat. */ /* The casts are for -Wc++-compat. */
return filename_cmp ((const char *) s1, (const char *) s2) == 0; 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 ...@@ -125,6 +125,16 @@ Uses @code{malloc} to allocate storage for @var{nelem} objects of
@end deftypefn @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 @c choose-temp.c:45
@deftypefn Extension char* choose_temp_base (void) @deftypefn Extension char* choose_temp_base (void)
...@@ -286,7 +296,7 @@ value 1). If @var{valu} is zero, zero is returned. ...@@ -286,7 +296,7 @@ value 1). If @var{valu} is zero, zero is returned.
@end deftypefn @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}) @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. Return zero if the two file names @var{s1} and @var{s2} are equivalent.
...@@ -303,7 +313,7 @@ and backward slashes are equal. ...@@ -303,7 +313,7 @@ and backward slashes are equal.
@end deftypefn @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}) @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. 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. ...@@ -311,7 +321,7 @@ This function is for use with hashtab.c hash tables.
@end deftypefn @end deftypefn
@c filename_cmp.c:147 @c filename_cmp.c:152
@deftypefn Extension hashval_t filename_hash (const void *@var{s}) @deftypefn Extension hashval_t filename_hash (const void *@var{s})
Return the hash value for file name @var{s} that will be compared 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. ...@@ -320,7 +330,7 @@ This function is for use with hashtab.c hash tables.
@end deftypefn @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}) @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 Return zero if the two file names @var{s1} and @var{s2} are equivalent
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment