From patchwork Sat Mar 12 16:01:44 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John David Anglin X-Patchwork-Id: 86525 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 291E2B6F12 for ; Sun, 13 Mar 2011 03:01:56 +1100 (EST) Received: (qmail 10718 invoked by alias); 12 Mar 2011 16:01:54 -0000 Received: (qmail 10690 invoked by uid 22791); 12 Mar 2011 16:01:52 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from hiauly1.hia.nrc.ca (HELO hiauly1.hia.nrc.ca) (132.246.10.84) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 12 Mar 2011 16:01:47 +0000 Received: by hiauly1.hia.nrc.ca (Postfix, from userid 1000) id 0B4684FDE; Sat, 12 Mar 2011 11:01:44 -0500 (EST) Subject: Re: [PATCH] Fix hpux10 string to real conversion defficiences To: jvdelisle@verizon.net (Jerry DeLisle) Date: Sat, 12 Mar 2011 11:01:44 -0500 (EST) From: "John David Anglin" Cc: fxcoudert@gmail.com, gcc-patches@gcc.gnu.org, fortran@gcc.gnu.org, burnus@net-b.de In-Reply-To: <1207971887.2938.35.camel@lenova.localdomain> from "Jerry DeLisle" at Apr 11, 2008 08:44:47 pm MIME-Version: 1.0 Message-Id: <20110312160145.0B4684FDE@hiauly1.hia.nrc.ca> Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org > I have reviewed the patch and FX'scomments. So far so good. > > I may have missed something in the thread, but are you planning > modifications to the functions that call convert_real to allow the nan > or inf strings to be passed to convert_real? > > The read_real function is already handling this for namelist and list > directed reads and I believe it is not needed by convert_real for those > functions. > > For formatted reads, read_f will error out on a nan or inf during the > read before calling convert_real. Here is take three. The configure checks are eliminated and a new function, convert_infnan, is added to convert INFs and NANs using builtins. It relies to some extent on the processing done by read_f, parse_real and read_real. Tested on hppa1.1-hp-hpux10.20, hppa2.0w-hp-hpux11.11, hppa64-hp-hpux11.11 and i686-apple-darwin9 with no observed regressions. Ok? Dave Index: io/list_read.c =================================================================== --- io/list_read.c (revision 170842) +++ io/list_read.c (working copy) @@ -1215,6 +1215,15 @@ return m; + done_infnan: + unget_char (dtp, c); + push_char (dtp, '\0'); + + m = convert_infnan (dtp, buffer, dtp->u.p.saved_string, length); + free_saved (dtp); + + return m; + inf_nan: /* Match INF and Infinity. */ if ((c == 'i' || c == 'I') @@ -1235,7 +1244,7 @@ push_char (dtp, 'i'); push_char (dtp, 'n'); push_char (dtp, 'f'); - goto done; + goto done_infnan; } } /* Match NaN. */ else if (((c = next_char (dtp)) == 'a' || c == 'A') @@ -1259,7 +1268,7 @@ if (is_separator (c)) unget_char (dtp, c); } - goto done; + goto done_infnan; } bad: @@ -1718,8 +1727,16 @@ } free_line (dtp); - goto done; + unget_char (dtp, c); + eat_separator (dtp); + push_char (dtp, '\0'); + if (convert_infnan (dtp, dest, dtp->u.p.saved_string, length)) + return; + free_saved (dtp); + dtp->u.p.saved_type = BT_REAL; + return; + unwind: if (dtp->u.p.namelist_mode) { Index: io/read.c =================================================================== --- io/read.c (revision 170842) +++ io/read.c (working copy) @@ -189,7 +189,76 @@ return 0; } +/* convert_infnan()-- Convert character INF/NAN representation to the + machine number. 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_infnan (st_parameter_dt *dtp, void *dest, const char *buffer, + int length) +{ + const char *s = buffer; + int is_inf, plus = 1; + + if (*s == '+') + s++; + else if (*s == '-') + { + s++; + plus = 0; + } + + is_inf = *s == 'i'; + + switch (length) + { + case 4: + if (is_inf) + *((GFC_REAL_4*) dest) = plus ? __builtin_inff () : -__builtin_inff (); + else + *((GFC_REAL_4*) dest) = plus ? __builtin_nanf ("") : -__builtin_nanf (""); + break; + + case 8: + if (is_inf) + *((GFC_REAL_8*) dest) = plus ? __builtin_inf () : -__builtin_inf (); + else + *((GFC_REAL_8*) dest) = plus ? __builtin_nan ("") : -__builtin_nan (""); + break; + +#if defined(HAVE_GFC_REAL_10) + case 10: + if (is_inf) + *((GFC_REAL_10*) dest) = plus ? __builtin_infl () : -__builtin_infl (); + else + *((GFC_REAL_10*) dest) = plus ? __builtin_nanl ("") : -__builtin_nanl (""); + 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); + break; +# else + case 16: + if (is_inf) + *((GFC_REAL_16*) dest) = plus ? __builtin_infl () : -__builtin_infl (); + else + *((GFC_REAL_16*) dest) = plus ? __builtin_nanl ("") : -__builtin_nanl (""); + break; +# endif +#endif + + default: + internal_error (&dtp->common, "Unsupported real kind during IO"); + } + + return 0; +} + + /* read_l()-- Read a logical value */ void @@ -896,7 +965,7 @@ else if (strcmp (save, "nan") != 0) goto bad_float; - convert_real (dtp, dest, buffer, length); + convert_infnan (dtp, dest, buffer, length); return; } Index: io/io.h =================================================================== --- io/io.h (revision 170842) +++ io/io.h (working copy) @@ -674,6 +674,9 @@ extern int convert_real (st_parameter_dt *, void *, const char *, int); internal_proto(convert_real); +extern int convert_infnan (st_parameter_dt *, void *, const char *, int); +internal_proto(convert_infnan); + extern void read_a (st_parameter_dt *, const fnode *, char *, int); internal_proto(read_a);