You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-01 00:25:06 +02:00
Add UNCONSTIFY() macro.
Allows casting const-ness away from an expression, but doesn't allow changing the type. Enforcement of the latter currently only works for gcc-like compilers. Note that it is not safe to cast const-ness away if the result will ever be modified (it would be undefined behavior). Doing so can cause compiler mis-optimizations or runtime crashes (by modifying read-only memory). It is only safe to use when the result will not be modified, but API design or language restrictions prevent you from declaring that (e.g. because a function returns both const and non-const variables). Note that this only works in function scope, not for global variables (it would be nice, but not trivial, to improve that). UNCONSTIFY() requires static assert which is a feature in its own right.
This commit is contained in:
@ -4,5 +4,11 @@ Build Flags Generated by Configure
|
|||||||
// Are test code and asserts disabled?
|
// Are test code and asserts disabled?
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
|
|
||||||
|
// Does the compiler provide _Static_assert()?
|
||||||
|
#undef HAVE_STATIC_ASSERT
|
||||||
|
|
||||||
|
// Does the compiler provide __builtin_types_compatible_p()?
|
||||||
|
#undef HAVE_BUILTIN_TYPES_COMPATIBLE_P
|
||||||
|
|
||||||
// Is liblz4 present?
|
// Is liblz4 present?
|
||||||
#undef HAVE_LIBLZ4
|
#undef HAVE_LIBLZ4
|
||||||
|
@ -28,6 +28,18 @@ case $host_os in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Check if the C compiler supports _Static_assert()
|
||||||
|
#
|
||||||
|
# Test the syntax ({_Static_assert(...)}) because gcc-style compound expressions are needed to wrap it into macros.
|
||||||
|
# ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [({_Static_assert(1, "foo");})])], [AC_DEFINE(HAVE_STATIC_ASSERT)])
|
||||||
|
|
||||||
|
# Check if the C compiler supports __builtin_types_compatible_p()
|
||||||
|
# ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([], [[int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)];]])],
|
||||||
|
[AC_DEFINE(HAVE_BUILTIN_TYPES_COMPATIBLE_P)])
|
||||||
|
|
||||||
# Set warnings and optimizations based on build type (i.e. production or test)
|
# Set warnings and optimizations based on build type (i.e. production or test)
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
AC_SUBST(CFLAGS, "${CFLAGS} -Wall -Wextra -Wno-missing-field-initializers")
|
AC_SUBST(CFLAGS, "${CFLAGS} -Wall -Wextra -Wno-missing-field-initializers")
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
General Macros
|
General Macros
|
||||||
|
|
||||||
|
Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
||||||
|
Portions Copyright (c) 1994, Regents of the University of California
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
#ifndef COMMON_MACRO_H
|
#ifndef COMMON_MACRO_H
|
||||||
#define COMMON_MACRO_H
|
#define COMMON_MACRO_H
|
||||||
@ -34,4 +37,52 @@ Useful for ensuring coverage in cases where compared values may be always ascend
|
|||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
If the "condition" (a compile-time-constant expression) evaluates to false then throw a compile error using the "message" (a string
|
||||||
|
literal).
|
||||||
|
|
||||||
|
gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic placement restrictions. Macros STATIC_ASSERT_STMT() and
|
||||||
|
STATIC_ASSERT_EXP() make it safe to use as a statement or in an expression, respectively.
|
||||||
|
|
||||||
|
Otherwise 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. Note that when std=c99 it looks like gcc is using the
|
||||||
|
same kluge.
|
||||||
|
|
||||||
|
Adapted from PostgreSQL src/include/c.h.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifdef HAVE_STATIC_ASSERT
|
||||||
|
#define STATIC_ASSERT_STMT(condition, message) \
|
||||||
|
do {_Static_assert(condition, message);} while(0)
|
||||||
|
|
||||||
|
#define STATIC_ASSERT_EXPR(condition, message) \
|
||||||
|
((void)({STATIC_ASSERT_STMT(condition, message); true;}))
|
||||||
|
#else
|
||||||
|
#define STATIC_ASSERT_STMT(condition, message) \
|
||||||
|
((void)sizeof(struct {int static_assert_failure : (condition) ? 1 : -1;}))
|
||||||
|
|
||||||
|
#define STATIC_ASSERT_EXPR(condition, message) \
|
||||||
|
STATIC_ASSERT_STMT(condition, message)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Allows casting const-ness away from an expression, but doesn't allow changing the type. Enforcement of the latter currently only
|
||||||
|
works for gcc-like compilers.
|
||||||
|
|
||||||
|
Note that it is not safe to cast const-ness away if the result will ever be modified (it would be undefined behavior). Doing so can
|
||||||
|
cause compiler mis-optimizations or runtime crashes (by modifying read-only memory). It is only safe to use when the result will not
|
||||||
|
be modified, but API design or language restrictions prevent you from declaring that (e.g. because a function returns both const and
|
||||||
|
non-const variables).
|
||||||
|
|
||||||
|
Note that this only works in function scope, not for global variables (it would be nice, but not trivial, to improve that).
|
||||||
|
|
||||||
|
Adapted from PostgreSQL src/include/c.h.
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifdef HAVE_BUILTIN_TYPES_COMPATIBLE_P
|
||||||
|
#define UNCONSTIFY(type, expression) \
|
||||||
|
(STATIC_ASSERT_EXPR(__builtin_types_compatible_p(__typeof(expression), const type), "invalid cast"), (type)(expression))
|
||||||
|
#else
|
||||||
|
#define UNCONSTIFY(type, expression) \
|
||||||
|
((type)(expression))
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
46
src/configure
vendored
46
src/configure
vendored
@ -3125,13 +3125,55 @@ case $host_os in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Check if the C compiler supports _Static_assert()
|
||||||
|
#
|
||||||
|
# Test the syntax ({_Static_assert(...)}) because gcc-style compound expressions are needed to wrap it into macros.
|
||||||
|
# ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
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 :
|
||||||
|
$as_echo "#define HAVE_STATIC_ASSERT 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
|
||||||
|
# Check if the C compiler supports __builtin_types_compatible_p()
|
||||||
|
# ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)];
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_link "$LINENO"; then :
|
||||||
|
$as_echo "#define HAVE_BUILTIN_TYPES_COMPATIBLE_P 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
|
||||||
# Set warnings and optimizations based on build type (i.e. production or test)
|
# Set warnings and optimizations based on build type (i.e. production or test)
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
CFLAGS="${CFLAGS} -Wall -Wextra -Wno-missing-field-initializers"
|
CFLAGS="${CFLAGS} -Wall -Wextra -Wno-missing-field-initializers"
|
||||||
|
|
||||||
|
|
||||||
# -Wno-clobbered is not supported on all compilers
|
# -Wno-clobbered is not supported on all compilers
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-clobbered" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-clobbered" >&5
|
||||||
$as_echo_n "checking whether C compiler accepts -Wno-clobbered... " >&6; }
|
$as_echo_n "checking whether C compiler accepts -Wno-clobbered... " >&6; }
|
||||||
if ${ax_cv_check_cflags__Werror__Wno_clobbered+:} false; then :
|
if ${ax_cv_check_cflags__Werror__Wno_clobbered+:} false; then :
|
||||||
@ -5306,4 +5348,4 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
|
|||||||
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
|
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Generated from src/build/configure.ac sha1 20715731e8e51aa203ea7b77c001d51175e2a797
|
# Generated from src/build/configure.ac sha1 17c781e6a91b7e2b3fac63e875f04188d84876e8
|
||||||
|
@ -438,6 +438,8 @@ sub run
|
|||||||
|
|
||||||
# Create build.auto.h
|
# Create build.auto.h
|
||||||
my $strBuildAutoH =
|
my $strBuildAutoH =
|
||||||
|
($self->{oTest}->{&TEST_VM} ne VM_CO6 ? "#define HAVE_STATIC_ASSERT\n" : '') .
|
||||||
|
"#define HAVE_BUILTIN_TYPES_COMPATIBLE_P\n" .
|
||||||
(vmWithLz4($self->{oTest}->{&TEST_VM}) ? '#define HAVE_LIBLZ4' : '') . "\n";
|
(vmWithLz4($self->{oTest}->{&TEST_VM}) ? '#define HAVE_LIBLZ4' : '') . "\n";
|
||||||
|
|
||||||
buildPutDiffers($self->{oStorageTest}, "$self->{strGCovPath}/" . BUILD_AUTO_H, $strBuildAutoH);
|
buildPutDiffers($self->{oStorageTest}, "$self->{strGCovPath}/" . BUILD_AUTO_H, $strBuildAutoH);
|
||||||
|
Reference in New Issue
Block a user