1From 6189d911a82c7763501be7c51a72fab50d7be597 Mon Sep 17 00:00:00 2001
2From: Florian Weimer <fweimer@redhat.com>
3Date: Sun, 3 Nov 2019 11:39:56 +0100
4Subject: [PATCH 09/20] Redefine _IO_iconv_t to store a single gconv step
5 pointer [BZ #25097]
6
7libio can only deal with gconv conversions which consist of a single
8step.  Not using __gconv_info simplifies the data structures somewhat.
9
10This eliminates a new GCC 10 warning about subscribing an inner
11zero-length array.
12
13Tested on x86_64-linux-gnu with mainline GCC.  Built with
14build-many-glibcs.py, also with mainline GCC.  Due to GCC PR 92039,
15there are failures left on 32-bit architectures with float128 support.
16
17Change-Id: I8b4c489b619a53154712ff32e1b6f13bb92d4203
18(cherry picked from commit 70c6e15654928c603c6d24bd01cf62e7a8e2ce9b)
19Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
20---
21 libio/fileops.c  | 30 +++++++++-----------
22 libio/iofclose.c |  4 +--
23 libio/iofwide.c  | 71 +++++++++++++++++++++++-------------------------
24 libio/libio.h    | 10 ++-----
25 4 files changed, 52 insertions(+), 63 deletions(-)
26
27diff --git a/libio/fileops.c b/libio/fileops.c
28index dd66cc67..387e8991 100644
29--- a/libio/fileops.c
30+++ b/libio/fileops.c
31@@ -331,23 +331,19 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode,
32
33 	  cc = fp->_codecvt = &fp->_wide_data->_codecvt;
34
35-	  cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
36-	  cc->__cd_in.__cd.__steps = fcts.towc;
37-
38-	  cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
39-	  cc->__cd_in.__cd.__data[0].__internal_use = 1;
40-	  cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
41-	  cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
42-
43-	  cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
44-	  cc->__cd_out.__cd.__steps = fcts.tomb;
45-
46-	  cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
47-	  cc->__cd_out.__cd.__data[0].__internal_use = 1;
48-	  cc->__cd_out.__cd.__data[0].__flags
49-	    = __GCONV_IS_LAST | __GCONV_TRANSLIT;
50-	  cc->__cd_out.__cd.__data[0].__statep =
51-	    &result->_wide_data->_IO_state;
52+	  cc->__cd_in.step = fcts.towc;
53+
54+	  cc->__cd_in.step_data.__invocation_counter = 0;
55+	  cc->__cd_in.step_data.__internal_use = 1;
56+	  cc->__cd_in.step_data.__flags = __GCONV_IS_LAST;
57+	  cc->__cd_in.step_data.__statep = &result->_wide_data->_IO_state;
58+
59+	  cc->__cd_out.step = fcts.tomb;
60+
61+	  cc->__cd_out.step_data.__invocation_counter = 0;
62+	  cc->__cd_out.step_data.__internal_use = 1;
63+	  cc->__cd_out.step_data.__flags = __GCONV_IS_LAST | __GCONV_TRANSLIT;
64+	  cc->__cd_out.step_data.__statep = &result->_wide_data->_IO_state;
65
66 	  /* From now on use the wide character callback functions.  */
67 	  _IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable;
68diff --git a/libio/iofclose.c b/libio/iofclose.c
69index 7a8b89f9..0e69c1c7 100644
70--- a/libio/iofclose.c
71+++ b/libio/iofclose.c
72@@ -62,8 +62,8 @@ _IO_new_fclose (FILE *fp)
73       struct _IO_codecvt *cc = fp->_codecvt;
74
75       __libc_lock_lock (__gconv_lock);
76-      __gconv_release_step (cc->__cd_in.__cd.__steps);
77-      __gconv_release_step (cc->__cd_out.__cd.__steps);
78+      __gconv_release_step (cc->__cd_in.step);
79+      __gconv_release_step (cc->__cd_out.step);
80       __libc_lock_unlock (__gconv_lock);
81     }
82   else
83diff --git a/libio/iofwide.c b/libio/iofwide.c
84index 0e9e7dd5..80d7cc65 100644
85--- a/libio/iofwide.c
86+++ b/libio/iofwide.c
87@@ -81,22 +81,19 @@ _IO_fwide (FILE *fp, int mode)
88 	assert (fcts.towc_nsteps == 1);
89 	assert (fcts.tomb_nsteps == 1);
90
91-	cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
92-	cc->__cd_in.__cd.__steps = fcts.towc;
93-
94-	cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
95-	cc->__cd_in.__cd.__data[0].__internal_use = 1;
96-	cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
97-	cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
98-
99-	cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
100-	cc->__cd_out.__cd.__steps = fcts.tomb;
101-
102-	cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
103-	cc->__cd_out.__cd.__data[0].__internal_use = 1;
104-	cc->__cd_out.__cd.__data[0].__flags
105-	  = __GCONV_IS_LAST | __GCONV_TRANSLIT;
106-	cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
107+	cc->__cd_in.step = fcts.towc;
108+
109+	cc->__cd_in.step_data.__invocation_counter = 0;
110+	cc->__cd_in.step_data.__internal_use = 1;
111+	cc->__cd_in.step_data.__flags = __GCONV_IS_LAST;
112+	cc->__cd_in.step_data.__statep = &fp->_wide_data->_IO_state;
113+
114+	cc->__cd_out.step = fcts.tomb;
115+
116+	cc->__cd_out.step_data.__invocation_counter = 0;
117+	cc->__cd_out.step_data.__internal_use = 1;
118+	cc->__cd_out.step_data.__flags = __GCONV_IS_LAST | __GCONV_TRANSLIT;
119+	cc->__cd_out.step_data.__statep = &fp->_wide_data->_IO_state;
120       }
121
122       /* From now on use the wide character callback functions.  */
123@@ -118,14 +115,14 @@ __libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
124 {
125   enum __codecvt_result result;
126
127-  struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps;
128+  struct __gconv_step *gs = codecvt->__cd_out.step;
129   int status;
130   size_t dummy;
131   const unsigned char *from_start_copy = (unsigned char *) from_start;
132
133-  codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start;
134-  codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end;
135-  codecvt->__cd_out.__cd.__data[0].__statep = statep;
136+  codecvt->__cd_out.step_data.__outbuf = (unsigned char *) to_start;
137+  codecvt->__cd_out.step_data.__outbufend = (unsigned char *) to_end;
138+  codecvt->__cd_out.step_data.__statep = statep;
139
140   __gconv_fct fct = gs->__fct;
141 #ifdef PTR_DEMANGLE
142@@ -134,12 +131,12 @@ __libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
143 #endif
144
145   status = DL_CALL_FCT (fct,
146-			(gs, codecvt->__cd_out.__cd.__data, &from_start_copy,
147+			(gs, &codecvt->__cd_out.step_data, &from_start_copy,
148 			 (const unsigned char *) from_end, NULL,
149 			 &dummy, 0, 0));
150
151   *from_stop = (wchar_t *) from_start_copy;
152-  *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf;
153+  *to_stop = (char *) codecvt->__cd_out.step_data.__outbuf;
154
155   switch (status)
156     {
157@@ -170,14 +167,14 @@ __libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
158 {
159   enum __codecvt_result result;
160
161-  struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps;
162+  struct __gconv_step *gs = codecvt->__cd_in.step;
163   int status;
164   size_t dummy;
165   const unsigned char *from_start_copy = (unsigned char *) from_start;
166
167-  codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_start;
168-  codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) to_end;
169-  codecvt->__cd_in.__cd.__data[0].__statep = statep;
170+  codecvt->__cd_in.step_data.__outbuf = (unsigned char *) to_start;
171+  codecvt->__cd_in.step_data.__outbufend = (unsigned char *) to_end;
172+  codecvt->__cd_in.step_data.__statep = statep;
173
174   __gconv_fct fct = gs->__fct;
175 #ifdef PTR_DEMANGLE
176@@ -186,12 +183,12 @@ __libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
177 #endif
178
179   status = DL_CALL_FCT (fct,
180-			(gs, codecvt->__cd_in.__cd.__data, &from_start_copy,
181+			(gs, &codecvt->__cd_in.step_data, &from_start_copy,
182 			 (const unsigned char *) from_end, NULL,
183 			 &dummy, 0, 0));
184
185   *from_stop = (const char *) from_start_copy;
186-  *to_stop = (wchar_t *) codecvt->__cd_in.__cd.__data[0].__outbuf;
187+  *to_stop = (wchar_t *) codecvt->__cd_in.step_data.__outbuf;
188
189   switch (status)
190     {
191@@ -218,16 +215,16 @@ int
192 __libio_codecvt_encoding (struct _IO_codecvt *codecvt)
193 {
194   /* See whether the encoding is stateful.  */
195-  if (codecvt->__cd_in.__cd.__steps[0].__stateful)
196+  if (codecvt->__cd_in.step->__stateful)
197     return -1;
198   /* Fortunately not.  Now determine the input bytes for the conversion
199      necessary for each wide character.  */
200-  if (codecvt->__cd_in.__cd.__steps[0].__min_needed_from
201-      != codecvt->__cd_in.__cd.__steps[0].__max_needed_from)
202+  if (codecvt->__cd_in.step->__min_needed_from
203+      != codecvt->__cd_in.step->__max_needed_from)
204     /* Not a constant value.  */
205     return 0;
206
207-  return codecvt->__cd_in.__cd.__steps[0].__min_needed_from;
208+  return codecvt->__cd_in.step->__min_needed_from;
209 }
210
211
212@@ -239,12 +236,12 @@ __libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
213   int result;
214   const unsigned char *cp = (const unsigned char *) from_start;
215   wchar_t to_buf[max];
216-  struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps;
217+  struct __gconv_step *gs = codecvt->__cd_in.step;
218   size_t dummy;
219
220-  codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_buf;
221-  codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) &to_buf[max];
222-  codecvt->__cd_in.__cd.__data[0].__statep = statep;
223+  codecvt->__cd_in.step_data.__outbuf = (unsigned char *) to_buf;
224+  codecvt->__cd_in.step_data.__outbufend = (unsigned char *) &to_buf[max];
225+  codecvt->__cd_in.step_data.__statep = statep;
226
227   __gconv_fct fct = gs->__fct;
228 #ifdef PTR_DEMANGLE
229@@ -253,7 +250,7 @@ __libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
230 #endif
231
232   DL_CALL_FCT (fct,
233-	       (gs, codecvt->__cd_in.__cd.__data, &cp,
234+	       (gs, &codecvt->__cd_in.step_data, &cp,
235 		(const unsigned char *) from_end, NULL,
236 		&dummy, 0, 0));
237
238diff --git a/libio/libio.h b/libio/libio.h
239index 5291bb8d..0f43de87 100644
240--- a/libio/libio.h
241+++ b/libio/libio.h
242@@ -48,14 +48,10 @@
243 #include <bits/types/wint_t.h>
244 #include <gconv.h>
245
246-typedef union
247+typedef struct
248 {
249-  struct __gconv_info __cd;
250-  struct
251-  {
252-    struct __gconv_info __cd;
253-    struct __gconv_step_data __data;
254-  } __combined;
255+  struct __gconv_step *step;
256+  struct __gconv_step_data step_data;
257 } _IO_iconv_t;
258
259 #include <shlib-compat.h>
260--
2612.20.1
262
263