Daily bump.
[gcc.git] / gcc / tlink.c
1 /* Scan linker error messages for missing template instantiations and provide
2 them.
3
4 Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2007, 2008,
5 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
6 Contributed by Jason Merrill (jason@cygnus.com).
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "intl.h"
29 #include "obstack.h"
30 #include "hashtab.h"
31 #include "demangle.h"
32 #include "collect2.h"
33 #include "filenames.h"
34 #include "diagnostic-core.h"
35 #include "vec.h"
36
37 /* TARGET_64BIT may be defined to use driver specific functionality. */
38 #undef TARGET_64BIT
39 #define TARGET_64BIT TARGET_64BIT_DEFAULT
40
41 #define MAX_ITERATIONS 17
42
43 /* Defined in the automatically-generated underscore.c. */
44 extern int prepends_underscore;
45
46 static int tlink_verbose;
47
48 static char *initial_cwd;
49 \f
50 /* Hash table boilerplate for working with htab_t. We have hash tables
51 for symbol names, file names, and demangled symbols. */
52
53 typedef struct symbol_hash_entry
54 {
55 const char *key;
56 struct file_hash_entry *file;
57 int chosen;
58 int tweaking;
59 int tweaked;
60 } symbol;
61
62 typedef struct file_hash_entry
63 {
64 const char *key;
65 const char *args;
66 const char *dir;
67 const char *main;
68 int tweaking;
69 } file;
70
71 typedef const char *str;
72
73 typedef struct demangled_hash_entry
74 {
75 const char *key;
76 vec<str> mangled;
77 } demangled;
78
79 /* Hash and comparison functions for these hash tables. */
80
81 static int hash_string_eq (const void *, const void *);
82 static hashval_t hash_string_hash (const void *);
83
84 static int
85 hash_string_eq (const void *s1_p, const void *s2_p)
86 {
87 const char *const *s1 = (const char *const *) s1_p;
88 const char *s2 = (const char *) s2_p;
89 return strcmp (*s1, s2) == 0;
90 }
91
92 static hashval_t
93 hash_string_hash (const void *s_p)
94 {
95 const char *const *s = (const char *const *) s_p;
96 return (*htab_hash_string) (*s);
97 }
98
99 static htab_t symbol_table;
100
101 static struct symbol_hash_entry * symbol_hash_lookup (const char *, int);
102 static struct file_hash_entry * file_hash_lookup (const char *);
103 static struct demangled_hash_entry *demangled_hash_lookup (const char *, int);
104 static void symbol_push (symbol *);
105 static symbol * symbol_pop (void);
106 static void file_push (file *);
107 static file * file_pop (void);
108 static void tlink_init (void);
109 static int tlink_execute (const char *, char **, const char *, const char *);
110 static char * frob_extension (const char *, const char *);
111 static char * obstack_fgets (FILE *, struct obstack *);
112 static char * tfgets (FILE *);
113 static char * pfgets (FILE *);
114 static void freadsym (FILE *, file *, int);
115 static void read_repo_file (file *);
116 static void maybe_tweak (char *, file *);
117 static int recompile_files (void);
118 static int read_repo_files (char **);
119 static void demangle_new_symbols (void);
120 static int scan_linker_output (const char *);
121
122 /* Look up an entry in the symbol hash table. */
123
124 static struct symbol_hash_entry *
125 symbol_hash_lookup (const char *string, int create)
126 {
127 void **e;
128 e = htab_find_slot_with_hash (symbol_table, string,
129 (*htab_hash_string) (string),
130 create ? INSERT : NO_INSERT);
131 if (e == NULL)
132 return NULL;
133 if (*e == NULL)
134 {
135 struct symbol_hash_entry *v;
136 *e = v = XCNEW (struct symbol_hash_entry);
137 v->key = xstrdup (string);
138 }
139 return (struct symbol_hash_entry *) *e;
140 }
141
142 static htab_t file_table;
143
144 /* Look up an entry in the file hash table. */
145
146 static struct file_hash_entry *
147 file_hash_lookup (const char *string)
148 {
149 void **e;
150 e = htab_find_slot_with_hash (file_table, string,
151 (*htab_hash_string) (string),
152 INSERT);
153 if (*e == NULL)
154 {
155 struct file_hash_entry *v;
156 *e = v = XCNEW (struct file_hash_entry);
157 v->key = xstrdup (string);
158 }
159 return (struct file_hash_entry *) *e;
160 }
161
162 static htab_t demangled_table;
163
164 /* Look up an entry in the demangled name hash table. */
165
166 static struct demangled_hash_entry *
167 demangled_hash_lookup (const char *string, int create)
168 {
169 void **e;
170 e = htab_find_slot_with_hash (demangled_table, string,
171 (*htab_hash_string) (string),
172 create ? INSERT : NO_INSERT);
173 if (e == NULL)
174 return NULL;
175 if (*e == NULL)
176 {
177 struct demangled_hash_entry *v;
178 *e = v = XCNEW (struct demangled_hash_entry);
179 v->key = xstrdup (string);
180 }
181 return (struct demangled_hash_entry *) *e;
182 }
183 \f
184 /* Stack code. */
185
186 struct symbol_stack_entry
187 {
188 symbol *value;
189 struct symbol_stack_entry *next;
190 };
191 struct obstack symbol_stack_obstack;
192 struct symbol_stack_entry *symbol_stack;
193
194 struct file_stack_entry
195 {
196 file *value;
197 struct file_stack_entry *next;
198 };
199 struct obstack file_stack_obstack;
200 struct file_stack_entry *file_stack;
201
202 static void
203 symbol_push (symbol *p)
204 {
205 struct symbol_stack_entry *ep
206 = XOBNEW (&symbol_stack_obstack, struct symbol_stack_entry);
207 ep->value = p;
208 ep->next = symbol_stack;
209 symbol_stack = ep;
210 }
211
212 static symbol *
213 symbol_pop (void)
214 {
215 struct symbol_stack_entry *ep = symbol_stack;
216 symbol *p;
217 if (ep == NULL)
218 return NULL;
219 p = ep->value;
220 symbol_stack = ep->next;
221 obstack_free (&symbol_stack_obstack, ep);
222 return p;
223 }
224
225 static void
226 file_push (file *p)
227 {
228 struct file_stack_entry *ep;
229
230 if (p->tweaking)
231 return;
232
233 ep = XOBNEW (&file_stack_obstack, struct file_stack_entry);
234 ep->value = p;
235 ep->next = file_stack;
236 file_stack = ep;
237 p->tweaking = 1;
238 }
239
240 static file *
241 file_pop (void)
242 {
243 struct file_stack_entry *ep = file_stack;
244 file *p;
245 if (ep == NULL)
246 return NULL;
247 p = ep->value;
248 file_stack = ep->next;
249 obstack_free (&file_stack_obstack, ep);
250 p->tweaking = 0;
251 return p;
252 }
253 \f
254 /* Other machinery. */
255
256 /* Initialize the tlink machinery. Called from do_tlink. */
257
258 static void
259 tlink_init (void)
260 {
261 const char *p;
262
263 symbol_table = htab_create (500, hash_string_hash, hash_string_eq,
264 NULL);
265 file_table = htab_create (500, hash_string_hash, hash_string_eq,
266 NULL);
267 demangled_table = htab_create (500, hash_string_hash, hash_string_eq,
268 NULL);
269
270 obstack_begin (&symbol_stack_obstack, 0);
271 obstack_begin (&file_stack_obstack, 0);
272
273 p = getenv ("TLINK_VERBOSE");
274 if (p)
275 tlink_verbose = atoi (p);
276 else
277 {
278 tlink_verbose = 1;
279 if (vflag)
280 tlink_verbose = 2;
281 if (debug)
282 tlink_verbose = 3;
283 }
284
285 initial_cwd = getpwd ();
286 }
287
288 static int
289 tlink_execute (const char *prog, char **argv, const char *outname,
290 const char *errname)
291 {
292 struct pex_obj *pex;
293
294 pex = collect_execute (prog, argv, outname, errname, PEX_LAST | PEX_SEARCH);
295 return collect_wait (prog, pex);
296 }
297
298 static char *
299 frob_extension (const char *s, const char *ext)
300 {
301 const char *p;
302
303 p = strrchr (lbasename (s), '.');
304 if (! p)
305 p = s + strlen (s);
306
307 obstack_grow (&temporary_obstack, s, p - s);
308 return (char *) obstack_copy0 (&temporary_obstack, ext, strlen (ext));
309 }
310
311 static char *
312 obstack_fgets (FILE *stream, struct obstack *ob)
313 {
314 int c;
315 while ((c = getc (stream)) != EOF && c != '\n')
316 obstack_1grow (ob, c);
317 if (obstack_object_size (ob) == 0)
318 return NULL;
319 obstack_1grow (ob, '\0');
320 return XOBFINISH (ob, char *);
321 }
322
323 static char *
324 tfgets (FILE *stream)
325 {
326 return obstack_fgets (stream, &temporary_obstack);
327 }
328
329 static char *
330 pfgets (FILE *stream)
331 {
332 return xstrdup (tfgets (stream));
333 }
334 \f
335 /* Real tlink code. */
336
337 /* Subroutine of read_repo_file. We are reading the repo file for file F,
338 which is coming in on STREAM, and the symbol that comes next in STREAM
339 is offered, chosen or provided if CHOSEN is 0, 1 or 2, respectively.
340
341 XXX "provided" is unimplemented, both here and in the compiler. */
342
343 static void
344 freadsym (FILE *stream, file *f, int chosen)
345 {
346 symbol *sym;
347
348 {
349 const char *name = tfgets (stream);
350 sym = symbol_hash_lookup (name, true);
351 }
352
353 if (sym->file == NULL)
354 {
355 /* We didn't have this symbol already, so we choose this file. */
356
357 symbol_push (sym);
358 sym->file = f;
359 sym->chosen = chosen;
360 }
361 else if (chosen)
362 {
363 /* We want this file; cast aside any pretender. */
364
365 if (sym->chosen && sym->file != f)
366 {
367 if (sym->chosen == 1)
368 file_push (sym->file);
369 else
370 {
371 file_push (f);
372 f = sym->file;
373 chosen = sym->chosen;
374 }
375 }
376 sym->file = f;
377 sym->chosen = chosen;
378 }
379 }
380
381 /* Read in the repo file denoted by F, and record all its information. */
382
383 static void
384 read_repo_file (file *f)
385 {
386 char c;
387 FILE *stream = fopen (f->key, "r");
388
389 if (tlink_verbose >= 2)
390 fprintf (stderr, _("collect: reading %s\n"), f->key);
391
392 while (fscanf (stream, "%c ", &c) == 1)
393 {
394 switch (c)
395 {
396 case 'A':
397 f->args = pfgets (stream);
398 break;
399 case 'D':
400 f->dir = pfgets (stream);
401 break;
402 case 'M':
403 f->main = pfgets (stream);
404 break;
405 case 'P':
406 freadsym (stream, f, 2);
407 break;
408 case 'C':
409 freadsym (stream, f, 1);
410 break;
411 case 'O':
412 freadsym (stream, f, 0);
413 break;
414 }
415 obstack_free (&temporary_obstack, temporary_firstobj);
416 }
417 fclose (stream);
418 if (f->args == NULL)
419 f->args = getenv ("COLLECT_GCC_OPTIONS");
420 if (f->dir == NULL)
421 f->dir = ".";
422 }
423
424 /* We might want to modify LINE, which is a symbol line from file F. We do
425 this if either we saw an error message referring to the symbol in
426 question, or we have already allocated the symbol to another file and
427 this one wants to emit it as well. */
428
429 static void
430 maybe_tweak (char *line, file *f)
431 {
432 symbol *sym = symbol_hash_lookup (line + 2, false);
433
434 if ((sym->file == f && sym->tweaking)
435 || (sym->file != f && line[0] == 'C'))
436 {
437 sym->tweaking = 0;
438 sym->tweaked = 1;
439
440 if (line[0] == 'O')
441 {
442 line[0] = 'C';
443 sym->chosen = 1;
444 }
445 else
446 {
447 line[0] = 'O';
448 sym->chosen = 0;
449 }
450 }
451 }
452
453 /* Update the repo files for each of the object files we have adjusted and
454 recompile. */
455
456 static int
457 recompile_files (void)
458 {
459 file *f;
460
461 putenv (xstrdup ("COMPILER_PATH="));
462 putenv (xstrdup ("LIBRARY_PATH="));
463
464 while ((f = file_pop ()) != NULL)
465 {
466 char *line;
467 const char *p, *q;
468 char **argv;
469 struct obstack arg_stack;
470 FILE *stream = fopen (f->key, "r");
471 const char *const outname = frob_extension (f->key, ".rnw");
472 FILE *output = fopen (outname, "w");
473
474 while ((line = tfgets (stream)) != NULL)
475 {
476 switch (line[0])
477 {
478 case 'C':
479 case 'O':
480 maybe_tweak (line, f);
481 }
482 fprintf (output, "%s\n", line);
483 }
484 fclose (stream);
485 fclose (output);
486 /* On Windows "rename" returns -1 and sets ERRNO to EACCESS if
487 the new file name already exists. Therefore, we explicitly
488 remove the old file first. */
489 if (remove (f->key) == -1)
490 fatal_error ("removing .rpo file: %m");
491 if (rename (outname, f->key) == -1)
492 fatal_error ("renaming .rpo file: %m");
493
494 if (!f->args)
495 {
496 error ("repository file '%s' does not contain command-line "
497 "arguments", f->key);
498 return 0;
499 }
500
501 /* Build a null-terminated argv array suitable for
502 tlink_execute(). Manipulate arguments on the arg_stack while
503 building argv on the temporary_obstack. */
504
505 obstack_init (&arg_stack);
506 obstack_ptr_grow (&temporary_obstack, c_file_name);
507
508 for (p = f->args; *p != '\0'; p = q + 1)
509 {
510 /* Arguments are delimited by single-quotes. Find the
511 opening quote. */
512 p = strchr (p, '\'');
513 if (!p)
514 goto done;
515
516 /* Find the closing quote. */
517 q = strchr (p + 1, '\'');
518 if (!q)
519 goto done;
520
521 obstack_grow (&arg_stack, p + 1, q - (p + 1));
522
523 /* Replace '\'' with '. This is how set_collect_gcc_options
524 encodes a single-quote. */
525 while (q[1] == '\\' && q[2] == '\'' && q[3] == '\'')
526 {
527 const char *r;
528
529 r = strchr (q + 4, '\'');
530 if (!r)
531 goto done;
532
533 obstack_grow (&arg_stack, q + 3, r - (q + 3));
534 q = r;
535 }
536
537 obstack_1grow (&arg_stack, '\0');
538 obstack_ptr_grow (&temporary_obstack, obstack_finish (&arg_stack));
539 }
540 done:
541 obstack_ptr_grow (&temporary_obstack, f->main);
542 obstack_ptr_grow (&temporary_obstack, NULL);
543 argv = XOBFINISH (&temporary_obstack, char **);
544
545 if (tlink_verbose)
546 fprintf (stderr, _("collect: recompiling %s\n"), f->main);
547
548 if (chdir (f->dir) != 0
549 || tlink_execute (c_file_name, argv, NULL, NULL) != 0
550 || chdir (initial_cwd) != 0)
551 return 0;
552
553 read_repo_file (f);
554
555 obstack_free (&arg_stack, NULL);
556 obstack_free (&temporary_obstack, temporary_firstobj);
557 }
558 return 1;
559 }
560
561 /* The first phase of processing: determine which object files have
562 .rpo files associated with them, and read in the information. */
563
564 static int
565 read_repo_files (char **object_lst)
566 {
567 char **object = object_lst;
568
569 for (; *object; object++)
570 {
571 const char *p;
572 file *f;
573
574 /* Don't bother trying for ld flags. */
575 if (*object[0] == '-')
576 continue;
577
578 p = frob_extension (*object, ".rpo");
579
580 if (! file_exists (p))
581 continue;
582
583 f = file_hash_lookup (p);
584
585 read_repo_file (f);
586 }
587
588 if (file_stack != NULL && ! recompile_files ())
589 return 0;
590
591 return (symbol_stack != NULL);
592 }
593
594 /* Add the demangled forms of any new symbols to the hash table. */
595
596 static void
597 demangle_new_symbols (void)
598 {
599 symbol *sym;
600
601 while ((sym = symbol_pop ()) != NULL)
602 {
603 demangled *dem;
604 const char *p = cplus_demangle (sym->key, DMGL_PARAMS | DMGL_ANSI);
605
606 if (! p)
607 continue;
608
609 dem = demangled_hash_lookup (p, true);
610 dem->mangled.safe_push (sym->key);
611 }
612 }
613
614 /* We want to tweak symbol SYM. Return true if all is well, false on
615 error. */
616
617 static bool
618 start_tweaking (symbol *sym)
619 {
620 if (sym && sym->tweaked)
621 {
622 error ("'%s' was assigned to '%s', but was not defined "
623 "during recompilation, or vice versa",
624 sym->key, sym->file->key);
625 return 0;
626 }
627 if (sym && !sym->tweaking)
628 {
629 if (tlink_verbose >= 2)
630 fprintf (stderr, _("collect: tweaking %s in %s\n"),
631 sym->key, sym->file->key);
632 sym->tweaking = 1;
633 file_push (sym->file);
634 }
635 return true;
636 }
637
638 /* Step through the output of the linker, in the file named FNAME, and
639 adjust the settings for each symbol encountered. */
640
641 static int
642 scan_linker_output (const char *fname)
643 {
644 FILE *stream = fopen (fname, "r");
645 char *line;
646 int skip_next_in_line = 0;
647
648 while ((line = tfgets (stream)) != NULL)
649 {
650 char *p = line, *q;
651 symbol *sym;
652 demangled *dem = 0;
653 int end;
654 int ok = 0;
655 unsigned ix;
656 str s;
657
658 /* On darwin9, we might have to skip " in " lines as well. */
659 if (skip_next_in_line
660 && strstr (p, " in "))
661 continue;
662 skip_next_in_line = 0;
663
664 while (*p && ISSPACE ((unsigned char) *p))
665 ++p;
666
667 if (! *p)
668 continue;
669
670 for (q = p; *q && ! ISSPACE ((unsigned char) *q); ++q)
671 ;
672
673 /* Try the first word on the line. */
674 if (*p == '.')
675 ++p;
676 if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
677 p += strlen (USER_LABEL_PREFIX);
678
679 end = ! *q;
680 *q = 0;
681 sym = symbol_hash_lookup (p, false);
682
683 /* Some SVR4 linkers produce messages like
684 ld: 0711-317 ERROR: Undefined symbol: .g__t3foo1Zi
685 */
686 if (! sym && ! end && strstr (q + 1, "Undefined symbol: "))
687 {
688 char *p = strrchr (q + 1, ' ');
689 p++;
690 if (*p == '.')
691 p++;
692 if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
693 p += strlen (USER_LABEL_PREFIX);
694 sym = symbol_hash_lookup (p, false);
695 }
696
697 if (! sym && ! end)
698 /* Try a mangled name in quotes. */
699 {
700 char *oldq = q + 1;
701 q = 0;
702
703 /* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)* */
704 if (strcmp (oldq, "referenced from:") == 0)
705 {
706 /* We have to remember that we found a symbol to tweak. */
707 ok = 1;
708
709 /* We actually want to start from the first word on the
710 line. */
711 oldq = p;
712
713 /* Since the format is multiline, we have to skip
714 following lines with " in ". */
715 skip_next_in_line = 1;
716 }
717
718 /* First try `GNU style'. */
719 p = strchr (oldq, '`');
720 if (p)
721 p++, q = strchr (p, '\'');
722 /* Then try "double quotes". */
723 else if (p = strchr (oldq, '"'), p)
724 p++, q = strchr (p, '"');
725 /* Then try 'single quotes'. */
726 else if (p = strchr (oldq, '\''), p)
727 p++, q = strchr (p, '\'');
728 else {
729 /* Then try entire line. */
730 q = strchr (oldq, 0);
731 if (q != oldq)
732 p = (char *)oldq;
733 }
734
735 if (p)
736 {
737 /* Don't let the strstr's below see the demangled name; we
738 might get spurious matches. */
739 p[-1] = '\0';
740
741 /* powerpc64-linux references .foo when calling function foo. */
742 if (*p == '.')
743 p++;
744 }
745
746 /* We need to check for certain error keywords here, or we would
747 mistakenly use GNU ld's "In function `foo':" message. */
748 if (q && (ok
749 || strstr (oldq, "ndefined")
750 || strstr (oldq, "nresolved")
751 || strstr (oldq, "nsatisfied")
752 || strstr (oldq, "ultiple")))
753 {
754 *q = 0;
755 dem = demangled_hash_lookup (p, false);
756 if (!dem)
757 {
758 if (!strncmp (p, USER_LABEL_PREFIX,
759 strlen (USER_LABEL_PREFIX)))
760 p += strlen (USER_LABEL_PREFIX);
761 sym = symbol_hash_lookup (p, false);
762 }
763 }
764 }
765
766 if (dem)
767 {
768 /* We found a demangled name. If this is the name of a
769 constructor or destructor, there can be several mangled names
770 that match it, so choose or unchoose all of them. If some are
771 chosen and some not, leave the later ones that don't match
772 alone for now; either this will cause the link to suceed, or
773 on the next attempt we will switch all of them the other way
774 and that will cause it to succeed. */
775 int chosen = 0;
776 int len = dem->mangled.length ();
777 ok = true;
778 FOR_EACH_VEC_ELT (dem->mangled, ix, s)
779 {
780 sym = symbol_hash_lookup (s, false);
781 if (ix == 0)
782 chosen = sym->chosen;
783 else if (sym->chosen != chosen)
784 /* Mismatch. */
785 continue;
786 /* Avoid an error about re-tweaking when we guess wrong in
787 the case of mismatch. */
788 if (len > 1)
789 sym->tweaked = false;
790 ok = start_tweaking (sym);
791 }
792 }
793 else
794 ok = start_tweaking (sym);
795
796 obstack_free (&temporary_obstack, temporary_firstobj);
797
798 if (!ok)
799 {
800 fclose (stream);
801 return 0;
802 }
803 }
804
805 fclose (stream);
806 return (file_stack != NULL);
807 }
808
809 /* Entry point for tlink. Called from main in collect2.c.
810
811 Iteratively try to provide definitions for all the unresolved symbols
812 mentioned in the linker error messages.
813
814 LD_ARGV is an array of arguments for the linker.
815 OBJECT_LST is an array of object files that we may be able to recompile
816 to provide missing definitions. Currently ignored. */
817
818 void
819 do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED)
820 {
821 int exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
822
823 tlink_init ();
824
825 if (exit)
826 {
827 int i = 0;
828
829 /* Until collect does a better job of figuring out which are object
830 files, assume that everything on the command line could be. */
831 if (read_repo_files (ld_argv))
832 while (exit && i++ < MAX_ITERATIONS)
833 {
834 if (tlink_verbose >= 3)
835 {
836 dump_ld_file (ldout, stdout);
837 dump_ld_file (lderrout, stderr);
838 }
839 demangle_new_symbols ();
840 if (! scan_linker_output (ldout)
841 && ! scan_linker_output (lderrout))
842 break;
843 if (! recompile_files ())
844 break;
845 if (tlink_verbose)
846 fprintf (stderr, _("collect: relinking\n"));
847 exit = tlink_execute ("ld", ld_argv, ldout, lderrout);
848 }
849 }
850
851 dump_ld_file (ldout, stdout);
852 unlink (ldout);
853 dump_ld_file (lderrout, stderr);
854 unlink (lderrout);
855 if (exit)
856 {
857 error ("ld returned %d exit status", exit);
858 collect_exit (exit);
859 }
860 else
861 {
862 /* We have just successfully produced an output file, so assume that we
863 may unlink it if need be for now on. */
864 may_unlink_output_file = true;
865 }
866 }