From e331531a771443edae4135e6bcd016282cf1a3aa Mon Sep 17 00:00:00 2001 From: Collin Funk Date: Thu, 22 May 2025 19:33:05 -0700 Subject: [PATCH] stdckdint-h: Don't generate header if it is not needed. Suggested by Paul Eggert in: . * m4/stdckdint_h.m4: New file. * modules/stdckdint-h (Files): Add m4/stdckdint_h.m4. (configure.ac): Remove checks and just invoke gl_STDCKDINT_H. (Makefile.am): Replace variables set by ./configure. * lib/stdckdint.in.h: Include the compilers header if it exists. Add comment mentioning expected future standardization in C++26. (ckd_add, ckd_sub, ckd_mul): Only define if the compilers definitions do not work. --- ChangeLog | 14 +++++ lib/stdckdint.in.h | 39 ++++++++++--- m4/stdckdint_h.m4 | 136 ++++++++++++++++++++++++++++++++++++++++++++ modules/stdckdint-h | 21 +++---- 4 files changed, 192 insertions(+), 18 deletions(-) create mode 100644 m4/stdckdint_h.m4 diff --git a/ChangeLog b/ChangeLog index 0145e21fb2..f2ccb1fb94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2025-05-22 Collin Funk + + stdckdint-h: Don't generate header if it is not needed. + Suggested by Paul Eggert in: + . + * m4/stdckdint_h.m4: New file. + * modules/stdckdint-h (Files): Add m4/stdckdint_h.m4. + (configure.ac): Remove checks and just invoke gl_STDCKDINT_H. + (Makefile.am): Replace variables set by ./configure. + * lib/stdckdint.in.h: Include the compilers header if it exists. Add + comment mentioning expected future standardization in C++26. + (ckd_add, ckd_sub, ckd_mul): Only define if the compilers definitions do + not work. + 2025-05-22 Bruno Haible strchrnul: Update doc. diff --git a/lib/stdckdint.in.h b/lib/stdckdint.in.h index 83277b728e..bb9089b4a1 100644 --- a/lib/stdckdint.in.h +++ b/lib/stdckdint.in.h @@ -15,10 +15,30 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ -#ifndef _GL_STDCKDINT_H -#define _GL_STDCKDINT_H +#if __GNUC__ >= 3 +@PRAGMA_SYSTEM_HEADER@ +#endif +@PRAGMA_COLUMNS@ -#include "intprops-internal.h" +#ifndef _@GUARD_PREFIX@_STDCKDINT_H + +/* The include_next requires a split double-inclusion guard. */ +#if defined __cplusplus ? @HAVE_CXX_STDCKDINT_H@ : @HAVE_C_STDCKDINT_H@ +# @INCLUDE_NEXT@ @NEXT_STDCKDINT_H@ +#endif + +#ifndef _@GUARD_PREFIX@_STDCKDINT_H +#define _@GUARD_PREFIX@_STDCKDINT_H + +/* Do nothing but include the system header if it works properly. */ +# if defined __cplusplus ? !@HAVE_WORKING_CXX_STDCKDINT_H@ : !@HAVE_WORKING_C_STDCKDINT_H@ + +/* Avoid redefining macros. */ +# undef ckd_add +# undef ckd_sub +# undef ckd_mul + +# include "intprops-internal.h" /* Store into *R the low-order bits of A + B, A - B, A * B, respectively. Return 1 if the result overflows, 0 otherwise. @@ -26,10 +46,13 @@ bit-precise integer type, or an enumeration type. These are like the standard macros introduced in C23, except that - arguments should not have side effects. */ + arguments should not have side effects. The C++26 standard is + expected to add this header and it's macros. */ -#define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r)) -#define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r)) -#define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r)) +# define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r)) +# define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r)) +# define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r)) -#endif /* _GL_STDCKDINT_H */ +# endif /* defined __cplusplus ? @HAVE_WORKING_CXX_STDCKDINT_H@ : @HAVE_WORKING_C_STDCKDINT_H@ */ +#endif /* _@GUARD_PREFIX@_STDCKDINT_H */ +#endif /* _@GUARD_PREFIX@_STDCKDINT_H */ diff --git a/m4/stdckdint_h.m4 b/m4/stdckdint_h.m4 new file mode 100644 index 0000000000..d269faa5c9 --- /dev/null +++ b/m4/stdckdint_h.m4 @@ -0,0 +1,136 @@ +# stdckdint_h.m4 +# serial 1 +dnl Copyright 2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl This file is offered as-is, without any warranty. + +dnl Written by Collin Funk. + +AC_DEFUN_ONCE([gl_STDCKDINT_H], +[ + gl_CHECK_NEXT_HEADERS([stdckdint.h]) + if test $ac_cv_header_stdckdint_h = yes; then + HAVE_STDCKDINT_H=1 + else + HAVE_STDCKDINT_H=0 + fi + AC_SUBST([HAVE_STDCKDINT_H]) + + if test $HAVE_STDCKDINT_H = 1; then + AC_CACHE_CHECK([whether stdckdint.h can be included in C], + [gl_cv_header_c_stdckdint_h], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]])], + [gl_cv_header_c_stdckdint_h=yes], + [gl_cv_header_c_stdckdint_h=no])]) + if test $gl_cv_header_c_stdckdint_h = yes; then + HAVE_C_STDCKDINT_H=1 + AC_CACHE_CHECK([checking for an ISO C23 compliant stdckdint.h in C], + [gl_cv_header_c_stdckdint_h_works], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[int r; + int a = 1; + int b = 1; + return !!(ckd_add (&r, a, b) || ckd_sub (&r, a, b) + || ckd_mul (&r, a, b)); + ]])], + [gl_cv_header_c_stdckdint_h_works=yes], + [gl_cv_header_c_stdckdint_h_works=no])]) + if test $gl_cv_header_c_stdckdint_h_works = yes; then + HAVE_WORKING_C_STDCKDINT_H=1 + else + HAVE_WORKING_C_STDCKDINT_H=0 + fi + else + HAVE_C_STDCKDINT_H=0 + HAVE_WORKING_C_STDCKDINT_H=0 + fi + if test "$CXX" != no; then + AC_CACHE_CHECK([whether stdckdint.h can be included in C++], + [gl_cv_header_cxx_stdckdint_h], + [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to + dnl an autoconf bug . + cat > conftest.cpp <<\EOF +#include +EOF + gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp" + if AC_TRY_EVAL([gl_command]); then + gl_cv_header_cxx_stdckdint_h=yes + else + gl_cv_header_cxx_stdckdint_h=no + fi + rm -fr conftest* + ]) + if test $gl_cv_header_cxx_stdckdint_h = yes; then + HAVE_CXX_STDCKDINT_H=1 + AC_CACHE_CHECK([checking for an ISO C++26 compliant stdckdint.h in C++], + [gl_cv_header_cxx_stdckdint_h_works], + [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to + dnl an autoconf bug . + cat > conftest.cpp <<\EOF +#include +int +main (void) +{ + int r; + int a = 1; + int b = 1; + return !!(ckd_add (&r, a, b) || ckd_sub (&r, a, b) || ckd_mul (&r, a, b)); +} +EOF + gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp" + if AC_TRY_EVAL([gl_command]); then + gl_cv_header_cxx_stdckdint_h_works=yes + else + gl_cv_header_cxx_stdckdint_h_works=no + fi + rm -fr conftest* + ]) + if test $gl_cv_header_cxx_stdckdint_h_works = yes; then + HAVE_WORKING_CXX_STDCKDINT_H=1 + else + HAVE_WORKING_CXX_STDCKDINT_H=0 + fi + else + HAVE_CXX_STDCKDINT_H=0 + HAVE_WORKING_CXX_STDCKDINT_H=0 + fi + fi + else + HAVE_C_STDCKDINT_H=0 + HAVE_WORKING_C_STDCKDINT_H=0 + HAVE_CXX_STDCKDINT_H=0 + HAVE_WORKING_CXX_STDCKDINT_H=0 + fi + AC_SUBST([HAVE_C_STDCKDINT_H]) + AC_SUBST([HAVE_WORKING_C_STDCKDINT_H]) + AC_SUBST([HAVE_CXX_STDCKDINT_H]) + AC_SUBST([HAVE_WORKING_CXX_STDCKDINT_H]) + + if test "$CXX" != no; then + dnl We might need the header for C or C++. + if test $HAVE_C_STDCKDINT_H = 1 \ + && test $HAVE_WORKING_C_STDCKDINT_H = 1 \ + && test $HAVE_CXX_STDCKDINT_H = 1 \ + && test $HAVE_WORKING_CXX_STDCKDINT_H = 1; then + GL_GENERATE_STDCKDINT_H=false + else + GL_GENERATE_STDCKDINT_H=true + fi + else + dnl We don't care about C++ here. + if test $HAVE_C_STDCKDINT_H = 1 \ + && test $HAVE_WORKING_C_STDCKDINT_H = 1; then + GL_GENERATE_STDCKDINT_H=false + else + GL_GENERATE_STDCKDINT_H=true + fi + fi +]) diff --git a/modules/stdckdint-h b/modules/stdckdint-h index ff777d8d62..7f7c612bce 100644 --- a/modules/stdckdint-h +++ b/modules/stdckdint-h @@ -2,6 +2,7 @@ Description: An that is like C23. Files: +m4/stdckdint_h.m4 lib/stdckdint.in.h lib/intprops-internal.h @@ -10,16 +11,7 @@ gen-header bool configure.ac: -AC_CHECK_HEADERS_ONCE([stdckdint.h]) -if test $ac_cv_header_stdckdint_h = yes; then - if test -n "$CXX" && test "$CXX" != no; then - GL_GENERATE_STDCKDINT_H=true - else - GL_GENERATE_STDCKDINT_H=false - fi -else - GL_GENERATE_STDCKDINT_H=true -fi +gl_STDCKDINT_H gl_CONDITIONAL_HEADER([stdckdint.h]) AC_PROG_MKDIR_P @@ -32,6 +24,15 @@ if GL_GENERATE_STDCKDINT_H stdckdint.h: stdckdint.in.h $(top_builddir)/config.status @NMD@ $(AM_V_GEN)$(MKDIR_P) '%reldir%' $(gl_V_at)$(SED_HEADER_STDOUT) \ + -e 's|@''GUARD_PREFIX''@|${gl_include_guard_prefix}|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDCKDINT_H''@|$(NEXT_STDCKDINT_H)|g' \ + -e 's|@''HAVE_C_STDCKDINT_H''@|$(HAVE_C_STDCKDINT_H)|g' \ + -e 's|@''HAVE_WORKING_C_STDCKDINT_H''@|$(HAVE_WORKING_C_STDCKDINT_H)|g' \ + -e 's|@''HAVE_CXX_STDCKDINT_H''@|$(HAVE_CXX_STDCKDINT_H)|g' \ + -e 's|@''HAVE_WORKING_CXX_STDCKDINT_H''@|$(HAVE_WORKING_CXX_STDCKDINT_H)|g' \ $(srcdir)/stdckdint.in.h > $@-t $(AM_V_at)mv $@-t $@ else