summaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-31 05:47:39 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2011-05-31 05:47:39 +0000
commit630d47b9fe9db6b61d4f372fc305a4569da984d3 (patch)
treeca6e2960bcc231a9c0e87ab14828e7e1ee7968e2 /libgfortran
parentfc41dd820f53334fd95a07641cbbd733b7b9259b (diff)
downloadgcc-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/ChangeLog24
-rw-r--r--libgfortran/io/read.c38
-rw-r--r--libgfortran/libgfortran.h3
-rw-r--r--libgfortran/runtime/backtrace.c14
-rw-r--r--libgfortran/runtime/compile_options.c11
-rw-r--r--libgfortran/runtime/main.c39
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);
}