You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +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? | ||||
| #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? | ||||
| #undef HAVE_LIBLZ4 | ||||
|   | ||||
| @@ -28,6 +28,18 @@ case $host_os in | ||||
|         ;; | ||||
| 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) | ||||
| # ---------------------------------------------------------------------------------------------------------------------------------- | ||||
| AC_SUBST(CFLAGS, "${CFLAGS} -Wall -Wextra -Wno-missing-field-initializers") | ||||
|   | ||||
| @@ -1,5 +1,8 @@ | ||||
| /*********************************************************************************************************************************** | ||||
| 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 | ||||
| #define COMMON_MACRO_H | ||||
| @@ -34,4 +37,52 @@ Useful for ensuring coverage in cases where compared values may be always ascend | ||||
|     }                                                                                                                              \ | ||||
|     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 | ||||
|   | ||||
							
								
								
									
										46
									
								
								src/configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								src/configure
									
									
									
									
										vendored
									
									
								
							| @@ -3125,13 +3125,55 @@ case $host_os in | ||||
|         ;; | ||||
| 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) | ||||
| # ---------------------------------------------------------------------------------------------------------------------------------- | ||||
| CFLAGS="${CFLAGS} -Wall -Wextra -Wno-missing-field-initializers" | ||||
|  | ||||
|  | ||||
| # -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_n "checking whether C compiler accepts -Wno-clobbered... " >&6; } | ||||
| 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;} | ||||
| 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 | ||||
|                 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"; | ||||
|  | ||||
|                 buildPutDiffers($self->{oStorageTest}, "$self->{strGCovPath}/" . BUILD_AUTO_H, $strBuildAutoH); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user