1 1.1.1.4 mrg /* Copyright (C) 2002-2024 Free Software Foundation, Inc. 2 1.1 mrg Contributed by Andy Vaught and Paul Brook <paul (at) nowt.org> 3 1.1 mrg 4 1.1 mrg This file is part of the GNU Fortran runtime library (libgfortran). 5 1.1 mrg 6 1.1 mrg Libgfortran is free software; you can redistribute it and/or modify 7 1.1 mrg it under the terms of the GNU General Public License as published by 8 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg any later version. 10 1.1 mrg 11 1.1 mrg Libgfortran is distributed in the hope that it will be useful, 12 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg You should have received a copy of the GNU General Public License and 21 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg <http://www.gnu.org/licenses/>. */ 24 1.1 mrg 25 1.1 mrg #include "libgfortran.h" 26 1.1 mrg 27 1.1.1.2 mrg #include <string.h> 28 1.1 mrg 29 1.1 mrg #ifdef HAVE_UNISTD_H 30 1.1 mrg #include <unistd.h> 31 1.1 mrg #endif 32 1.1 mrg 33 1.1.1.2 mrg 34 1.1.1.2 mrg #if __nvptx__ 35 1.1.1.2 mrg /* Map "exit" to "abort"; see PR85463 '[nvptx] "exit" in offloaded region 36 1.1.1.2 mrg doesn't terminate process'. */ 37 1.1.1.2 mrg # undef exit 38 1.1.1.2 mrg # define exit(status) do { (void) (status); abort (); } while (0) 39 1.1.1.2 mrg #endif 40 1.1.1.2 mrg 41 1.1.1.2 mrg 42 1.1.1.2 mrg #if __nvptx__ 43 1.1.1.2 mrg /* 'printf' is all we have. */ 44 1.1.1.2 mrg # undef estr_vprintf 45 1.1.1.2 mrg # define estr_vprintf vprintf 46 1.1.1.2 mrg #else 47 1.1.1.2 mrg # error TODO 48 1.1.1.2 mrg #endif 49 1.1.1.2 mrg 50 1.1.1.2 mrg 51 1.1.1.2 mrg /* runtime/environ.c */ 52 1.1.1.2 mrg 53 1.1.1.2 mrg options_t options; 54 1.1.1.2 mrg 55 1.1.1.2 mrg 56 1.1.1.2 mrg /* runtime/main.c */ 57 1.1.1.2 mrg 58 1.1 mrg /* Stupid function to be sure the constructor is always linked in, even 59 1.1 mrg in the case of static linking. See PR libfortran/22298 for details. */ 60 1.1 mrg void 61 1.1 mrg stupid_function_name_for_static_linking (void) 62 1.1 mrg { 63 1.1 mrg return; 64 1.1 mrg } 65 1.1 mrg 66 1.1 mrg 67 1.1 mrg static int argc_save; 68 1.1 mrg static char **argv_save; 69 1.1 mrg 70 1.1.1.2 mrg 71 1.1.1.2 mrg /* Set the saved values of the command line arguments. */ 72 1.1.1.2 mrg 73 1.1.1.2 mrg void 74 1.1.1.2 mrg set_args (int argc, char **argv) 75 1.1.1.2 mrg { 76 1.1.1.2 mrg argc_save = argc; 77 1.1.1.2 mrg argv_save = argv; 78 1.1.1.2 mrg } 79 1.1.1.2 mrg iexport(set_args); 80 1.1.1.2 mrg 81 1.1.1.2 mrg 82 1.1.1.2 mrg /* Retrieve the saved values of the command line arguments. */ 83 1.1.1.2 mrg 84 1.1.1.2 mrg void 85 1.1.1.2 mrg get_args (int *argc, char ***argv) 86 1.1.1.2 mrg { 87 1.1.1.2 mrg *argc = argc_save; 88 1.1.1.2 mrg *argv = argv_save; 89 1.1.1.2 mrg } 90 1.1.1.2 mrg 91 1.1.1.2 mrg 92 1.1.1.2 mrg /* runtime/error.c */ 93 1.1.1.2 mrg 94 1.1.1.2 mrg /* Write a null-terminated C string to standard error. This function 95 1.1.1.2 mrg is async-signal-safe. */ 96 1.1.1.2 mrg 97 1.1.1.2 mrg ssize_t 98 1.1.1.2 mrg estr_write (const char *str) 99 1.1.1.2 mrg { 100 1.1.1.2 mrg return write (STDERR_FILENO, str, strlen (str)); 101 1.1.1.2 mrg } 102 1.1.1.2 mrg 103 1.1.1.2 mrg 104 1.1.1.2 mrg /* printf() like function for for printing to stderr. Uses a stack 105 1.1.1.2 mrg allocated buffer and doesn't lock stderr, so it should be safe to 106 1.1.1.2 mrg use from within a signal handler. */ 107 1.1.1.2 mrg 108 1.1.1.2 mrg int 109 1.1.1.2 mrg st_printf (const char * format, ...) 110 1.1.1.2 mrg { 111 1.1.1.2 mrg int written; 112 1.1.1.2 mrg va_list ap; 113 1.1.1.2 mrg va_start (ap, format); 114 1.1.1.2 mrg written = estr_vprintf (format, ap); 115 1.1.1.2 mrg va_end (ap); 116 1.1.1.2 mrg return written; 117 1.1.1.2 mrg } 118 1.1.1.2 mrg 119 1.1.1.2 mrg 120 1.1.1.2 mrg /* sys_abort()-- Terminate the program showing backtrace and dumping 121 1.1.1.2 mrg core. */ 122 1.1.1.2 mrg 123 1.1.1.2 mrg void 124 1.1.1.2 mrg sys_abort (void) 125 1.1.1.2 mrg { 126 1.1.1.2 mrg /* If backtracing is enabled, print backtrace and disable signal 127 1.1.1.2 mrg handler for ABRT. */ 128 1.1.1.2 mrg if (options.backtrace == 1 129 1.1.1.2 mrg || (options.backtrace == -1 && compile_options.backtrace == 1)) 130 1.1.1.2 mrg { 131 1.1.1.2 mrg estr_write ("\nProgram aborted.\n"); 132 1.1.1.2 mrg } 133 1.1.1.2 mrg 134 1.1.1.2 mrg abort(); 135 1.1.1.2 mrg } 136 1.1.1.2 mrg 137 1.1.1.2 mrg 138 1.1.1.2 mrg /* Exit in case of error termination. If backtracing is enabled, print 139 1.1.1.2 mrg backtrace, then exit. */ 140 1.1.1.2 mrg 141 1.1.1.2 mrg void 142 1.1.1.2 mrg exit_error (int status) 143 1.1.1.2 mrg { 144 1.1.1.2 mrg if (options.backtrace == 1 145 1.1.1.2 mrg || (options.backtrace == -1 && compile_options.backtrace == 1)) 146 1.1.1.2 mrg { 147 1.1.1.2 mrg estr_write ("\nError termination.\n"); 148 1.1.1.2 mrg } 149 1.1.1.2 mrg exit (status); 150 1.1.1.2 mrg } 151 1.1.1.2 mrg 152 1.1.1.2 mrg 153 1.1.1.2 mrg /* show_locus()-- Print a line number and filename describing where 154 1.1.1.2 mrg * something went wrong */ 155 1.1.1.2 mrg 156 1.1.1.2 mrg void 157 1.1.1.2 mrg show_locus (st_parameter_common *cmp) 158 1.1.1.2 mrg { 159 1.1.1.2 mrg char *filename; 160 1.1.1.2 mrg 161 1.1.1.2 mrg if (!options.locus || cmp == NULL || cmp->filename == NULL) 162 1.1.1.2 mrg return; 163 1.1.1.2 mrg 164 1.1.1.2 mrg if (cmp->unit > 0) 165 1.1.1.2 mrg { 166 1.1.1.2 mrg filename = /* TODO filename_from_unit (cmp->unit) */ NULL; 167 1.1.1.2 mrg 168 1.1.1.2 mrg if (filename != NULL) 169 1.1.1.2 mrg { 170 1.1.1.2 mrg st_printf ("At line %d of file %s (unit = %d, file = '%s')\n", 171 1.1.1.2 mrg (int) cmp->line, cmp->filename, (int) cmp->unit, filename); 172 1.1.1.2 mrg free (filename); 173 1.1.1.2 mrg } 174 1.1.1.2 mrg else 175 1.1.1.2 mrg { 176 1.1.1.2 mrg st_printf ("At line %d of file %s (unit = %d)\n", 177 1.1.1.2 mrg (int) cmp->line, cmp->filename, (int) cmp->unit); 178 1.1.1.2 mrg } 179 1.1.1.2 mrg return; 180 1.1.1.2 mrg } 181 1.1.1.2 mrg 182 1.1.1.2 mrg st_printf ("At line %d of file %s\n", (int) cmp->line, cmp->filename); 183 1.1.1.2 mrg } 184 1.1.1.2 mrg 185 1.1.1.2 mrg 186 1.1 mrg /* recursion_check()-- It's possible for additional errors to occur 187 1.1 mrg * during fatal error processing. We detect this condition here and 188 1.1 mrg * exit with code 4 immediately. */ 189 1.1 mrg 190 1.1 mrg #define MAGIC 0x20DE8101 191 1.1 mrg 192 1.1 mrg static void 193 1.1 mrg recursion_check (void) 194 1.1 mrg { 195 1.1 mrg static int magic = 0; 196 1.1 mrg 197 1.1 mrg /* Don't even try to print something at this point */ 198 1.1 mrg if (magic == MAGIC) 199 1.1 mrg sys_abort (); 200 1.1 mrg 201 1.1 mrg magic = MAGIC; 202 1.1 mrg } 203 1.1 mrg 204 1.1 mrg 205 1.1 mrg /* os_error()-- Operating system error. We get a message from the 206 1.1 mrg * operating system, show it and leave. Some operating system errors 207 1.1 mrg * are caught and processed by the library. If not, we come here. */ 208 1.1 mrg 209 1.1 mrg void 210 1.1 mrg os_error (const char *message) 211 1.1 mrg { 212 1.1 mrg recursion_check (); 213 1.1.1.2 mrg estr_write ("Operating system error: "); 214 1.1.1.2 mrg estr_write (message); 215 1.1.1.2 mrg estr_write ("\n"); 216 1.1.1.2 mrg exit_error (1); 217 1.1 mrg } 218 1.1.1.2 mrg iexport(os_error); /* TODO, DEPRECATED, ABI: Should not be exported 219 1.1.1.2 mrg anymore when bumping so version. */ 220 1.1.1.2 mrg 221 1.1.1.2 mrg 222 1.1.1.2 mrg /* Improved version of os_error with a printf style format string and 223 1.1.1.2 mrg a locus. */ 224 1.1.1.2 mrg 225 1.1.1.2 mrg void 226 1.1.1.2 mrg os_error_at (const char *where, const char *message, ...) 227 1.1.1.2 mrg { 228 1.1.1.2 mrg va_list ap; 229 1.1.1.2 mrg 230 1.1.1.2 mrg recursion_check (); 231 1.1.1.2 mrg estr_write (where); 232 1.1.1.2 mrg estr_write (": "); 233 1.1.1.2 mrg va_start (ap, message); 234 1.1.1.2 mrg estr_vprintf (message, ap); 235 1.1.1.2 mrg va_end (ap); 236 1.1.1.2 mrg estr_write ("\n"); 237 1.1.1.2 mrg exit_error (1); 238 1.1.1.2 mrg } 239 1.1.1.2 mrg iexport(os_error_at); 240 1.1 mrg 241 1.1 mrg 242 1.1 mrg /* void runtime_error()-- These are errors associated with an 243 1.1 mrg * invalid fortran program. */ 244 1.1 mrg 245 1.1 mrg void 246 1.1 mrg runtime_error (const char *message, ...) 247 1.1 mrg { 248 1.1 mrg va_list ap; 249 1.1 mrg 250 1.1 mrg recursion_check (); 251 1.1.1.2 mrg estr_write ("Fortran runtime error: "); 252 1.1 mrg va_start (ap, message); 253 1.1.1.2 mrg estr_vprintf (message, ap); 254 1.1 mrg va_end (ap); 255 1.1.1.2 mrg estr_write ("\n"); 256 1.1.1.2 mrg exit_error (2); 257 1.1 mrg } 258 1.1 mrg iexport(runtime_error); 259 1.1 mrg 260 1.1 mrg /* void runtime_error_at()-- These are errors associated with a 261 1.1 mrg * run time error generated by the front end compiler. */ 262 1.1 mrg 263 1.1 mrg void 264 1.1 mrg runtime_error_at (const char *where, const char *message, ...) 265 1.1 mrg { 266 1.1 mrg va_list ap; 267 1.1 mrg 268 1.1 mrg recursion_check (); 269 1.1.1.2 mrg estr_write (where); 270 1.1.1.2 mrg estr_write ("\nFortran runtime error: "); 271 1.1 mrg va_start (ap, message); 272 1.1.1.2 mrg estr_vprintf (message, ap); 273 1.1 mrg va_end (ap); 274 1.1.1.2 mrg estr_write ("\n"); 275 1.1.1.2 mrg exit_error (2); 276 1.1 mrg } 277 1.1 mrg iexport(runtime_error_at); 278 1.1 mrg 279 1.1 mrg 280 1.1 mrg void 281 1.1 mrg runtime_warning_at (const char *where, const char *message, ...) 282 1.1 mrg { 283 1.1 mrg va_list ap; 284 1.1 mrg 285 1.1.1.2 mrg estr_write (where); 286 1.1.1.2 mrg estr_write ("\nFortran runtime warning: "); 287 1.1 mrg va_start (ap, message); 288 1.1.1.2 mrg estr_vprintf (message, ap); 289 1.1 mrg va_end (ap); 290 1.1.1.2 mrg estr_write ("\n"); 291 1.1 mrg } 292 1.1 mrg iexport(runtime_warning_at); 293 1.1 mrg 294 1.1 mrg 295 1.1 mrg /* void internal_error()-- These are this-can't-happen errors 296 1.1 mrg * that indicate something deeply wrong. */ 297 1.1 mrg 298 1.1 mrg void 299 1.1 mrg internal_error (st_parameter_common *cmp, const char *message) 300 1.1 mrg { 301 1.1 mrg recursion_check (); 302 1.1.1.2 mrg show_locus (cmp); 303 1.1.1.2 mrg estr_write ("Internal Error: "); 304 1.1.1.2 mrg estr_write (message); 305 1.1.1.2 mrg estr_write ("\n"); 306 1.1 mrg 307 1.1 mrg /* This function call is here to get the main.o object file included 308 1.1 mrg when linking statically. This works because error.o is supposed to 309 1.1 mrg be always linked in (and the function call is in internal_error 310 1.1 mrg because hopefully it doesn't happen too often). */ 311 1.1 mrg stupid_function_name_for_static_linking(); 312 1.1 mrg 313 1.1.1.2 mrg exit_error (3); 314 1.1 mrg } 315 1.1 mrg 316 1.1 mrg 317 1.1 mrg /* runtime/stop.c */ 318 1.1 mrg 319 1.1 mrg #undef report_exception 320 1.1 mrg #define report_exception() do {} while (0) 321 1.1.1.2 mrg 322 1.1 mrg 323 1.1 mrg /* A numeric STOP statement. */ 324 1.1 mrg 325 1.1 mrg extern _Noreturn void stop_numeric (int, bool); 326 1.1 mrg export_proto(stop_numeric); 327 1.1 mrg 328 1.1 mrg void 329 1.1 mrg stop_numeric (int code, bool quiet) 330 1.1 mrg { 331 1.1 mrg if (!quiet) 332 1.1 mrg { 333 1.1 mrg report_exception (); 334 1.1 mrg st_printf ("STOP %d\n", code); 335 1.1 mrg } 336 1.1 mrg exit (code); 337 1.1 mrg } 338 1.1 mrg 339 1.1 mrg 340 1.1 mrg /* A character string or blank STOP statement. */ 341 1.1 mrg 342 1.1 mrg void 343 1.1 mrg stop_string (const char *string, size_t len, bool quiet) 344 1.1 mrg { 345 1.1 mrg if (!quiet) 346 1.1 mrg { 347 1.1 mrg report_exception (); 348 1.1 mrg if (string) 349 1.1 mrg { 350 1.1 mrg estr_write ("STOP "); 351 1.1 mrg (void) write (STDERR_FILENO, string, len); 352 1.1 mrg estr_write ("\n"); 353 1.1 mrg } 354 1.1 mrg } 355 1.1 mrg exit (0); 356 1.1 mrg } 357 1.1 mrg 358 1.1 mrg 359 1.1 mrg /* Per Fortran 2008, section 8.4: "Execution of a STOP statement initiates 360 1.1 mrg normal termination of execution. Execution of an ERROR STOP statement 361 1.1 mrg initiates error termination of execution." Thus, error_stop_string returns 362 1.1 mrg a nonzero exit status code. */ 363 1.1 mrg 364 1.1 mrg extern _Noreturn void error_stop_string (const char *, size_t, bool); 365 1.1 mrg export_proto(error_stop_string); 366 1.1 mrg 367 1.1 mrg void 368 1.1 mrg error_stop_string (const char *string, size_t len, bool quiet) 369 1.1 mrg { 370 1.1 mrg if (!quiet) 371 1.1 mrg { 372 1.1 mrg report_exception (); 373 1.1 mrg estr_write ("ERROR STOP "); 374 1.1 mrg (void) write (STDERR_FILENO, string, len); 375 1.1 mrg estr_write ("\n"); 376 1.1 mrg } 377 1.1 mrg exit_error (1); 378 1.1 mrg } 379 1.1 mrg 380 1.1 mrg 381 1.1 mrg /* A numeric ERROR STOP statement. */ 382 1.1 mrg 383 1.1 mrg extern _Noreturn void error_stop_numeric (int, bool); 384 1.1 mrg export_proto(error_stop_numeric); 385 1.1 mrg 386 1.1 mrg void 387 1.1 mrg error_stop_numeric (int code, bool quiet) 388 1.1 mrg { 389 1.1 mrg if (!quiet) 390 1.1 mrg { 391 1.1 mrg report_exception (); 392 1.1 mrg st_printf ("ERROR STOP %d\n", code); 393 1.1 mrg } 394 1.1 mrg exit_error (code); 395 1.1 mrg } 396