Fix memory barrier patterns for pre PA8800 processors
[official-gcc.git] / libgfortran / runtime / minimal.c
blob81d911592fc894fe048de508097b9837bb175549
1 /* Copyright (C) 2002-2023 Free Software Foundation, Inc.
2 Contributed by Andy Vaught and Paul Brook <paul@nowt.org>
4 This file is part of the GNU Fortran runtime library (libgfortran).
6 Libgfortran is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 Libgfortran is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
25 #include "libgfortran.h"
27 #include <string.h>
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
34 #if __nvptx__
35 /* Map "exit" to "abort"; see PR85463 '[nvptx] "exit" in offloaded region
36 doesn't terminate process'. */
37 # undef exit
38 # define exit(status) do { (void) (status); abort (); } while (0)
39 #endif
42 #if __nvptx__
43 /* 'printf' is all we have. */
44 # undef estr_vprintf
45 # define estr_vprintf vprintf
46 #else
47 # error TODO
48 #endif
51 /* runtime/environ.c */
53 options_t options;
56 /* runtime/main.c */
58 /* Stupid function to be sure the constructor is always linked in, even
59 in the case of static linking. See PR libfortran/22298 for details. */
60 void
61 stupid_function_name_for_static_linking (void)
63 return;
67 static int argc_save;
68 static char **argv_save;
71 /* Set the saved values of the command line arguments. */
73 void
74 set_args (int argc, char **argv)
76 argc_save = argc;
77 argv_save = argv;
79 iexport(set_args);
82 /* Retrieve the saved values of the command line arguments. */
84 void
85 get_args (int *argc, char ***argv)
87 *argc = argc_save;
88 *argv = argv_save;
92 /* runtime/error.c */
94 /* Write a null-terminated C string to standard error. This function
95 is async-signal-safe. */
97 ssize_t
98 estr_write (const char *str)
100 return write (STDERR_FILENO, str, strlen (str));
104 /* printf() like function for for printing to stderr. Uses a stack
105 allocated buffer and doesn't lock stderr, so it should be safe to
106 use from within a signal handler. */
109 st_printf (const char * format, ...)
111 int written;
112 va_list ap;
113 va_start (ap, format);
114 written = estr_vprintf (format, ap);
115 va_end (ap);
116 return written;
120 /* sys_abort()-- Terminate the program showing backtrace and dumping
121 core. */
123 void
124 sys_abort (void)
126 /* If backtracing is enabled, print backtrace and disable signal
127 handler for ABRT. */
128 if (options.backtrace == 1
129 || (options.backtrace == -1 && compile_options.backtrace == 1))
131 estr_write ("\nProgram aborted.\n");
134 abort();
138 /* Exit in case of error termination. If backtracing is enabled, print
139 backtrace, then exit. */
141 void
142 exit_error (int status)
144 if (options.backtrace == 1
145 || (options.backtrace == -1 && compile_options.backtrace == 1))
147 estr_write ("\nError termination.\n");
149 exit (status);
153 /* show_locus()-- Print a line number and filename describing where
154 * something went wrong */
156 void
157 show_locus (st_parameter_common *cmp)
159 char *filename;
161 if (!options.locus || cmp == NULL || cmp->filename == NULL)
162 return;
164 if (cmp->unit > 0)
166 filename = /* TODO filename_from_unit (cmp->unit) */ NULL;
168 if (filename != NULL)
170 st_printf ("At line %d of file %s (unit = %d, file = '%s')\n",
171 (int) cmp->line, cmp->filename, (int) cmp->unit, filename);
172 free (filename);
174 else
176 st_printf ("At line %d of file %s (unit = %d)\n",
177 (int) cmp->line, cmp->filename, (int) cmp->unit);
179 return;
182 st_printf ("At line %d of file %s\n", (int) cmp->line, cmp->filename);
186 /* recursion_check()-- It's possible for additional errors to occur
187 * during fatal error processing. We detect this condition here and
188 * exit with code 4 immediately. */
190 #define MAGIC 0x20DE8101
192 static void
193 recursion_check (void)
195 static int magic = 0;
197 /* Don't even try to print something at this point */
198 if (magic == MAGIC)
199 sys_abort ();
201 magic = MAGIC;
205 /* os_error()-- Operating system error. We get a message from the
206 * operating system, show it and leave. Some operating system errors
207 * are caught and processed by the library. If not, we come here. */
209 void
210 os_error (const char *message)
212 recursion_check ();
213 estr_write ("Operating system error: ");
214 estr_write (message);
215 estr_write ("\n");
216 exit_error (1);
218 iexport(os_error); /* TODO, DEPRECATED, ABI: Should not be exported
219 anymore when bumping so version. */
222 /* Improved version of os_error with a printf style format string and
223 a locus. */
225 void
226 os_error_at (const char *where, const char *message, ...)
228 va_list ap;
230 recursion_check ();
231 estr_write (where);
232 estr_write (": ");
233 va_start (ap, message);
234 estr_vprintf (message, ap);
235 va_end (ap);
236 estr_write ("\n");
237 exit_error (1);
239 iexport(os_error_at);
242 /* void runtime_error()-- These are errors associated with an
243 * invalid fortran program. */
245 void
246 runtime_error (const char *message, ...)
248 va_list ap;
250 recursion_check ();
251 estr_write ("Fortran runtime error: ");
252 va_start (ap, message);
253 estr_vprintf (message, ap);
254 va_end (ap);
255 estr_write ("\n");
256 exit_error (2);
258 iexport(runtime_error);
260 /* void runtime_error_at()-- These are errors associated with a
261 * run time error generated by the front end compiler. */
263 void
264 runtime_error_at (const char *where, const char *message, ...)
266 va_list ap;
268 recursion_check ();
269 estr_write (where);
270 estr_write ("\nFortran runtime error: ");
271 va_start (ap, message);
272 estr_vprintf (message, ap);
273 va_end (ap);
274 estr_write ("\n");
275 exit_error (2);
277 iexport(runtime_error_at);
280 void
281 runtime_warning_at (const char *where, const char *message, ...)
283 va_list ap;
285 estr_write (where);
286 estr_write ("\nFortran runtime warning: ");
287 va_start (ap, message);
288 estr_vprintf (message, ap);
289 va_end (ap);
290 estr_write ("\n");
292 iexport(runtime_warning_at);
295 /* void internal_error()-- These are this-can't-happen errors
296 * that indicate something deeply wrong. */
298 void
299 internal_error (st_parameter_common *cmp, const char *message)
301 recursion_check ();
302 show_locus (cmp);
303 estr_write ("Internal Error: ");
304 estr_write (message);
305 estr_write ("\n");
307 /* This function call is here to get the main.o object file included
308 when linking statically. This works because error.o is supposed to
309 be always linked in (and the function call is in internal_error
310 because hopefully it doesn't happen too often). */
311 stupid_function_name_for_static_linking();
313 exit_error (3);
317 /* runtime/stop.c */
319 #undef report_exception
320 #define report_exception() do {} while (0)
323 /* A numeric STOP statement. */
325 extern _Noreturn void stop_numeric (int, bool);
326 export_proto(stop_numeric);
328 void
329 stop_numeric (int code, bool quiet)
331 if (!quiet)
333 report_exception ();
334 st_printf ("STOP %d\n", code);
336 exit (code);
340 /* A character string or blank STOP statement. */
342 void
343 stop_string (const char *string, size_t len, bool quiet)
345 if (!quiet)
347 report_exception ();
348 if (string)
350 estr_write ("STOP ");
351 (void) write (STDERR_FILENO, string, len);
352 estr_write ("\n");
355 exit (0);
359 /* Per Fortran 2008, section 8.4: "Execution of a STOP statement initiates
360 normal termination of execution. Execution of an ERROR STOP statement
361 initiates error termination of execution." Thus, error_stop_string returns
362 a nonzero exit status code. */
364 extern _Noreturn void error_stop_string (const char *, size_t, bool);
365 export_proto(error_stop_string);
367 void
368 error_stop_string (const char *string, size_t len, bool quiet)
370 if (!quiet)
372 report_exception ();
373 estr_write ("ERROR STOP ");
374 (void) write (STDERR_FILENO, string, len);
375 estr_write ("\n");
377 exit_error (1);
381 /* A numeric ERROR STOP statement. */
383 extern _Noreturn void error_stop_numeric (int, bool);
384 export_proto(error_stop_numeric);
386 void
387 error_stop_numeric (int code, bool quiet)
389 if (!quiet)
391 report_exception ();
392 st_printf ("ERROR STOP %d\n", code);
394 exit_error (code);