Skip to content

Commit

Permalink
Redefine _IO_iconv_t to store a single gconv step pointer [BZ #25097]
Browse files Browse the repository at this point in the history
libio can only deal with gconv conversions which consist of a single
step.  Not using __gconv_info simplifies the data structures somewhat.

This eliminates a new GCC 10 warning about subscribing an inner
zero-length array.

Tested on x86_64-linux-gnu with mainline GCC.  Built with
build-many-glibcs.py, also with mainline GCC.  Due to GCC PR 92039,
there are failures left on 32-bit architectures with float128 support.

Change-Id: I8b4c489b619a53154712ff32e1b6f13bb92d4203
  • Loading branch information
fweimer-rh committed Nov 13, 2019
1 parent 1574078 commit 70c6e15
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 63 deletions.
30 changes: 13 additions & 17 deletions libio/fileops.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,23 +331,19 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode,

cc = fp->_codecvt = &fp->_wide_data->_codecvt;

cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
cc->__cd_in.__cd.__steps = fcts.towc;

cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
cc->__cd_in.__cd.__data[0].__internal_use = 1;
cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;

cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
cc->__cd_out.__cd.__steps = fcts.tomb;

cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
cc->__cd_out.__cd.__data[0].__internal_use = 1;
cc->__cd_out.__cd.__data[0].__flags
= __GCONV_IS_LAST | __GCONV_TRANSLIT;
cc->__cd_out.__cd.__data[0].__statep =
&result->_wide_data->_IO_state;
cc->__cd_in.step = fcts.towc;

cc->__cd_in.step_data.__invocation_counter = 0;
cc->__cd_in.step_data.__internal_use = 1;
cc->__cd_in.step_data.__flags = __GCONV_IS_LAST;
cc->__cd_in.step_data.__statep = &result->_wide_data->_IO_state;

cc->__cd_out.step = fcts.tomb;

cc->__cd_out.step_data.__invocation_counter = 0;
cc->__cd_out.step_data.__internal_use = 1;
cc->__cd_out.step_data.__flags = __GCONV_IS_LAST | __GCONV_TRANSLIT;
cc->__cd_out.step_data.__statep = &result->_wide_data->_IO_state;

/* From now on use the wide character callback functions. */
_IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable;
Expand Down
4 changes: 2 additions & 2 deletions libio/iofclose.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ _IO_new_fclose (FILE *fp)
struct _IO_codecvt *cc = fp->_codecvt;

__libc_lock_lock (__gconv_lock);
__gconv_release_step (cc->__cd_in.__cd.__steps);
__gconv_release_step (cc->__cd_out.__cd.__steps);
__gconv_release_step (cc->__cd_in.step);
__gconv_release_step (cc->__cd_out.step);
__libc_lock_unlock (__gconv_lock);
}
else
Expand Down
71 changes: 34 additions & 37 deletions libio/iofwide.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,22 +80,19 @@ _IO_fwide (FILE *fp, int mode)
assert (fcts.towc_nsteps == 1);
assert (fcts.tomb_nsteps == 1);

cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
cc->__cd_in.__cd.__steps = fcts.towc;

cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
cc->__cd_in.__cd.__data[0].__internal_use = 1;
cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;

cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
cc->__cd_out.__cd.__steps = fcts.tomb;

cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
cc->__cd_out.__cd.__data[0].__internal_use = 1;
cc->__cd_out.__cd.__data[0].__flags
= __GCONV_IS_LAST | __GCONV_TRANSLIT;
cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
cc->__cd_in.step = fcts.towc;

cc->__cd_in.step_data.__invocation_counter = 0;
cc->__cd_in.step_data.__internal_use = 1;
cc->__cd_in.step_data.__flags = __GCONV_IS_LAST;
cc->__cd_in.step_data.__statep = &fp->_wide_data->_IO_state;

cc->__cd_out.step = fcts.tomb;

cc->__cd_out.step_data.__invocation_counter = 0;
cc->__cd_out.step_data.__internal_use = 1;
cc->__cd_out.step_data.__flags = __GCONV_IS_LAST | __GCONV_TRANSLIT;
cc->__cd_out.step_data.__statep = &fp->_wide_data->_IO_state;
}

