mirror of
https://github.com/postgres/postgres.git
synced 2026-04-22 22:59:54 -04:00
Portable StaticAssertExpr
Use a different way to write StaticAssertExpr() that does not require the GCC extension statement expressions. For C, we put the static_assert into a struct. This appears to be a common approach. We still need to keep the fallback implementation to support buggy MSVC < 19.33. For C++, we put it into a lambda expression. (The C approach doesn't work; it's not permitted to define a new type inside sizeof.) Reviewed-by: Jelte Fennema-Nio <postgres@jeltef.nl> Discussion: https://www.postgresql.org/message-id/flat/5fa3a9f5-eb9a-4408-9baf-403d281f8b10%40eisentraut.org
This commit is contained in:
parent
6eedb2a5fd
commit
aa7c868523
6 changed files with 22 additions and 72 deletions
|
|
@ -150,22 +150,6 @@ fi])# PGAC_TYPE_128BIT_INT
|
|||
|
||||
|
||||
|
||||
# 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_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
|
||||
|
||||
|
||||
|
||||
# PGAC_C_TYPEOF
|
||||
# -------------
|
||||
# Check if the C compiler understands typeof or a variant. Define
|
||||
|
|
|
|||
31
configure
vendored
31
configure
vendored
|
|
@ -15005,37 +15005,6 @@ cat >>confdefs.h <<_ACEOF
|
|||
_ACEOF
|
||||
|
||||
|
||||
{ $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
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
({ _Static_assert(1, "foo"); })
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
pgac_cv_statement_expressions=yes
|
||||
else
|
||||
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_statement_expressions" >&5
|
||||
$as_echo "$pgac_cv_statement_expressions" >&6; }
|
||||
if test x"$pgac_cv_statement_expressions" = xyes ; then
|
||||
|
||||
$as_echo "#define HAVE_STATEMENT_EXPRESSIONS 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 :
|
||||
|
|
|
|||
|
|
@ -1730,7 +1730,6 @@ m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that.
|
|||
AC_C_BIGENDIAN
|
||||
PGAC_PRINTF_ARCHETYPE
|
||||
PGAC_CXX_PRINTF_ARCHETYPE
|
||||
PGAC_C_STATEMENT_EXPRESSIONS
|
||||
PGAC_C_TYPEOF
|
||||
PGAC_CXX_TYPEOF
|
||||
PGAC_C_TYPES_COMPATIBLE
|
||||
|
|
|
|||
13
meson.build
13
meson.build
|
|
@ -1990,19 +1990,6 @@ if cc.compiles('''
|
|||
endif
|
||||
|
||||
|
||||
# Check if the C compiler supports GCC-style statement expressions.
|
||||
if cc.compiles('''
|
||||
int main(int arg, char **argv)
|
||||
{
|
||||
({ _Static_assert(1, "foo"); });
|
||||
}
|
||||
''',
|
||||
name: 'statement expressions',
|
||||
args: test_c_args)
|
||||
cdata.set('HAVE_STATEMENT_EXPRESSIONS', 1)
|
||||
endif
|
||||
|
||||
|
||||
# Select the format archetype to be used to check printf-type functions.
|
||||
#
|
||||
# Need to check a call with %m because netbsd supports gnu_printf but emits a
|
||||
|
|
|
|||
|
|
@ -981,18 +981,32 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
|
|||
/*
|
||||
* StaticAssertExpr() is for use in an expression.
|
||||
*
|
||||
* 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.
|
||||
* See <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3715.pdf> for some
|
||||
* rationale for the precise behavior of this implementation. See
|
||||
* <https://stackoverflow.com/questions/31311748> about the C++
|
||||
* implementation.
|
||||
*
|
||||
* For compilers that don't support this, 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.
|
||||
*/
|
||||
#ifdef HAVE_STATEMENT_EXPRESSIONS
|
||||
#ifndef __cplusplus
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1933
|
||||
#define StaticAssertExpr(condition, errmessage) \
|
||||
((void) ({ static_assert(condition, errmessage); true; }))
|
||||
#else
|
||||
((void) sizeof(struct {static_assert(condition, errmessage); char a;}))
|
||||
#else /* _MSC_VER < 1933 */
|
||||
/*
|
||||
* This compiler is buggy and fails to compile the previous variant; use a
|
||||
* fallback implementation.
|
||||
*/
|
||||
#define StaticAssertExpr(condition, errmessage) \
|
||||
((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; }))
|
||||
#endif /* HAVE_STATEMENT_EXPRESSIONS */
|
||||
#endif /* _MSC_VER < 1933 */
|
||||
#else /* __cplusplus */
|
||||
#define StaticAssertExpr(condition, errmessage) \
|
||||
([]{static_assert(condition, errmessage);})
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -374,9 +374,6 @@
|
|||
/* 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 <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue