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