OSDN Git Service

06c144ae153e2916f50fc9529700573daa5e8206
[pf3gnuchains/gcc-fork.git] / libgfortran / runtime / error.c
1 /* Copyright (C) 2002, 2003, 2005, 2006, 2007, 2009, 2010, 2011
2    Free Software Foundation, Inc.
3    Contributed by Andy Vaught
4
5 This file is part of the GNU Fortran runtime library (libgfortran).
6
7 Libgfortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 <http://www.gnu.org/licenses/>.  */
25
26
27 #include "libgfortran.h"
28 #include <assert.h>
29 #include <string.h>
30 #include <errno.h>
31
32 #ifdef HAVE_SIGNAL_H
33 #include <signal.h>
34 #endif
35
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39
40 #ifdef HAVE_STDLIB_H
41 #include <stdlib.h>
42 #endif
43
44 #ifdef HAVE_SYS_TIME_H
45 #include <sys/time.h>
46 #endif
47
48 /* <sys/time.h> has to be included before <sys/resource.h> to work
49    around PR 30518; otherwise, MacOS 10.3.9 headers are just broken.  */
50 #ifdef HAVE_SYS_RESOURCE_H
51 #include <sys/resource.h>
52 #endif
53
54
55 #ifdef __MINGW32__
56 #define HAVE_GETPID 1
57 #include <process.h>
58 #endif
59
60
61 /* sys_exit()-- Terminate the program with an exit code.  */
62
63 void
64 sys_exit (int code)
65 {
66   /* Show error backtrace if possible.  */
67   if (code != 0 && code != 4
68       && (options.backtrace == 1
69           || (options.backtrace == -1 && compile_options.backtrace == 1)))
70     show_backtrace ();
71
72   /* Dump core if requested.  */
73   if (code != 0
74       && (options.dump_core == 1
75          || (options.dump_core == -1 && compile_options.dump_core == 1)))
76     {
77 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
78       /* Warn if a core file cannot be produced because
79          of core size limit.  */
80
81       struct rlimit core_limit;
82
83       if (getrlimit (RLIMIT_CORE, &core_limit) == 0 && core_limit.rlim_cur == 0)
84         st_printf ("** Warning: a core dump was requested, but the core size"
85                    "limit\n**          is currently zero.\n\n");
86 #endif
87       
88       
89 #if defined(HAVE_KILL) && defined(HAVE_GETPID) && defined(SIGQUIT)
90       kill (getpid (), SIGQUIT);
91 #else
92       st_printf ("Core dump not possible, sorry.");
93 #endif
94     }
95
96   exit (code);
97 }
98
99
100 /* Error conditions.  The tricky part here is printing a message when
101  * it is the I/O subsystem that is severely wounded.  Our goal is to
102  * try and print something making the fewest assumptions possible,
103  * then try to clean up before actually exiting.
104  *
105  * The following exit conditions are defined:
106  * 0    Normal program exit.
107  * 1    Terminated because of operating system error.
108  * 2    Error in the runtime library
109  * 3    Internal error in runtime library
110  * 4    Error during error processing (very bad)
111  *
112  * Other error returns are reserved for the STOP statement with a numeric code.
113  */
114
115 /* gfc_xtoa()-- Integer to hexadecimal conversion.  */
116
117 const char *
118 gfc_xtoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len)
119 {
120   int digit;
121   char *p;
122
123   assert (len >= GFC_XTOA_BUF_SIZE);
124
125   if (n == 0)
126     return "0";
127
128   p = buffer + GFC_XTOA_BUF_SIZE - 1;
129   *p = '\0';
130
131   while (n != 0)
132     {
133       digit = n & 0xF;
134       if (digit > 9)
135         digit += 'A' - '0' - 10;
136
137       *--p = '0' + digit;
138       n >>= 4;
139     }
140
141   return p;
142 }
143
144
145 /* Hopefully thread-safe wrapper for a strerror_r() style function.  */
146
147 char *
148 gf_strerror (int errnum, 
149              char * buf __attribute__((unused)), 
150              size_t buflen __attribute__((unused)))
151 {
152 #ifdef HAVE_STRERROR_R
153   /* TODO: How to prevent the compiler warning due to strerror_r of
154      the untaken branch having the wrong return type?  */
155   if (__builtin_classify_type (strerror_r (0, buf, 0)) == 5)
156     {
157       /* GNU strerror_r()  */
158       return strerror_r (errnum, buf, buflen);
159     }
160   else
161     {
162       /* POSIX strerror_r ()  */
163       strerror_r (errnum, buf, buflen);
164       return buf;
165     }
166 #else
167   /* strerror () is not necessarily thread-safe, but should at least
168      be available everywhere.  */
169   return strerror (errnum);
170 #endif
171 }
172
173
174 /* show_locus()-- Print a line number and filename describing where
175  * something went wrong */
176
177 void
178 show_locus (st_parameter_common *cmp)
179 {
180   static char *filename;
181
182   if (!options.locus || cmp == NULL || cmp->filename == NULL)
183     return;
184   
185   if (cmp->unit > 0)
186     {
187       filename = filename_from_unit (cmp->unit);
188       if (filename != NULL)
189         {
190           st_printf ("At line %d of file %s (unit = %d, file = '%s')\n",
191                    (int) cmp->line, cmp->filename, (int) cmp->unit, filename);
192           free (filename);
193         }
194       else
195         {
196           st_printf ("At line %d of file %s (unit = %d)\n",
197                    (int) cmp->line, cmp->filename, (int) cmp->unit);
198         }
199       return;
200     }
201
202   st_printf ("At line %d of file %s\n", (int) cmp->line, cmp->filename);
203 }
204
205
206 /* recursion_check()-- It's possible for additional errors to occur
207  * during fatal error processing.  We detect this condition here and
208  * exit with code 4 immediately. */
209
210 #define MAGIC 0x20DE8101
211
212 static void
213 recursion_check (void)
214 {
215   static int magic = 0;
216
217   /* Don't even try to print something at this point */
218   if (magic == MAGIC)
219     sys_exit (4);
220
221   magic = MAGIC;
222 }
223
224
225 #define STRERR_MAXSZ 256
226
227 /* os_error()-- Operating system error.  We get a message from the
228  * operating system, show it and leave.  Some operating system errors
229  * are caught and processed by the library.  If not, we come here. */
230
231 void
232 os_error (const char *message)
233 {
234   char errmsg[STRERR_MAXSZ];
235   recursion_check ();
236   st_printf ("Operating system error: %s\n%s\n", 
237              gf_strerror (errno, errmsg, STRERR_MAXSZ), message);
238   sys_exit (1);
239 }
240 iexport(os_error);
241
242
243 /* void runtime_error()-- These are errors associated with an
244  * invalid fortran program. */
245
246 void
247 runtime_error (const char *message, ...)
248 {
249   va_list ap;
250
251   recursion_check ();
252   st_printf ("Fortran runtime error: ");
253   va_start (ap, message);
254   st_vprintf (message, ap);
255   va_end (ap);
256   st_printf ("\n");
257   sys_exit (2);
258 }
259 iexport(runtime_error);
260
261 /* void runtime_error_at()-- These are errors associated with a
262  * run time error generated by the front end compiler.  */
263
264 void
265 runtime_error_at (const char *where, const char *message, ...)
266 {
267   va_list ap;
268
269   recursion_check ();
270   st_printf ("%s\n", where);
271   st_printf ("Fortran runtime error: ");
272   va_start (ap, message);
273   st_vprintf (message, ap);
274   va_end (ap);
275   st_printf ("\n");
276   sys_exit (2);
277 }
278 iexport(runtime_error_at);
279
280
281 void
282 runtime_warning_at (const char *where, const char *message, ...)
283 {
284   va_list ap;
285
286   st_printf ("%s\n", where);
287   st_printf ("Fortran runtime warning: ");
288   va_start (ap, message);
289   st_vprintf (message, ap);
290   va_end (ap);
291   st_printf ("\n");
292 }
293 iexport(runtime_warning_at);
294
295
296 /* void internal_error()-- These are this-can't-happen errors
297  * that indicate something deeply wrong. */
298
299 void
300 internal_error (st_parameter_common *cmp, const char *message)
301 {
302   recursion_check ();
303   show_locus (cmp);
304   st_printf ("Internal Error: %s\n", message);
305
306   /* This function call is here to get the main.o object file included
307      when linking statically. This works because error.o is supposed to
308      be always linked in (and the function call is in internal_error
309      because hopefully it doesn't happen too often).  */
310   stupid_function_name_for_static_linking();
311
312   sys_exit (3);
313 }
314
315
316 /* translate_error()-- Given an integer error code, return a string
317  * describing the error. */
318
319 const char *
320 translate_error (int code)
321 {
322   const char *p;
323
324   switch (code)
325     {
326     case LIBERROR_EOR:
327       p = "End of record";
328       break;
329
330     case LIBERROR_END:
331       p = "End of file";
332       break;
333
334     case LIBERROR_OK:
335       p = "Successful return";
336       break;
337
338     case LIBERROR_OS:
339       p = "Operating system error";
340       break;
341
342     case LIBERROR_BAD_OPTION:
343       p = "Bad statement option";
344       break;
345
346     case LIBERROR_MISSING_OPTION:
347       p = "Missing statement option";
348       break;
349
350     case LIBERROR_OPTION_CONFLICT:
351       p = "Conflicting statement options";
352       break;
353
354     case LIBERROR_ALREADY_OPEN:
355       p = "File already opened in another unit";
356       break;
357
358     case LIBERROR_BAD_UNIT:
359       p = "Unattached unit";
360       break;
361
362     case LIBERROR_FORMAT:
363       p = "FORMAT error";
364       break;
365
366     case LIBERROR_BAD_ACTION:
367       p = "Incorrect ACTION specified";
368       break;
369
370     case LIBERROR_ENDFILE:
371       p = "Read past ENDFILE record";
372       break;
373
374     case LIBERROR_BAD_US:
375       p = "Corrupt unformatted sequential file";
376       break;
377
378     case LIBERROR_READ_VALUE:
379       p = "Bad value during read";
380       break;
381
382     case LIBERROR_READ_OVERFLOW:
383       p = "Numeric overflow on read";
384       break;
385
386     case LIBERROR_INTERNAL:
387       p = "Internal error in run-time library";
388       break;
389
390     case LIBERROR_INTERNAL_UNIT:
391       p = "Internal unit I/O error";
392       break;
393
394     case LIBERROR_DIRECT_EOR:
395       p = "Write exceeds length of DIRECT access record";
396       break;
397
398     case LIBERROR_SHORT_RECORD:
399       p = "I/O past end of record on unformatted file";
400       break;
401
402     case LIBERROR_CORRUPT_FILE:
403       p = "Unformatted file structure has been corrupted";
404       break;
405
406     default:
407       p = "Unknown error code";
408       break;
409     }
410
411   return p;
412 }
413
414
415 /* generate_error()-- Come here when an error happens.  This
416  * subroutine is called if it is possible to continue on after the error.
417  * If an IOSTAT or IOMSG variable exists, we set it.  If IOSTAT or
418  * ERR labels are present, we return, otherwise we terminate the program
419  * after printing a message.  The error code is always required but the
420  * message parameter can be NULL, in which case a string describing
421  * the most recent operating system error is used. */
422
423 void
424 generate_error (st_parameter_common *cmp, int family, const char *message)
425 {
426   char errmsg[STRERR_MAXSZ];
427
428   /* If there was a previous error, don't mask it with another
429      error message, EOF or EOR condition.  */
430
431   if ((cmp->flags & IOPARM_LIBRETURN_MASK) == IOPARM_LIBRETURN_ERROR)
432     return;
433
434   /* Set the error status.  */
435   if ((cmp->flags & IOPARM_HAS_IOSTAT))
436     *cmp->iostat = (family == LIBERROR_OS) ? errno : family;
437
438   if (message == NULL)
439     message =
440       (family == LIBERROR_OS) ? gf_strerror (errno, errmsg, STRERR_MAXSZ) :
441       translate_error (family);
442
443   if (cmp->flags & IOPARM_HAS_IOMSG)
444     cf_strcpy (cmp->iomsg, cmp->iomsg_len, message);
445
446   /* Report status back to the compiler.  */
447   cmp->flags &= ~IOPARM_LIBRETURN_MASK;
448   switch (family)
449     {
450     case LIBERROR_EOR:
451       cmp->flags |= IOPARM_LIBRETURN_EOR;
452       if ((cmp->flags & IOPARM_EOR))
453         return;
454       break;
455
456     case LIBERROR_END:
457       cmp->flags |= IOPARM_LIBRETURN_END;
458       if ((cmp->flags & IOPARM_END))
459         return;
460       break;
461
462     default:
463       cmp->flags |= IOPARM_LIBRETURN_ERROR;
464       if ((cmp->flags & IOPARM_ERR))
465         return;
466       break;
467     }
468
469   /* Return if the user supplied an iostat variable.  */
470   if ((cmp->flags & IOPARM_HAS_IOSTAT))
471     return;
472
473   /* Terminate the program */
474
475   recursion_check ();
476   show_locus (cmp);
477   st_printf ("Fortran runtime error: %s\n", message);
478   sys_exit (2);
479 }
480 iexport(generate_error);
481
482
483 /* generate_warning()-- Similar to generate_error but just give a warning.  */
484
485 void
486 generate_warning (st_parameter_common *cmp, const char *message)
487 {
488   if (message == NULL)
489     message = " ";
490
491   show_locus (cmp);
492   st_printf ("Fortran runtime warning: %s\n", message);
493 }
494
495
496 /* Whether, for a feature included in a given standard set (GFC_STD_*),
497    we should issue an error or a warning, or be quiet.  */
498
499 notification
500 notification_std (int std)
501 {
502   int warning;
503
504   if (!compile_options.pedantic)
505     return NOTIFICATION_SILENT;
506
507   warning = compile_options.warn_std & std;
508   if ((compile_options.allow_std & std) != 0 && !warning)
509     return NOTIFICATION_SILENT;
510
511   return warning ? NOTIFICATION_WARNING : NOTIFICATION_ERROR;
512 }
513
514
515 /* Possibly issue a warning/error about use of a nonstandard (or deleted)
516    feature.  An error/warning will be issued if the currently selected
517    standard does not contain the requested bits.  */
518
519 try
520 notify_std (st_parameter_common *cmp, int std, const char * message)
521 {
522   int warning;
523
524   if (!compile_options.pedantic)
525     return SUCCESS;
526
527   warning = compile_options.warn_std & std;
528   if ((compile_options.allow_std & std) != 0 && !warning)
529     return SUCCESS;
530
531   if (!warning)
532     {
533       recursion_check ();
534       show_locus (cmp);
535       st_printf ("Fortran runtime error: %s\n", message);
536       sys_exit (2);
537     }
538   else
539     {
540       show_locus (cmp);
541       st_printf ("Fortran runtime warning: %s\n", message);
542     }
543   return FAILURE;
544 }