libgfortran: Verify the presence of all functions for POSIX 2008 locale
authorMaciej W. Rozycki <macro@linux-mips.org>
Thu, 26 Nov 2020 17:26:43 +0000 (17:26 +0000)
committerMaciej W. Rozycki <macro@linux-mips.org>
Thu, 26 Nov 2020 17:26:43 +0000 (17:26 +0000)
While we have `configure' checks for the individual POSIX 2008 extended
locale functions we refer to and use to guard the respective call sites,
we only verify the presence of `newlocale' for our global feature enable
check.  Consequently compilation fails for targets like NetBSD that only
have partial support for POSIX 2008 locale features and in particular
lack the `uselocale' function:

.../libgfortran/io/transfer.c: In function 'data_transfer_init_worker':
.../libgfortran/io/transfer.c:3416:30: error:
'old_locale_lock' undeclared (first use in this function)
 3416 |       __gthread_mutex_lock (&old_locale_lock);
      |                              ^~~~~~~~~~~~~~~
.../libgfortran/io/transfer.c:3416:30: note: each undeclared identifier is reported only once for each function it appears in
.../libgfortran/io/transfer.c:3417:12: error:
'old_locale_ctr' undeclared (first use in this function)
 3417 |       if (!old_locale_ctr++)
      |            ^~~~~~~~~~~~~~
.../libgfortran/io/transfer.c:3419:11: error:
'old_locale' undeclared (first use in this function); did you mean 'c_locale'?
 3419 |           old_locale = setlocale (LC_NUMERIC, NULL);
      |           ^~~~~~~~~~
      |           c_locale
.../libgfortran/io/transfer.c: In function 'finalize_transfer':
.../libgfortran/io/transfer.c:4253:26: error:
'old_locale_lock' undeclared (first use in this function)
 4253 |   __gthread_mutex_lock (&old_locale_lock);
      |                          ^~~~~~~~~~~~~~~
.../libgfortran/io/transfer.c:4254:10: error:
'old_locale_ctr' undeclared (first use in this function)
 4254 |   if (!--old_locale_ctr)
      |          ^~~~~~~~~~~~~~
.../libgfortran/io/transfer.c:4256:30: error:
'old_locale' undeclared (first use in this function); did you mean 'c_locale'?
 4256 |       setlocale (LC_NUMERIC, old_locale);
      |                              ^~~~~~~~~~
      |                              c_locale
make[3]: *** [Makefile:6221: transfer.lo] Error 1

Only enable the use of POSIX 2008 extended locale features then when all
the three functions required are present, removing said build errors.

libgfortran/
* io/io.h [HAVE_NEWLOCALE]: Also check for HAVE_FREELOCALE and
HAVE_USELOCALE.
[HAVE_FREELOCALE && HAVE_NEWLOCALE && HAVE_USELOCALE]
(HAVE_POSIX_2008_LOCALE): New macro.
(st_parameter_dt) [HAVE_NEWLOCALE]: Check for
HAVE_POSIX_2008_LOCALE instead.
* io/transfer.c (data_transfer_init_worker, finalize_transfer)
[HAVE_USELOCALE]: Check for HAVE_POSIX_2008_LOCALE instead.
* io/unit.c [HAVE_NEWLOCALE]: Likewise.
(init_units) [HAVE_NEWLOCALE]: Likewise.
(close_units) [HAVE_FREELOCALE]: Likewise.
* runtime/error.c (gf_strerror) [HAVE_USELOCALE]: Likewise.

libgfortran/io/io.h
libgfortran/io/transfer.c
libgfortran/io/unit.c
libgfortran/runtime/error.c

index ab4a103787c1534be26395f366b29b4a10c473ea..b4a811384c93a6ed7bd5c09fc8042a24ffe7a1fa 100644 (file)
@@ -52,8 +52,12 @@ struct format_data;
 typedef struct fnode fnode;
 struct gfc_unit;
 
-#ifdef HAVE_NEWLOCALE
-/* We have POSIX 2008 extended locale stuff.  */
+#if defined (HAVE_FREELOCALE) && defined (HAVE_NEWLOCALE) \
+  && defined (HAVE_USELOCALE)
+/* We have POSIX 2008 extended locale stuff.  We only choose to use it
+   if all the functions required are present as some systems, e.g. NetBSD
+   do not have `uselocale'.  */
+#define HAVE_POSIX_2008_LOCALE
 extern locale_t c_locale;
 internal_proto(c_locale);
 #else
@@ -562,7 +566,7 @@ typedef struct st_parameter_dt
          char *line_buffer;
          struct format_data *fmt;
          namelist_info *ionml;
-#ifdef HAVE_NEWLOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
          locale_t old_locale;
 #endif
          /* Current position within the look-ahead line buffer.  */
index dc18bc34b3230f4e650993e76b399c311d29d51d..c36d8bca808f199319335fe95dcc44285bc9e26b 100644 (file)
@@ -3410,7 +3410,7 @@ data_transfer_init_worker (st_parameter_dt *dtp, int read_flag)
 
   if (dtp->u.p.current_unit->flags.form == FORM_FORMATTED)
     {
-#ifdef HAVE_USELOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
       dtp->u.p.old_locale = uselocale (c_locale);
 #else
       __gthread_mutex_lock (&old_locale_lock);
@@ -4243,7 +4243,7 @@ finalize_transfer (st_parameter_dt *dtp)
        }
     }
 
-#ifdef HAVE_USELOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
   if (dtp->u.p.old_locale != (locale_t) 0)
     {
       uselocale (dtp->u.p.old_locale);
index a3b0656cb9091953f7be8dd6e0f6563827200e61..faf62997b5e74eafb98dc3ebd302af9bfdbdbbca 100644 (file)
@@ -114,7 +114,7 @@ static char stdout_name[] = "stdout";
 static char stderr_name[] = "stderr";
 
 
-#ifdef HAVE_NEWLOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
 locale_t c_locale;
 #else
 /* If we don't have POSIX 2008 per-thread locales, we need to use the
@@ -586,7 +586,7 @@ init_units (void)
 {
   gfc_unit *u;
 
-#ifdef HAVE_NEWLOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
   c_locale = newlocale (0, "C", 0);
 #else
 #ifndef __GTHREAD_MUTEX_INIT
@@ -803,7 +803,7 @@ close_units (void)
 
   free (newunits);
 
-#ifdef HAVE_FREELOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
   freelocale (c_locale);
 #endif
 }
index ff6b852a07c38dec5384efebbe488ce7b02336c2..a401dbad1644dd3e5ec200a85001f9d4963600fa 100644 (file)
@@ -272,7 +272,7 @@ gf_strerror (int errnum,
     p = strerror (errnum);
   return p;
 #elif defined(HAVE_STRERROR_R)
-#ifdef HAVE_USELOCALE
+#ifdef HAVE_POSIX_2008_LOCALE
   /* Some targets (Darwin at least) have the POSIX 2008 extended
      locale functions, but not strerror_l.  So reset the per-thread
      locale here.  */