On OpenBSD 6.7, a testdir with C++ tests fails to compile: c++ -DHAVE_CONFIG_H -DEXEEXT=\"\" -I. -I../../gltests -I.. -DGNULIB_STRICT_CHECKING=1 -DIN_GNULIB_TESTS=1 -I. -I../../gltests -I.. -I../../gltests/.. -I../gllib -I../../gltests/../gllib -I/home/bruno/prefix-cc/include -Wall -g -O2 -MT test-uchar-c++.o -MD -MP -MF $depbase.Tpo -c -o test-uchar-c++.o ../../gltests/test-uchar-c++.cc &&\ mv -f $depbase.Tpo $depbase.Po In file included from ../../gltests/test-uchar-c++.cc:22: ../gllib/uchar.h:372:24: error: cannot combine with previous 'type-name' declaration specifier typedef uint_least16_t char16_t; ^ ../gllib/uchar.h:386:24: error: cannot combine with previous 'type-name' declaration specifier typedef uint_least32_t char32_t; ^ 2 errors generated.
The reason is that the clang C++ compiler, at least in this configuration but probably also in other configurations, defines the types 'char16_t' and 'char32_t' without any includes. This patch fixes the problem. 2020-08-19 Bruno Haible <br...@clisp.org> uchar: Fix compilation errors in C++ mode on OpenBSD. * lib/uchar.in.h (char16_t, char32_t): Don't define in C++ mode if CXX_HAS_UCHAR_TYPES is 1. * m4/uchar.m4 (gl_UCHAR_H): Determine whether the C++ compiler predefines char16_t and char32_t. Substitute CXX_HAS_UCHAR_TYPES. * modules/uchar (Makefile.am): Substitute CXX_HAS_UCHAR_TYPES. diff --git a/lib/uchar.in.h b/lib/uchar.in.h index b77116d..12f9935 100644 --- a/lib/uchar.in.h +++ b/lib/uchar.in.h @@ -40,7 +40,7 @@ /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ -#if !@HAVE_UCHAR_H@ +#if !(@HAVE_UCHAR_H@ || (defined __cplusplus && @CXX_HAS_UCHAR_TYPES@)) /* A 16-bit variant of wchar_t. Note: This type does *NOT* denote UTF-16 units. (Only on platforms @@ -54,7 +54,7 @@ typedef uint_least16_t gl_char16_t; #endif -#if !@HAVE_UCHAR_H@ +#if !(@HAVE_UCHAR_H@ || (defined __cplusplus && @CXX_HAS_UCHAR_TYPES@)) /* A 32-bit variant of wchar_t. Note: This type does *NOT* denote UTF-32 code points. (Only on platforms diff --git a/m4/uchar.m4 b/m4/uchar.m4 index 0875caa..a573f5d 100644 --- a/m4/uchar.m4 +++ b/m4/uchar.m4 @@ -1,4 +1,4 @@ -# uchar.m4 serial 14 +# uchar.m4 serial 15 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, @@ -22,6 +22,31 @@ AC_DEFUN_ONCE([gl_UCHAR_H], gl_TYPE_CHAR16_T gl_TYPE_CHAR32_T + dnl In C++ mode, clang defines 'char16_t' and 'char32_t' as built-in types + dnl on some platforms (e.g. OpenBSD 6.7). + CXX_HAS_UCHAR_TYPES=0 + if test $HAVE_UCHAR_H = 0; then + if test "$CXX" != no; then + AC_CACHE_CHECK([whether the C++ compiler predefines the <uchar.h> types], + [gl_cv_cxx_has_uchar_types], + [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to + dnl an autoconf bug <https://savannah.gnu.org/support/?110294>. + echo 'char16_t a; char32_t b;' > conftest.cpp + gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp" + if AC_TRY_EVAL([gl_command]); then + gl_cv_cxx_has_uchar_types=yes + else + gl_cv_cxx_has_uchar_types=no + fi + rm -fr conftest* + ]) + if test $gl_cv_cxx_has_uchar_types = yes; then + CXX_HAS_UCHAR_TYPES=1 + fi + fi + fi + AC_SUBST([CXX_HAS_UCHAR_TYPES]) + 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 diff --git a/modules/uchar b/modules/uchar index 7215b36..7cddcad 100644 --- a/modules/uchar +++ b/modules/uchar @@ -27,6 +27,7 @@ uchar.h: uchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_UCHAR_H''@|$(NEXT_UCHAR_H)|g' \ + -e 's|@''CXX_HAS_UCHAR_TYPES''@|$(CXX_HAS_UCHAR_TYPES)|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' \