On a recent Haiku/x86_64, a gnulib testdir fails to compile: In file included from ../../gltests/test-uchar.c:23: ../../gltests/../gllib/verify.h:216:41: error: static assertion failed: "verify ((char16_t)(-1) >= 0)" # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) ^~~~~~~~~~~~~~ ../../gltests/../gllib/verify.h:276:20: note: in expansion of macro '_GL_VERIFY' # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) ^~~~~~~~~~ ../../gltests/test-uchar.c:32:1: note: in expansion of macro 'verify' verify ((char16_t)(-1) >= 0); ^~~~~~ ../../gltests/../gllib/verify.h:216:41: error: static assertion failed: "verify ((char32_t)(-1) >= 0)" # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) ^~~~~~~~~~~~~~ ../../gltests/../gllib/verify.h:276:20: note: in expansion of macro '_GL_VERIFY' # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) ^~~~~~~~~~ ../../gltests/test-uchar.c:34:1: note: in expansion of macro 'verify' verify ((char32_t)(-1) >= 0); ^~~~~~
The reason is that the char16_t and char32_t types are incorrectly defined. Reported at <https://dev.haiku-os.org/ticket/15990>. But since the bug exists already for two years and is fatal, let me add a workaround. 2020-05-09 Bruno Haible <br...@clisp.org> uchar: Work around incorrect char16_t, char32_t types on Haiku 2020. * lib/uchar.in.h (char16_t): Define as macro if GNULIB_OVERRIDES_CHAR16_T. (char32_t): Define as macro if GNULIB_OVERRIDES_CHAR32_T. * m4/uchar.m4 (gl_TYPE_CHAR16_T, gl_TYPE_CHAR32_T): New macros. (gl_UCHAR_H): Invoke them. (gl_UCHAR_H_DEFAULTS): Initialize GNULIB_OVERRIDES_CHAR16_T, GNULIB_OVERRIDES_CHAR32_T. * m4/mbrtoc32.m4 (gl_FUNC_MBRTOC32, gl_MBRTOC32_SANITYCHECK): Require gl_TYPE_CHAR32_T and test GNULIB_OVERRIDES_CHAR32_T. * modules/uchar (Makefile.am): Substitute GNULIB_OVERRIDES_CHAR16_T, GNULIB_OVERRIDES_CHAR32_T. diff --git a/lib/uchar.in.h b/lib/uchar.in.h index 9c76cc9..b77116d 100644 --- a/lib/uchar.in.h +++ b/lib/uchar.in.h @@ -47,11 +47,25 @@ on which __STDC_UTF_16__ is defined.) */ typedef uint_least16_t char16_t; +#elif @GNULIB_OVERRIDES_CHAR16_T@ + +typedef uint_least16_t gl_char16_t; +# define char16_t gl_char16_t + +#endif + +#if !@HAVE_UCHAR_H@ + /* A 32-bit variant of wchar_t. Note: This type does *NOT* denote UTF-32 code points. (Only on platforms on which __STDC_UTF_32__ is defined.) */ typedef uint_least32_t char32_t; +#elif @GNULIB_OVERRIDES_CHAR32_T@ + +typedef uint_least32_t gl_char32_t; +# define char32_t gl_char32_t + #endif /* Define if a 'char32_t' can hold more characters than a 'wchar_t'. */ diff --git a/m4/mbrtoc32.m4 b/m4/mbrtoc32.m4 index 991bbc8..5b5e938 100644 --- a/m4/mbrtoc32.m4 +++ b/m4/mbrtoc32.m4 @@ -1,4 +1,4 @@ -# mbrtoc32.m4 serial 4 +# mbrtoc32.m4 serial 5 dnl Copyright (C) 2014-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -11,13 +11,14 @@ AC_DEFUN([gl_FUNC_MBRTOC32], AC_REQUIRE([AC_TYPE_MBSTATE_T]) gl_MBSTATE_T_BROKEN + AC_REQUIRE([gl_TYPE_CHAR32_T]) AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) AC_REQUIRE([gl_CHECK_FUNC_MBRTOC32]) if test $gl_cv_func_mbrtoc32 = no; then HAVE_MBRTOC32=0 else - if test $REPLACE_MBSTATE_T = 1; then + if test $GNULIB_OVERRIDES_CHAR32_T = 1 || test $REPLACE_MBSTATE_T = 1; then REPLACE_MBRTOC32=1 else gl_MBRTOC32_EMPTY_INPUT @@ -141,11 +142,12 @@ dnl Result is HAVE_WORKING_MBRTOC32. AC_DEFUN([gl_MBRTOC32_SANITYCHECK], [ AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_TYPE_CHAR32_T]) AC_REQUIRE([gl_CHECK_FUNC_MBRTOC32]) AC_REQUIRE([gt_LOCALE_FR]) AC_REQUIRE([gt_LOCALE_ZH_CN]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - if test $gl_cv_func_mbrtoc32 = no; then + if test $GNULIB_OVERRIDES_CHAR32_T = 1 || test $gl_cv_func_mbrtoc32 = no; then HAVE_WORKING_MBRTOC32=0 else AC_CACHE_CHECK([whether mbrtoc32 works as well as mbrtowc], diff --git a/m4/uchar.m4 b/m4/uchar.m4 index 63d8b13..0875caa 100644 --- a/m4/uchar.m4 +++ b/m4/uchar.m4 @@ -1,4 +1,4 @@ -# uchar.m4 serial 13 +# uchar.m4 serial 14 dnl Copyright (C) 2019-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -19,6 +19,9 @@ AC_DEFUN_ONCE([gl_UCHAR_H], fi AC_SUBST([HAVE_UCHAR_H]) + gl_TYPE_CHAR16_T + gl_TYPE_CHAR32_T + dnl Test whether a 'char32_t' can hold more characters than a 'wchar_t'. gl_STDINT_BITSIZEOF([wchar_t], [gl_STDINT_INCLUDES]) if test $BITSIZEOF_WCHAR_T -lt 32; then @@ -36,6 +39,51 @@ AC_DEFUN_ONCE([gl_UCHAR_H], ]], [c32rtomb mbrtoc32]) ]) +dnl On Haiku 2020, char16_t and char32_t are incorrectly defined. +dnl See <https://dev.haiku-os.org/ticket/15990>. +AC_DEFUN_ONCE([gl_TYPE_CHAR16_T], +[ + AC_REQUIRE([gl_UCHAR_H_DEFAULTS]) + dnl Determine whether gnulib's <uchar.h> would, if present, override char16_t. + AC_CACHE_CHECK([whether char16_t is correctly defined], + [gl_cv_type_char16_t_works], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include <uchar.h> + /* For simplicity, assume that uint16_least_t is equivalent to + 'unsigned short'. */ + int verify[(char16_t)(-1) >= 0 && sizeof (char16_t) == sizeof (unsigned short) ? 1 : -1]; + ]]) + ], + [gl_cv_type_char16_t_works=yes], + [gl_cv_type_char16_t_works=no]) + ]) + if test $gl_cv_type_char16_t_works = no; then + GNULIB_OVERRIDES_CHAR16_T=1 + fi +]) +AC_DEFUN_ONCE([gl_TYPE_CHAR32_T], +[ + AC_REQUIRE([gl_UCHAR_H_DEFAULTS]) + dnl Determine whether gnulib's <uchar.h> would, if present, override char32_t. + AC_CACHE_CHECK([whether char32_t is correctly defined], + [gl_cv_type_char32_t_works], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include <uchar.h> + /* For simplicity, assume that uint32_least_t is equivalent to + 'unsigned int'. */ + int verify[(char32_t)(-1) >= 0 && sizeof (char32_t) == sizeof (unsigned int) ? 1 : -1]; + ]]) + ], + [gl_cv_type_char32_t_works=yes], + [gl_cv_type_char32_t_works=no]) + ]) + if test $gl_cv_type_char32_t_works = no; then + GNULIB_OVERRIDES_CHAR32_T=1 + fi +]) + AC_DEFUN([gl_UCHAR_MODULE_INDICATOR], [ dnl Use AC_REQUIRE here, so that the default settings are expanded once only. @@ -47,31 +95,33 @@ AC_DEFUN([gl_UCHAR_MODULE_INDICATOR], AC_DEFUN([gl_UCHAR_H_DEFAULTS], [ - GNULIB_BTOC32=0; AC_SUBST([GNULIB_BTOC32]) - GNULIB_C32ISALNUM=0; AC_SUBST([GNULIB_C32ISALNUM]) - GNULIB_C32ISALPHA=0; AC_SUBST([GNULIB_C32ISALPHA]) - GNULIB_C32ISBLANK=0; AC_SUBST([GNULIB_C32ISBLANK]) - GNULIB_C32ISCNTRL=0; AC_SUBST([GNULIB_C32ISCNTRL]) - GNULIB_C32ISDIGIT=0; AC_SUBST([GNULIB_C32ISDIGIT]) - GNULIB_C32ISGRAPH=0; AC_SUBST([GNULIB_C32ISGRAPH]) - GNULIB_C32ISLOWER=0; AC_SUBST([GNULIB_C32ISLOWER]) - GNULIB_C32ISPRINT=0; AC_SUBST([GNULIB_C32ISPRINT]) - GNULIB_C32ISPUNCT=0; AC_SUBST([GNULIB_C32ISPUNCT]) - GNULIB_C32ISSPACE=0; AC_SUBST([GNULIB_C32ISSPACE]) - GNULIB_C32ISUPPER=0; AC_SUBST([GNULIB_C32ISUPPER]) - GNULIB_C32ISXDIGIT=0; AC_SUBST([GNULIB_C32ISXDIGIT]) - GNULIB_C32RTOMB=0; AC_SUBST([GNULIB_C32RTOMB]) - GNULIB_C32SNRTOMBS=0; AC_SUBST([GNULIB_C32SNRTOMBS]) - GNULIB_C32SRTOMBS=0; AC_SUBST([GNULIB_C32SRTOMBS]) - GNULIB_C32STOMBS=0; AC_SUBST([GNULIB_C32STOMBS]) - GNULIB_C32TOB=0; AC_SUBST([GNULIB_C32TOB]) - GNULIB_MBRTOC32=0; AC_SUBST([GNULIB_MBRTOC32]) - GNULIB_MBSNRTOC32S=0; AC_SUBST([GNULIB_MBSNRTOC32S]) - GNULIB_MBSRTOC32S=0; AC_SUBST([GNULIB_MBSRTOC32S]) - GNULIB_MBSTOC32S=0; AC_SUBST([GNULIB_MBSTOC32S]) + GNULIB_OVERRIDES_CHAR16_T=0; AC_SUBST([GNULIB_OVERRIDES_CHAR16_T]) + GNULIB_OVERRIDES_CHAR32_T=0; AC_SUBST([GNULIB_OVERRIDES_CHAR32_T]) + GNULIB_BTOC32=0; AC_SUBST([GNULIB_BTOC32]) + GNULIB_C32ISALNUM=0; AC_SUBST([GNULIB_C32ISALNUM]) + GNULIB_C32ISALPHA=0; AC_SUBST([GNULIB_C32ISALPHA]) + GNULIB_C32ISBLANK=0; AC_SUBST([GNULIB_C32ISBLANK]) + GNULIB_C32ISCNTRL=0; AC_SUBST([GNULIB_C32ISCNTRL]) + GNULIB_C32ISDIGIT=0; AC_SUBST([GNULIB_C32ISDIGIT]) + GNULIB_C32ISGRAPH=0; AC_SUBST([GNULIB_C32ISGRAPH]) + GNULIB_C32ISLOWER=0; AC_SUBST([GNULIB_C32ISLOWER]) + GNULIB_C32ISPRINT=0; AC_SUBST([GNULIB_C32ISPRINT]) + GNULIB_C32ISPUNCT=0; AC_SUBST([GNULIB_C32ISPUNCT]) + GNULIB_C32ISSPACE=0; AC_SUBST([GNULIB_C32ISSPACE]) + GNULIB_C32ISUPPER=0; AC_SUBST([GNULIB_C32ISUPPER]) + GNULIB_C32ISXDIGIT=0; AC_SUBST([GNULIB_C32ISXDIGIT]) + GNULIB_C32RTOMB=0; AC_SUBST([GNULIB_C32RTOMB]) + GNULIB_C32SNRTOMBS=0; AC_SUBST([GNULIB_C32SNRTOMBS]) + GNULIB_C32SRTOMBS=0; AC_SUBST([GNULIB_C32SRTOMBS]) + GNULIB_C32STOMBS=0; AC_SUBST([GNULIB_C32STOMBS]) + GNULIB_C32TOB=0; AC_SUBST([GNULIB_C32TOB]) + GNULIB_MBRTOC32=0; AC_SUBST([GNULIB_MBRTOC32]) + GNULIB_MBSNRTOC32S=0; AC_SUBST([GNULIB_MBSNRTOC32S]) + GNULIB_MBSRTOC32S=0; AC_SUBST([GNULIB_MBSRTOC32S]) + GNULIB_MBSTOC32S=0; AC_SUBST([GNULIB_MBSTOC32S]) dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_C32RTOMB=1; AC_SUBST([HAVE_C32RTOMB]) - HAVE_MBRTOC32=1; AC_SUBST([HAVE_MBRTOC32]) - REPLACE_C32RTOMB=0; AC_SUBST([REPLACE_C32RTOMB]) - REPLACE_MBRTOC32=0; AC_SUBST([REPLACE_MBRTOC32]) + HAVE_C32RTOMB=1; AC_SUBST([HAVE_C32RTOMB]) + HAVE_MBRTOC32=1; AC_SUBST([HAVE_MBRTOC32]) + REPLACE_C32RTOMB=0; AC_SUBST([REPLACE_C32RTOMB]) + REPLACE_MBRTOC32=0; AC_SUBST([REPLACE_MBRTOC32]) ]) diff --git a/modules/uchar b/modules/uchar index 2f94105..7215b36 100644 --- a/modules/uchar +++ b/modules/uchar @@ -28,6 +28,8 @@ uchar.h: uchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_UCHAR_H''@|$(NEXT_UCHAR_H)|g' \ -e 's|@''SMALL_WCHAR_T''@|$(SMALL_WCHAR_T)|g' \ + -e 's|@''GNULIB_OVERRIDES_CHAR16_T''@|$(GNULIB_OVERRIDES_CHAR16_T)|g' \ + -e 's|@''GNULIB_OVERRIDES_CHAR32_T''@|$(GNULIB_OVERRIDES_CHAR32_T)|g' \ -e 's/@''GNULIB_BTOC32''@/$(GNULIB_BTOC32)/g' \ -e 's/@''GNULIB_C32ISALNUM''@/$(GNULIB_C32ISALNUM)/g' \ -e 's/@''GNULIB_C32ISALPHA''@/$(GNULIB_C32ISALPHA)/g' \