From 7af13e08a0f7151137a46bc38543d1134eea961d Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 18 Nov 2025 08:43:13 +0100 Subject: [PATCH 5/6] Portable StaticAssertExpr Use a different way to write StaticAssertExpr() that does not require the GCC extension statement expressions. --- config/c-compiler.m4 | 20 -------------------- configure | 31 ------------------------------- configure.ac | 1 - meson.build | 17 ----------------- src/include/c.h | 29 +++++------------------------ src/include/pg_config.h.in | 3 --- 6 files changed, 5 insertions(+), 96 deletions(-) diff --git a/config/c-compiler.m4 b/config/c-compiler.m4 index 236a59e8536..897194875c1 100644 --- a/config/c-compiler.m4 +++ b/config/c-compiler.m4 @@ -114,26 +114,6 @@ fi])# PGAC_TYPE_128BIT_INT -# PGAC_C_STATIC_ASSERT -# -------------------- -# Check if the C compiler understands _Static_assert(), -# and define HAVE__STATIC_ASSERT if so. -# -# We actually check the syntax ({ _Static_assert(...) }), because we need -# gcc-style compound expressions to be able to wrap the thing into macros. -AC_DEFUN([PGAC_C_STATIC_ASSERT], -[AC_CACHE_CHECK(for _Static_assert, pgac_cv__static_assert, -[AC_LINK_IFELSE([AC_LANG_PROGRAM([], -[({ _Static_assert(1, "foo"); })])], -[pgac_cv__static_assert=yes], -[pgac_cv__static_assert=no])]) -if test x"$pgac_cv__static_assert" = xyes ; then -AC_DEFINE(HAVE__STATIC_ASSERT, 1, - [Define to 1 if your compiler understands _Static_assert.]) -fi])# PGAC_C_STATIC_ASSERT - - - # PGAC_C_TYPEOF # ------------- # Check if the C compiler understands typeof or a variant. Define diff --git a/configure b/configure index 3a0ed11fa8e..7db1dfe92e6 100755 --- a/configure +++ b/configure @@ -14714,37 +14714,6 @@ cat >>confdefs.h <<_ACEOF _ACEOF -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _Static_assert" >&5 -$as_echo_n "checking for _Static_assert... " >&6; } -if ${pgac_cv__static_assert+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -({ _Static_assert(1, "foo"); }) - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - pgac_cv__static_assert=yes -else - pgac_cv__static_assert=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__static_assert" >&5 -$as_echo "$pgac_cv__static_assert" >&6; } -if test x"$pgac_cv__static_assert" = xyes ; then - -$as_echo "#define HAVE__STATIC_ASSERT 1" >>confdefs.h - -fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for typeof" >&5 $as_echo_n "checking for typeof... " >&6; } if ${pgac_cv_c_typeof+:} false; then : diff --git a/configure.ac b/configure.ac index c2413720a18..c17796a7f2e 100644 --- a/configure.ac +++ b/configure.ac @@ -1674,7 +1674,6 @@ m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that. AC_C_BIGENDIAN AC_C_INLINE PGAC_PRINTF_ARCHETYPE -PGAC_C_STATIC_ASSERT PGAC_C_TYPEOF PGAC_C_TYPES_COMPATIBLE PGAC_C_BUILTIN_CONSTANT_P diff --git a/meson.build b/meson.build index c1e17aa3040..00ba587ec04 100644 --- a/meson.build +++ b/meson.build @@ -1877,23 +1877,6 @@ if cc.compiles(''' endif -# Check if the C compiler understands _Static_assert(), -# and define HAVE__STATIC_ASSERT if so. -# -# We actually check the syntax ({ _Static_assert(...) }), because we need -# gcc-style compound expressions to be able to wrap the thing into macros. -if cc.compiles(''' - int main(int arg, char **argv) - { - ({ _Static_assert(1, "foo"); }); - } - ''', - name: '_Static_assert', - args: test_c_args) - cdata.set('HAVE__STATIC_ASSERT', 1) -endif - - # Need to check a call with %m because netbsd supports gnu_printf but emits a # warning for each use of %m. printf_attributes = ['gnu_printf', '__syslog__', 'printf'] diff --git a/src/include/c.h b/src/include/c.h index f074c50fc0c..d462ebbebd1 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -914,43 +914,24 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName, * If the "condition" (a compile-time-constant expression) evaluates to false, * throw a compile error using the "errmessage" (a string literal). * - * C11 has _Static_assert(), and most C99 compilers already support that. For - * portability, we wrap it into StaticAssertDecl(). _Static_assert() is a - * "declaration", and so it must be placed where for example a variable - * declaration would be valid. As long as we compile with + * We require C11 and C++11, so _Static_assert()/static_assert() are expected + * to be there. For portability, we wrap it into StaticAssertDecl(). + * _Static_assert() is a "declaration", and so it must be placed where for + * example a variable declaration would be valid. As long as we compile with * -Wno-declaration-after-statement, that also means it cannot be placed after * statements in a function. The macro StaticAssertExpr() makes it safe to * use in an expression. - * - * For compilers without _Static_assert(), we fall back on a kluge that - * assumes the compiler will complain about a negative width for a struct - * bit-field. This will not include a helpful error message, but it beats not - * getting an error at all. */ #ifndef __cplusplus -#ifdef HAVE__STATIC_ASSERT #define StaticAssertDecl(condition, errmessage) \ _Static_assert(condition, errmessage) #define StaticAssertExpr(condition, errmessage) \ - ((void) ({ StaticAssertDecl(condition, errmessage); true; })) -#else /* !HAVE__STATIC_ASSERT */ -#define StaticAssertDecl(condition, errmessage) \ - extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) -#define StaticAssertExpr(condition, errmessage) \ - ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) -#endif /* HAVE__STATIC_ASSERT */ + ((void) sizeof(struct {_Static_assert(condition, errmessage); char a;})) #else /* C++ */ -#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410 #define StaticAssertDecl(condition, errmessage) \ static_assert(condition, errmessage) #define StaticAssertExpr(condition, errmessage) \ ({ static_assert(condition, errmessage); }) -#else /* !__cpp_static_assert */ -#define StaticAssertDecl(condition, errmessage) \ - extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) -#define StaticAssertExpr(condition, errmessage) \ - ((void) ({ do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0); })) -#endif /* __cpp_static_assert */ #endif /* C++ */ diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index b0b0cfdaf79..ec61f301b2c 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -565,9 +565,6 @@ /* Define to 1 if you have __get_cpuid_count. */ #undef HAVE__GET_CPUID_COUNT -/* Define to 1 if your compiler understands _Static_assert. */ -#undef HAVE__STATIC_ASSERT - /* Define as the maximum alignment requirement of any C data type. */ #undef MAXIMUM_ALIGNOF -- 2.51.0