diff --git a/config/c-compiler.m4 b/config/c-compiler.m4 index e309a5e3e40..1509dbfa2ab 100644 --- a/config/c-compiler.m4 +++ b/config/c-compiler.m4 @@ -150,23 +150,19 @@ 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, +# PGAC_C_STATEMENT_EXPRESSIONS +# ---------------------------- +# Check if the C compiler understands GCC statement expressions. +AC_DEFUN([PGAC_C_STATEMENT_EXPRESSIONS], +[AC_CACHE_CHECK(for statement expressions, pgac_cv_statement_expressions, [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_cv_statement_expressions=yes], +[pgac_cv_statement_expressions=no])]) +if test x"$pgac_cv_statement_expressions" = xyes ; then +AC_DEFINE(HAVE_STATEMENT_EXPRESSIONS, 1, + [Define to 1 if your compiler supports statement expressions.]) +fi])# PGAC_C_STATEMENT_EXPRESSIONS diff --git a/configure b/configure index 5ee3c265b1c..14ad0a5006f 100755 --- a/configure +++ b/configure @@ -14846,9 +14846,9 @@ 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 "$as_me:${as_lineno-$LINENO}: checking for statement expressions" >&5 +$as_echo_n "checking for statement expressions... " >&6; } +if ${pgac_cv_statement_expressions+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -14863,18 +14863,18 @@ main () } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - pgac_cv__static_assert=yes + pgac_cv_statement_expressions=yes else - pgac_cv__static_assert=no + pgac_cv_statement_expressions=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 "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_statement_expressions" >&5 +$as_echo "$pgac_cv_statement_expressions" >&6; } +if test x"$pgac_cv_statement_expressions" = xyes ; then -$as_echo "#define HAVE__STATIC_ASSERT 1" >>confdefs.h +$as_echo "#define HAVE_STATEMENT_EXPRESSIONS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for typeof" >&5 diff --git a/configure.ac b/configure.ac index 4ba3967db0f..01b3bbc1be8 100644 --- a/configure.ac +++ b/configure.ac @@ -1677,7 +1677,7 @@ AC_C_BIGENDIAN AC_C_INLINE PGAC_PRINTF_ARCHETYPE PGAC_CXX_PRINTF_ARCHETYPE -PGAC_C_STATIC_ASSERT +PGAC_C_STATEMENT_EXPRESSIONS PGAC_C_TYPEOF PGAC_C_TYPES_COMPATIBLE PGAC_C_BUILTIN_CONSTANT_P diff --git a/meson.build b/meson.build index 1256094fa57..d7c5193d4ce 100644 --- a/meson.build +++ b/meson.build @@ -1880,20 +1880,16 @@ 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. +# Check if the C compiler supports GCC-style statement expressions. if cc.compiles(''' int main(int arg, char **argv) { ({ _Static_assert(1, "foo"); }); } ''', - name: '_Static_assert', + name: 'statement expressions', args: test_c_args) - cdata.set('HAVE__STATIC_ASSERT', 1) + cdata.set('HAVE_STATEMENT_EXPRESSIONS', 1) endif diff --git a/src/include/c.h b/src/include/c.h index d2cdc76644c..811d6d0110c 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -923,52 +923,31 @@ 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 + * We require C11 and C++11, so static_assert() is expected to be there. + * StaticAssertDecl() was previously used for portability, but it's now just a + * plain wrapper and doesn't need to be used in new code. 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. Macros StaticAssertStmt() and StaticAssertExpr() * make it safe to use as a statement or in an expression, respectively. * - * For compilers without _Static_assert(), we fall back on a kluge that - * assumes the compiler will complain about a negative width for a struct + * For compilers without GCC statement expressions, 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 StaticAssertStmt(condition, errmessage) \ - do { _Static_assert(condition, errmessage); } while(0) -#define StaticAssertExpr(condition, errmessage) \ - ((void) ({ StaticAssertStmt(condition, errmessage); true; })) -#else /* !HAVE__STATIC_ASSERT */ -#define StaticAssertDecl(condition, errmessage) \ - extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) -#define StaticAssertStmt(condition, errmessage) \ - ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) -#define StaticAssertExpr(condition, errmessage) \ - StaticAssertStmt(condition, errmessage) -#endif /* HAVE__STATIC_ASSERT */ -#else /* C++ */ -#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410 #define StaticAssertDecl(condition, errmessage) \ static_assert(condition, errmessage) #define StaticAssertStmt(condition, errmessage) \ - static_assert(condition, errmessage) + do { static_assert(condition, errmessage); } while(0) +#ifdef HAVE_STATEMENT_EXPRESSIONS #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 StaticAssertStmt(condition, errmessage) \ - do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0) + ((void) ({ static_assert(condition, errmessage); true; })) +#else #define StaticAssertExpr(condition, errmessage) \ - ((void) ({ StaticAssertStmt(condition, errmessage); })) -#endif /* __cpp_static_assert */ -#endif /* C++ */ + ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) +#endif /* HAVE_STATEMENT_EXPRESSIONS */ /* diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 3a7edb1f0a0..92fcc5f3063 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -385,6 +385,9 @@ /* Define to 1 if you have the `SSL_CTX_set_num_tickets' function. */ #undef HAVE_SSL_CTX_SET_NUM_TICKETS +/* Define to 1 if your compiler supports statement expressions. */ +#undef HAVE_STATEMENT_EXPRESSIONS + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H @@ -565,9 +568,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