Ticket #39677

Compilation of gettext-0.20.1 fails with "conflicting types for '_findclose'" error

Open Date: 2019-10-15 01:47 Last Update: 2020-04-27 19:39

5 - Medium
5 - Medium
Score: 0
No votes
0.0% (0/0)
0.0% (0/0)


When compiling GNU gettext-0.20.1 with GCC-8.2.0 and mingwrt-5.2.2, I see:

mingw32-gcc -DLOCALEDIR=\"/mingw/share/locale\" -DBISON_LOCALEDIR=\"/usr/share/locale\" -DLOCALE_ALIAS_PATH=\"/mingw/share/locale\" -DUSEJAVA=1 -DGETTEXTJAR=\"/mingw/share/gettext/gettext.jar\" -DLIBDIR=\"/mingw/lib\" -DGETTEXTDATADIR=\"/mingw/share/gettext\" -DPROJECTSDIR=\"/mingw/share/gettext/projects\" -DEXEEXT=\".exe\" -DHAVE_CONFIG_H -I. -I../../../src/gettext-0.20.1/gettext-tools/src -I..  -I. -I../../../src/gettext-0.20.1/gettext-tools/src -I.. -I../../../src/gettext-0.20.1/gettext-tools -I../../../src/gettext-0.20.1/gettext-tools/libgrep -I../gnulib-lib -I../../../src/gettext-0.20.1/gettext-tools/gnulib-lib -I../intl -I../../../src/gettext-0.20.1/gettext-tools/../gettext-runtime/intl -DINSTALLDIR=\"/mingw/bin\" -I/mingw/include  -g -O2 -c -o msgfmt-write-qt.o `test -f 'write-qt.c' || echo '../../../src/gettext-0.20.1/gettext-tools/src/'`write-qt.c
In file included from ../gnulib-lib/sys/stat.h:542,
                 from ../gnulib-lib/fcntl.h:58,
                 from ../../../src/gettext-0.20.1/gettext-tools/gnulib-lib/binary-io.h:22,
                 from ../../../src/gettext-0.20.1/gettext-tools/src/write-qt.c:43:
/home/keith/mingw32-gcc-8.2.0/include/io.h:484:38: error: conflicting types for '_findclose'
 _CRTIMP __cdecl __MINGW_NOTHROW  int _findclose (intptr_t);
In file included from /home/keith/mingw32-gcc-8.2.0/include/wchar.h:254,
                 from ../gnulib-lib/wchar.h:87,
                 from /mingw/include/iconv.h:110,
                 from ../gnulib-lib/iconv.h:27,
                 from ../../../src/gettext-0.20.1/gettext-tools/src/po-charset.h:25,
                 from ../../../src/gettext-0.20.1/gettext-tools/src/write-qt.c:35:
/home/keith/mingw32-gcc-8.2.0/include/io.h:484:38: note: previous declaration of '_findclose' was here
 _CRTIMP __cdecl __MINGW_NOTHROW  int _findclose (intptr_t);
make[5]: *** [Makefile:3324: msgfmt-write-qt.o] Error 1

Ticket History (3/6 Histories)

2019-10-15 01:47 Updated by: keith
  • New Ticket "Compilation of gettext-0.20.1 fails with "conflicting types for '_findclose'" error" created
2019-10-15 04:31 Updated by: keith

On the face of it, this is a puzzling failure ... the error message shows identically the same declaration in both instances, so there really appears to be no conflict! However, re-running the failing command, with the -E option in place of -c, and the -o msgfmt-write-qt.o removed is rather more informative.

It may be noticed, even from the original error message, that <io.h> is included twice; initially by GnuLib's "iconv.h" wrapper, via <wchar.h>, and subsequently by GnuLib's "sys/stat.h" replacement. The first inclusion is selective, exposing only the subset of <io.h> content which Microsoft require to be exposed when including <wchar.h>, and thus, does not activate the _IO_H repeat-inclusion guard; the second is normal (full) inclusion, which does activate the _IO_H guard. The declaration of _findclose is exposed, supposedly identically in both passes, as does indeed appear to be the case, from inspection of the error message alone.

What isn't obvious, from the original error message, is that GnuLib introduces a conflict between the first and second inclusions of <io.h>. It may be seen, by inspection of the preprocessor output; during the first inclusion of <io.h>, _findclose is declared (correctly) thus:

  1. _CRTIMP __cdecl __MINGW_NOTHROW int _findclose (intptr_t);
However, by the time we get to the second inclusion, GnuLib has trashed the preprocessor environment, by the introduction of:
  1. typedef long int gl_intptr_t;
  2. # define intptr_t gl_intptr_t
and thus, in the second pass through <io.h>, the declaration of _findclose becomes:
  1. _CRTIMP __cdecl __MINGW_NOTHROW int _findclose (gl_intptr_t);
and GCC (correctly) rejects the change in the declared type of the function's argument.

2019-10-15 23:10 Updated by: keith

Technically, this should be classified as a GnuLib defect ... it really should not subvert the system's <stdint.h> typedef of intptr_t, (as it does in statement #2 in the second code block of the preceding comment), in cases where the system implementation has provided one. (ISO C99, and later, leave it as optional for the system implementation to provide intptr_t, but when it is provided — as it is in mingwrt — then it becomes mandatory to also provide INTPTR_MIN and INTPTR_MAX macro definitions, so GnuLib could — and should — readily check availability).

Notwithstanding that this issue arises from a GnuLib bug, its effect may be mitigated by the attached patch.

2019-10-18 08:39 Updated by: keith
  • Owner Update from (None) to keith

I pushed the proposed patch to the code repository.

2020-04-27 19:39 Updated by: keith
  • Resolution Update from None to Fixed
  • Status Update from Open to Closed

Mitigation is incorporated within mingwrt-5.3.

Attachment File List


Please login to add comment to this ticket » Login