summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/c-compiler.m49
-rwxr-xr-xconfigure42
-rw-r--r--configure.in7
-rw-r--r--src/include/c.h26
-rw-r--r--src/include/pg_config.h.in3
-rw-r--r--src/include/pg_config.h.win323
6 files changed, 78 insertions, 12 deletions
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index ea8ea9705b4..133b2098254 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -128,9 +128,11 @@ undefine([Ac_cachevar])dnl
# PGAC_TYPE_128BIT_INT
# ---------------------
# Check if __int128 is a working 128 bit integer type, and if so
-# define PG_INT128_TYPE to that typename. This currently only detects
-# a GCC/clang extension, but support for different environments may be
-# added in the future.
+# define PG_INT128_TYPE to that typename, and define ALIGNOF_PG_INT128_TYPE
+# as its alignment requirement.
+#
+# This currently only detects a GCC/clang extension, but support for other
+# environments may be added in the future.
#
# For the moment we only test for support for 128bit math; support for
# 128bit literals and snprintf is not required.
@@ -160,6 +162,7 @@ return 1;
[pgac_cv__128bit_int=no])])
if test x"$pgac_cv__128bit_int" = xyes ; then
AC_DEFINE(PG_INT128_TYPE, __int128, [Define to the name of a signed 128-bit integer type.])
+ AC_CHECK_ALIGNOF(PG_INT128_TYPE)
fi])# PGAC_TYPE_128BIT_INT
diff --git a/configure b/configure
index 897b69eab9a..15497b5519a 100755
--- a/configure
+++ b/configure
@@ -13961,7 +13961,10 @@ _ACEOF
# Compute maximum alignment of any basic type.
# We assume long's alignment is at least as strong as char, short, or int;
-# but we must check long long (if it exists) and double.
+# but we must check long long (if it is being used for int64) and double.
+# Note that we intentionally do not consider any types wider than 64 bits,
+# as allowing MAXIMUM_ALIGNOF to exceed 8 would be too much of a penalty
+# for disk and memory space.
MAX_ALIGNOF=$ac_cv_alignof_long
if test $MAX_ALIGNOF -lt $ac_cv_alignof_double ; then
@@ -14035,7 +14038,7 @@ _ACEOF
fi
-# Check for extensions offering the integer scalar type __int128.
+# Some compilers offer a 128-bit integer scalar type.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128" >&5
$as_echo_n "checking for __int128... " >&6; }
if ${pgac_cv__128bit_int+:} false; then :
@@ -14085,6 +14088,41 @@ if test x"$pgac_cv__128bit_int" = xyes ; then
$as_echo "#define PG_INT128_TYPE __int128" >>confdefs.h
+ # The cast to long int works around a bug in the HP C Compiler,
+# see AC_CHECK_SIZEOF for more information.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of PG_INT128_TYPE" >&5
+$as_echo_n "checking alignment of PG_INT128_TYPE... " >&6; }
+if ${ac_cv_alignof_PG_INT128_TYPE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_PG_INT128_TYPE" "$ac_includes_default
+#ifndef offsetof
+# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
+#endif
+typedef struct { char x; PG_INT128_TYPE y; } ac__type_alignof_;"; then :
+
+else
+ if test "$ac_cv_type_PG_INT128_TYPE" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute alignment of PG_INT128_TYPE
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_alignof_PG_INT128_TYPE=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_PG_INT128_TYPE" >&5
+$as_echo "$ac_cv_alignof_PG_INT128_TYPE" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define ALIGNOF_PG_INT128_TYPE $ac_cv_alignof_PG_INT128_TYPE
+_ACEOF
+
+
fi
# Check for various atomic operations now that we have checked how to declare
diff --git a/configure.in b/configure.in
index 728c3cb77d3..cc03f837be9 100644
--- a/configure.in
+++ b/configure.in
@@ -1805,7 +1805,10 @@ AC_CHECK_ALIGNOF(double)
# Compute maximum alignment of any basic type.
# We assume long's alignment is at least as strong as char, short, or int;
-# but we must check long long (if it exists) and double.
+# but we must check long long (if it is being used for int64) and double.
+# Note that we intentionally do not consider any types wider than 64 bits,
+# as allowing MAXIMUM_ALIGNOF to exceed 8 would be too much of a penalty
+# for disk and memory space.
MAX_ALIGNOF=$ac_cv_alignof_long
if test $MAX_ALIGNOF -lt $ac_cv_alignof_double ; then
@@ -1826,7 +1829,7 @@ AC_CHECK_TYPES([int8, uint8, int64, uint64], [], [],
# C, but is missing on some old platforms.
AC_CHECK_TYPES(sig_atomic_t, [], [], [#include <signal.h>])
-# Check for extensions offering the integer scalar type __int128.
+# Some compilers offer a 128-bit integer scalar type.
PGAC_TYPE_128BIT_INT
# Check for various atomic operations now that we have checked how to declare
diff --git a/src/include/c.h b/src/include/c.h
index b0f98d46a35..e8df5a23dd9 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -361,13 +361,29 @@ typedef unsigned long long int uint64;
/*
* 128-bit signed and unsigned integers
- * There currently is only a limited support for the type. E.g. 128bit
- * literals and snprintf are not supported; but math is.
+ * There currently is only limited support for such types.
+ * E.g. 128bit literals and snprintf are not supported; but math is.
+ * Also, because we exclude such types when choosing MAXIMUM_ALIGNOF,
+ * it must be possible to coerce the compiler to allocate them on no
+ * more than MAXALIGN boundaries.
*/
#if defined(PG_INT128_TYPE)
-#define HAVE_INT128
-typedef PG_INT128_TYPE int128;
-typedef unsigned PG_INT128_TYPE uint128;
+#if defined(pg_attribute_aligned) || ALIGNOF_PG_INT128_TYPE <= MAXIMUM_ALIGNOF
+#define HAVE_INT128 1
+
+typedef PG_INT128_TYPE int128
+#if defined(pg_attribute_aligned)
+pg_attribute_aligned(MAXIMUM_ALIGNOF)
+#endif
+;
+
+typedef unsigned PG_INT128_TYPE uint128
+#if defined(pg_attribute_aligned)
+pg_attribute_aligned(MAXIMUM_ALIGNOF)
+#endif
+;
+
+#endif
#endif
/*
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 95d30d16b68..4931f4cf80e 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -27,6 +27,9 @@
/* The normal alignment of `long long int', in bytes. */
#undef ALIGNOF_LONG_LONG_INT
+/* The normal alignment of `PG_INT128_TYPE', in bytes. */
+#undef ALIGNOF_PG_INT128_TYPE
+
/* The normal alignment of `short', in bytes. */
#undef ALIGNOF_SHORT
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 13b35d0afa2..73636ea57ea 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -34,6 +34,9 @@
/* The alignment requirement of a `long long int'. */
#define ALIGNOF_LONG_LONG_INT 8
+/* The normal alignment of `PG_INT128_TYPE', in bytes. */
+#undef ALIGNOF_PG_INT128_TYPE
+
/* The alignment requirement of a `short'. */
#define ALIGNOF_SHORT 2