/* From now on use the wide character callback functions. */
Expand All @@ -117,14 +114,14 @@ __libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
{
enum __codecvt_result result;

struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps;
struct __gconv_step *gs = codecvt->__cd_out.step;
int status;
size_t dummy;
const unsigned char *from_start_copy = (unsigned char *) from_start;

codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start;
codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end;
codecvt->__cd_out.__cd.__data[0].__statep = statep;
codecvt->__cd_out.step_data.__outbuf = (unsigned char *) to_start;
codecvt->__cd_out.step_data.__outbufend = (unsigned char *) to_end;
codecvt->__cd_out.step_data.__statep = statep;

__gconv_fct fct = gs->__fct;
#ifdef PTR_DEMANGLE
Expand All @@ -133,12 +130,12 @@ __libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
#endif

status = DL_CALL_FCT (fct,
(gs, codecvt->__cd_out.__cd.__data, &from_start_copy,
(gs, &codecvt->__cd_out.step_data, &from_start_copy,
(const unsigned char *) from_end, NULL,
&dummy, 0, 0));

*from_stop = (wchar_t *) from_start_copy;
*to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf;
*to_stop = (char *) codecvt->__cd_out.step_data.__outbuf;

switch (status)
{
Expand Down Expand Up @@ -169,14 +166,14 @@ __libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
{
enum __codecvt_result result;

struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps;
struct __gconv_step *gs = codecvt->__cd_in.step;
int status;
size_t dummy;
const unsigned char *from_start_copy = (unsigned char *) from_start;

codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_start;
codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) to_end;
codecvt->__cd_in.__cd.__data[0].__statep = statep;
codecvt->__cd_in.step_data.__outbuf = (unsigned char *) to_start;
codecvt->__cd_in.step_data.__outbufend = (unsigned char *) to_end;
codecvt->__cd_in.step_data.__statep = statep;

__gconv_fct fct = gs->__fct;
#ifdef PTR_DEMANGLE
Expand All @@ -185,12 +182,12 @@ __libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
#endif

status = DL_CALL_FCT (fct,
(gs, codecvt->__cd_in.__cd.__data, &from_start_copy,
(gs, &codecvt->__cd_in.step_data, &from_start_copy,
(const unsigned char *) from_end, NULL,
&dummy, 0, 0));

*from_stop = (const char *) from_start_copy;
*to_stop = (wchar_t *) codecvt->__cd_in.__cd.__data[0].__outbuf;
*to_stop = (wchar_t *) codecvt->__cd_in.step_data.__outbuf;

switch (status)
{
Expand All @@ -217,16 +214,16 @@ int
__libio_codecvt_encoding (struct _IO_codecvt *codecvt)
{
/* See whether the encoding is stateful. */
if (codecvt->__cd_in.__cd.__steps[0].__stateful)
if (codecvt->__cd_in.step->__stateful)
return -1;
/* Fortunately not. Now determine the input bytes for the conversion
necessary for each wide character. */
if (codecvt->__cd_in.__cd.__steps[0].__min_needed_from
!= codecvt->__cd_in.__cd.__steps[0].__max_needed_from)
if (codecvt->__cd_in.step->__min_needed_from
!= codecvt->__cd_in.step->__max_needed_from)
/* Not a constant value. */
return 0;

return codecvt->__cd_in.__cd.__steps[0].__min_needed_from;
return codecvt->__cd_in.step->__min_needed_from;
}


Expand All @@ -238,12 +235,12 @@ __libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
int result;
const unsigned char *cp = (const unsigned char *) from_start;
wchar_t to_buf[max];
struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps;
struct __gconv_step *gs = codecvt->__cd_in.step;
size_t dummy;

codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_buf;
codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) &to_buf[max];
codecvt->__cd_in.__cd.__data[0].__statep = statep;
codecvt->__cd_in.step_data.__outbuf = (unsigned char *) to_buf;
codecvt->__cd_in.step_data.__outbufend = (unsigned char *) &to_buf[max];
codecvt->__cd_in.step_data.__statep = statep;

__gconv_fct fct = gs->__fct;
#ifdef PTR_DEMANGLE
Expand All @@ -252,7 +249,7 @@ __libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
#endif

DL_CALL_FCT (fct,
(gs, codecvt->__cd_in.__cd.__data, &cp,
(gs, &codecvt->__cd_in.step_data, &cp,
(const unsigned char *) from_end, NULL,
&dummy, 0, 0));

Expand Down
10 changes: 3 additions & 7 deletions libio/libio.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,10 @@
#include <bits/types/wint_t.h>
#include <gconv.h>

typedef union
typedef struct
{
struct __gconv_info __cd;
struct
{
struct __gconv_info __cd;
struct __gconv_step_data __data;
} __combined;
struct __gconv_step *step;
struct __gconv_step_data step_data;
} _IO_iconv_t;

#include <shlib-compat.h>
Expand Down

0 comments on commit 70c6e15

Please sign in to comment.