From dd344de6718ba144e6c6def5b095bf4e220733a0 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 1 Sep 2017 15:14:18 -0400 Subject: [PATCH] Make [U]INT64CONST safe for use in #if conditions. Instead of using a cast to force the constant to be the right width, assume we can plaster on an L, UL, LL, or ULL suffix as appropriate. The old approach to this is very hoary, dating from before we were willing to require compilers to have working int64 types. This fix makes the PG_INT64_MIN, PG_INT64_MAX, and PG_UINT64_MAX constants safe to use in preprocessor conditions, where a cast doesn't work. Other symbolic constants that might be defined using [U]INT64CONST are likewise safer than before. Also fix the SIZE_MAX macro to be similarly safe, if we are forced to provide a definition for that. The test added in commit 2e70d6b5e happens to do what we want even with the hack "(size_t) -1" definition, but we could easily get burnt on other tests in future. Back-patch to all supported branches, like the previous commits. Discussion: https://postgr.es/m/15883.1504278595@sss.pgh.pa.us --- configure | 54 ----------------------------------- configure.in | 13 --------- src/include/c.h | 19 ++++++------ src/include/pg_config.h.in | 4 --- src/include/pg_config.h.win32 | 8 +----- 5 files changed, 10 insertions(+), 88 deletions(-) diff --git a/configure b/configure index 6f30b03a41b..359d359eba6 100755 --- a/configure +++ b/configure @@ -25392,60 +25392,6 @@ cat >>confdefs.h <<_ACEOF _ACEOF - -if test x"$HAVE_LONG_LONG_INT_64" = xyes ; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#define INT64CONST(x) x##LL -long long int foo = INT64CONST(0x1234567890123456); - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LL_CONSTANTS 1 -_ACEOF - -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - - # If we found "long int" is 64 bits, assume snprintf handles it. If # we found we need to use "long long int", better check. We cope with # snprintfs that use %lld, %qd, or %I64d as the format. If none of these diff --git a/configure.in b/configure.in index 832e23cde66..e68fe7d3874 100644 --- a/configure.in +++ b/configure.in @@ -1667,19 +1667,6 @@ fi AC_DEFINE_UNQUOTED(PG_INT64_TYPE, $pg_int64_type, [Define to the name of a signed 64-bit integer type.]) -dnl If we need to use "long long int", figure out whether nnnLL notation works. - -if test x"$HAVE_LONG_LONG_INT_64" = xyes ; then - AC_TRY_COMPILE([ -#define INT64CONST(x) x##LL -long long int foo = INT64CONST(0x1234567890123456); -], - [], - [AC_DEFINE(HAVE_LL_CONSTANTS, 1, [Define to 1 if constants of type 'long long int' should have the suffix LL.])], - []) -fi - - # If we found "long int" is 64 bits, assume snprintf handles it. If # we found we need to use "long long int", better check. We cope with # snprintfs that use %lld, %qd, or %I64d as the format. If none of these diff --git a/src/include/c.h b/src/include/c.h index 47c5e8db112..2d1576016ab 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -272,6 +272,8 @@ typedef long int int64; #ifndef HAVE_UINT64 typedef unsigned long int uint64; #endif +#define INT64CONST(x) (x##L) +#define UINT64CONST(x) (x##UL) #elif defined(HAVE_LONG_LONG_INT_64) /* We have working support for "long long int", use that */ @@ -281,23 +283,20 @@ typedef long long int int64; #ifndef HAVE_UINT64 typedef unsigned long long int uint64; #endif +#define INT64CONST(x) (x##LL) +#define UINT64CONST(x) (x##ULL) #else /* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */ #error must have a working 64-bit integer datatype #endif -/* Decide if we need to decorate 64-bit constants */ -#ifdef HAVE_LL_CONSTANTS -#define INT64CONST(x) ((int64) x##LL) -#define UINT64CONST(x) ((uint64) x##ULL) -#else -#define INT64CONST(x) ((int64) x) -#define UINT64CONST(x) ((uint64) x) -#endif - /* Max value of size_t might be missing if we don't have stdint.h */ #ifndef SIZE_MAX -#define SIZE_MAX ((size_t) -1) +#if SIZEOF_SIZE_T == 8 +#define SIZE_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF) +#else +#define SIZE_MAX (0xFFFFFFFFU) +#endif #endif /* Select timestamp representation (float8 or int64) */ diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 872d39fb819..c1b7e299b9c 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -326,10 +326,6 @@ /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ -/* Define to 1 if constants of type 'long long int' should have the suffix LL. - */ -#undef HAVE_LL_CONSTANTS - /* Define to 1 if the system has the type `locale_t'. */ #undef HAVE_LOCALE_T diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index 7fd2a346eec..06c5b534324 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -232,12 +232,6 @@ /* Define to 1 if you have the `z' library (-lz). */ /* #undef HAVE_LIBZ */ -/* Define to 1 if constants of type 'long long int' should have the suffix LL. - */ -#if (_MSC_VER > 1200) -#define HAVE_LL_CONSTANTS 1 -#endif - /* Define to 1 if the system has the type `locale_t'. */ #define HAVE_LOCALE_T 1 @@ -246,7 +240,7 @@ /* Define to 1 if `long long int' works and is 64 bits. */ #if (_MSC_VER > 1200) -#define HAVE_LONG_LONG_INT_64 +#define HAVE_LONG_LONG_INT_64 1 #endif /* Define to 1 if you have the `mbstowcs_l' function. */