diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/diagnostic-core.h | 2 | ||||
-rw-r--r-- | gcc/diagnostic.c | 17 | ||||
-rw-r--r-- | gcc/gcc.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.misc-tests/output.exp | 66 | ||||
-rw-r--r-- | gcc/toplev.c | 11 |
7 files changed, 126 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 350f21d0af2..5a637686e97 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h index a8245de8985..2fba279af96 100644 --- a/gcc/diagnostic-core.h +++ b/gcc/diagnostic-core.h @@ -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); diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index 642cbe38b9a..f7f8aaa23c0 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -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 diff --git a/gcc/gcc.c b/gcc/gcc.c index e013d5216f5..7e6af22a7c3 100644 --- a/gcc/gcc.c +++ b/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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c1e65213f1..55511f5aa46 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.misc-tests/output.exp b/gcc/testsuite/gcc.misc-tests/output.exp new file mode 100644 index 00000000000..6a810df4c61 --- /dev/null +++ b/gcc/testsuite/gcc.misc-tests/output.exp @@ -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 diff --git a/gcc/toplev.c b/gcc/toplev.c index ef2a813abeb..aa1653e7c44 100644 --- a/gcc/toplev.c +++ b/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) |