about summary refs log tree commit diff
path: root/wcsmbs
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2022-05-23 10:08:18 +0200
committerFlorian Weimer <fweimer@redhat.com>2022-05-23 11:06:31 +0200
commit7ee41feba6b834d9e17e634bfbf222c4d8dd1a4f (patch)
treecae31634fe857b963791bf3697bdae20312acc2e /wcsmbs
parentbbebe83a2874cd25934046d908824dfc11711a2b (diff)
downloadglibc-7ee41feba6b834d9e17e634bfbf222c4d8dd1a4f.tar.gz
glibc-7ee41feba6b834d9e17e634bfbf222c4d8dd1a4f.tar.xz
glibc-7ee41feba6b834d9e17e634bfbf222c4d8dd1a4f.zip
locale: Remove private union from struct __locale_data
This avoids an alias violation later.  This commit also fixes
an incorrect double-checked locking idiom in _nl_init_era_entries.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Diffstat (limited to 'wcsmbs')
-rw-r--r--wcsmbs/wcsmbsload.c10
-rw-r--r--wcsmbs/wcsmbsload.h8
2 files changed, 10 insertions, 8 deletions
diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c
index af539a099a..2650834e29 100644
--- a/wcsmbs/wcsmbsload.c
+++ b/wcsmbs/wcsmbsload.c
@@ -155,7 +155,7 @@ __wcsmbs_load_conv (struct __locale_data *new_category)
 
   /* We should repeat the test since while we waited some other thread
      might have run this function.  */
-  if (__glibc_likely (new_category->private.ctype == NULL))
+  if (__glibc_likely (new_category->private == NULL))
     {
       /* We must find the real functions.  */
       const char *charset_name;
@@ -199,10 +199,10 @@ __wcsmbs_load_conv (struct __locale_data *new_category)
 	  free (new_fcts);
 
 	failed:
-	  new_category->private.ctype = &__wcsmbs_gconv_fcts_c;
+	  new_category->private = (void *) &__wcsmbs_gconv_fcts_c;
 	}
       else
-	new_category->private.ctype = new_fcts;
+	new_category->private = new_fcts;
     }
 
   __libc_rwlock_unlock (__libc_setlocale_lock);
@@ -263,10 +263,10 @@ __wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
 void
 _nl_cleanup_ctype (struct __locale_data *locale)
 {
-  const struct gconv_fcts *const data = locale->private.ctype;
+  const struct gconv_fcts *const data = locale->private;
   if (data != NULL && data != &__wcsmbs_gconv_fcts_c)
     {
-      locale->private.ctype = NULL;
+      locale->private = NULL;
 
       /* Free the old conversions.  */
       __gconv_close_transform (data->tomb, data->tomb_nsteps);
diff --git a/wcsmbs/wcsmbsload.h b/wcsmbs/wcsmbsload.h
index 1ff51e0f8a..8bbd34ba02 100644
--- a/wcsmbs/wcsmbsload.h
+++ b/wcsmbs/wcsmbsload.h
@@ -66,13 +66,15 @@ extern const struct __locale_data _nl_C_LC_CTYPE attribute_hidden;
 static inline const struct gconv_fcts *
 get_gconv_fcts (struct __locale_data *data)
 {
-  if (__glibc_unlikely (data->private.ctype == NULL))
+  struct gconv_fcts *private = data->private;
+  if (private == NULL)
     {
-      if (__glibc_unlikely (data == &_nl_C_LC_CTYPE))
+      if (data == &_nl_C_LC_CTYPE)
 	return &__wcsmbs_gconv_fcts_c;
       __wcsmbs_load_conv (data);
+      private = data->private;
     }
-  return data->private.ctype;
+  return private;
 }
 
 #endif	/* wcsmbsload.h */