diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-31 05:47:39 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-31 05:47:39 +0000 |
commit | 630d47b9fe9db6b61d4f372fc305a4569da984d3 (patch) | |
tree | ca6e2960bcc231a9c0e87ab14828e7e1ee7968e2 /libgfortran | |
parent | fc41dd820f53334fd95a07641cbbd733b7b9259b (diff) | |
download | gcc-630d47b9fe9db6b61d4f372fc305a4569da984d3.tar.gz |
2011-05-31 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 174464 using svnmerge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@174466 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 24 | ||||
-rw-r--r-- | libgfortran/io/read.c | 38 | ||||
-rw-r--r-- | libgfortran/libgfortran.h | 3 | ||||
-rw-r--r-- | libgfortran/runtime/backtrace.c | 14 | ||||
-rw-r--r-- | libgfortran/runtime/compile_options.c | 11 | ||||
-rw-r--r-- | libgfortran/runtime/main.c | 39 |
6 files changed, 112 insertions, 17 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 5c1144fe000..90929219d8c 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,27 @@ +2011-05-29 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/48931 + * libgfortran.h (find_addr2line): New prototype. + * runtime/backtrace.c (show_backtrace): Use async-signal-safe + execve and stored path of addr2line. + * runtime/compile_options.c (maybe_find_addr2line): New function. + (set_options): Call maybe_find_addr2line if backtracing is enabled. + * runtime/main.c (find_addr2line): New function. + (init): Call find_addr2line if backtracing is enabled. + (cleanup): Free addr2line_path. + +2011-05-29 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/49214 + * runtime/backtrace.c (fd_gets): Return NULL if nothing was read. + +2011-05-29 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/19155 + * io/read.c (convert_real): Check for invalid input by comparing + endptr instead of EINVAL. + (read_f): Fixup floating point input without significand. + 2011-05-22 Tobias Burnus <burnus@net-b.de> * runtime/stop.c (stop_string,error_stop_string): Minor cleanup. diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c index 3ee5717e823..aa41bc7b9d2 100644 --- a/libgfortran/io/read.c +++ b/libgfortran/io/read.c @@ -1,9 +1,9 @@ -/* Copyright (C) 2002, 2003, 2005, 2007, 2008, 2009, 2010 +/* Copyright (C) 2002, 2003, 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Andy Vaught F2003 I/O support contributed by Jerry DeLisle -This file is part of the GNU Fortran 95 runtime library (libgfortran). +This file is part of the GNU Fortran runtime library (libgfortran). Libgfortran is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -131,45 +131,45 @@ max_value (int length, int signed_flag) /* convert_real()-- Convert a character representation of a floating - point number to the machine number. Returns nonzero if there is a - range problem during conversion. Note: many architectures - (e.g. IA-64, HP-PA) require that the storage pointed to by the dest - argument is properly aligned for the type in question. */ + point number to the machine number. Returns nonzero if there is an + invalid input. Note: many architectures (e.g. IA-64, HP-PA) + require that the storage pointed to by the dest argument is + properly aligned for the type in question. */ int convert_real (st_parameter_dt *dtp, void *dest, const char *buffer, int length) { - errno = 0; + char *endptr = NULL; switch (length) { case 4: *((GFC_REAL_4*) dest) = #if defined(HAVE_STRTOF) - gfc_strtof (buffer, NULL); + gfc_strtof (buffer, &endptr); #else - (GFC_REAL_4) gfc_strtod (buffer, NULL); + (GFC_REAL_4) gfc_strtod (buffer, &endptr); #endif break; case 8: - *((GFC_REAL_8*) dest) = gfc_strtod (buffer, NULL); + *((GFC_REAL_8*) dest) = gfc_strtod (buffer, &endptr); break; #if defined(HAVE_GFC_REAL_10) && defined (HAVE_STRTOLD) case 10: - *((GFC_REAL_10*) dest) = gfc_strtold (buffer, NULL); + *((GFC_REAL_10*) dest) = gfc_strtold (buffer, &endptr); break; #endif #if defined(HAVE_GFC_REAL_16) # if defined(GFC_REAL_16_IS_FLOAT128) case 16: - *((GFC_REAL_16*) dest) = __qmath_(strtoflt128) (buffer, NULL); + *((GFC_REAL_16*) dest) = __qmath_(strtoflt128) (buffer, &endptr); break; # elif defined(HAVE_STRTOLD) case 16: - *((GFC_REAL_16*) dest) = gfc_strtold (buffer, NULL); + *((GFC_REAL_16*) dest) = gfc_strtold (buffer, &endptr); break; # endif #endif @@ -178,10 +178,10 @@ convert_real (st_parameter_dt *dtp, void *dest, const char *buffer, int length) internal_error (&dtp->common, "Unsupported real kind during IO"); } - if (errno == EINVAL) + if (buffer == endptr) { generate_error (&dtp->common, LIBERROR_READ_VALUE, - "Error during floating point read"); + "Error during floating point read"); next_record (dtp, 1); return 1; } @@ -1114,6 +1114,14 @@ done: /* Output a trailing '0' after decimal point if not yet found. */ if (seen_dp && !seen_dec_digit) *(out++) = '0'; + /* Handle input of style "E+NN" by inserting a 0 for the + significand. */ + else if (!seen_int_digit && !seen_dec_digit) + { + notify_std (&dtp->common, GFC_STD_LEGACY, + "REAL input of style 'E+NN'"); + *(out++) = '0'; + } /* Print out the exponent to finish the reformatted number. Maximum 4 digits for the exponent. */ diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h index e77ba10790f..b72b250c84a 100644 --- a/libgfortran/libgfortran.h +++ b/libgfortran/libgfortran.h @@ -665,6 +665,9 @@ export_proto(store_exe_path); extern char * full_exe_path (void); internal_proto(full_exe_path); +extern void find_addr2line (void); +internal_proto(find_addr2line); + /* backtrace.c */ extern void show_backtrace (void); diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c index dff4466aa56..7d6479fe905 100644 --- a/libgfortran/runtime/backtrace.c +++ b/libgfortran/runtime/backtrace.c @@ -95,6 +95,8 @@ fd_gets (char *s, int size, int fd) else { s[i] = '\0'; + if (i == 0) + return NULL; break; } } @@ -102,6 +104,9 @@ fd_gets (char *s, int size, int fd) } +extern char *addr2line_path; + + /* show_backtrace displays the backtrace, currently obtained by means of the glibc backtrace* functions. */ @@ -122,6 +127,9 @@ show_backtrace (void) #if CAN_PIPE + if (addr2line_path == NULL) + goto fallback_noerr; + /* We attempt to extract file and line information from addr2line. */ do { @@ -144,6 +152,7 @@ show_backtrace (void) /* Child process. */ #define NUM_FIXEDARGS 7 char *arg[NUM_FIXEDARGS]; + char *newenv[] = { NULL }; close (f[0]); @@ -158,14 +167,14 @@ show_backtrace (void) _exit (1); close (f[1]); - arg[0] = (char *) "addr2line"; + arg[0] = addr2line_path; arg[1] = (char *) "-e"; arg[2] = full_exe_path (); arg[3] = (char *) "-f"; arg[4] = (char *) "-s"; arg[5] = (char *) "-C"; arg[6] = NULL; - execvp (arg[0], arg); + execve (addr2line_path, arg, newenv); _exit (1); #undef NUM_FIXEDARGS } @@ -262,6 +271,7 @@ fallback: #endif /* CAN_PIPE */ +fallback_noerr: /* Fallback to the glibc backtrace. */ estr_write ("\nBacktrace for this error:\n"); backtrace_symbols_fd (trace, depth, STDERR_FILENO); diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c index dc0da4bcb90..c3e64de33ba 100644 --- a/libgfortran/runtime/compile_options.c +++ b/libgfortran/runtime/compile_options.c @@ -58,6 +58,15 @@ backtrace_handler (int signum) } +/* Helper function for set_options because we need to access the + global variable options which is not seen in set_options. */ +static void +maybe_find_addr2line (void) +{ + if (options.backtrace == -1) + find_addr2line (); +} + /* Set the usual compile-time options. */ extern void set_options (int , int []); export_proto(set_options); @@ -131,6 +140,8 @@ set_options (int num, int options[]) #if defined(SIGXFSZ) signal (SIGXFSZ, backtrace_handler); #endif + + maybe_find_addr2line (); } #endif diff --git a/libgfortran/runtime/main.c b/libgfortran/runtime/main.c index 54d9e091ce2..bc8dab449e8 100644 --- a/libgfortran/runtime/main.c +++ b/libgfortran/runtime/main.c @@ -139,6 +139,40 @@ full_exe_path (void) } +char *addr2line_path; + +/* Find addr2line and store the path. */ + +void +find_addr2line (void) +{ +#ifdef HAVE_ACCESS +#define A2L_LEN 10 + char *path = getenv ("PATH"); + size_t n = strlen (path); + char ap[n + 1 + A2L_LEN]; + size_t ai = 0; + for (size_t i = 0; i < n; i++) + { + if (path[i] != ':') + ap[ai++] = path[i]; + else + { + ap[ai++] = '/'; + memcpy (ap + ai, "addr2line", A2L_LEN); + if (access (ap, R_OK|X_OK) == 0) + { + addr2line_path = strdup (ap); + return; + } + else + ai = 0; + } + } +#endif +} + + /* Set the saved values of the command line arguments. */ void @@ -185,6 +219,9 @@ init (void) /* if (argc > 1 && strcmp(argv[1], "--resume") == 0) resume(); */ #endif + if (options.backtrace == 1) + find_addr2line (); + random_seed_i4 (NULL, NULL, NULL); } @@ -198,4 +235,6 @@ cleanup (void) if (please_free_exe_path_when_done) free ((char *) exe_path); + + free (addr2line_path); } |