From 6f7bcca6fc2736af6ba582aaa4233599f8185756 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 20 Jan 2026 07:20:30 +0100 Subject: [PATCH] Move MAXIMUM_ALIGNOF definition to c.h This combines duplicate code from configure.in and meson.build. Discussion: https://www.postgresql.org/message-id/CA%2BhUKGLQUivg-NC7dHdbRAPmG0Hapg1gGnygM5KgDfDM2a_TMg%40mail.gmail.com --- configure | 30 -------------- configure.ac | 26 ------------ meson.build | 25 +----------- src/include/c.h | 81 +++++++++++++++++++++++++------------- src/include/pg_config.h.in | 3 -- 5 files changed, 56 insertions(+), 109 deletions(-) diff --git a/configure b/configure index fb6a4914b06..5f6f79c9516 100755 --- a/configure +++ b/configure @@ -17110,36 +17110,6 @@ _ACEOF -# Compute maximum alignment of any basic type. -# -# We require 'double' to have the strictest alignment among the basic types, -# because otherwise the C ABI might impose 8-byte alignment on some of the -# other C types that correspond to TYPALIGN_DOUBLE SQL types. That could -# cause a mismatch between the tuple layout and the C struct layout of a -# catalog tuple. We used to carefully order catalog columns such that any -# fixed-width, attalign=4 columns were at offsets divisible by 8 regardless -# of MAXIMUM_ALIGNOF to avoid that, but we no longer support any platforms -# where TYPALIGN_DOUBLE != MAXIMUM_ALIGNOF. -# -# We assume without checking that long's alignment is at least as strong as -# char, short, or int. 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_double - -if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then - as_fn_error $? "alignment of 'long' is greater than the alignment of 'double'" "$LINENO" 5 -fi -if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then - as_fn_error $? "alignment of 'int64_t' is greater than the alignment of 'double'" "$LINENO" 5 -fi - -cat >>confdefs.h <<_ACEOF -#define MAXIMUM_ALIGNOF $MAX_ALIGNOF -_ACEOF - - # 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; } diff --git a/configure.ac b/configure.ac index d3febfe58f1..dde7dcfa35f 100644 --- a/configure.ac +++ b/configure.ac @@ -1995,32 +1995,6 @@ AC_CHECK_ALIGNOF(long) AC_CHECK_ALIGNOF(int64_t) AC_CHECK_ALIGNOF(double) -# Compute maximum alignment of any basic type. -# -# We require 'double' to have the strictest alignment among the basic types, -# because otherwise the C ABI might impose 8-byte alignment on some of the -# other C types that correspond to TYPALIGN_DOUBLE SQL types. That could -# cause a mismatch between the tuple layout and the C struct layout of a -# catalog tuple. We used to carefully order catalog columns such that any -# fixed-width, attalign=4 columns were at offsets divisible by 8 regardless -# of MAXIMUM_ALIGNOF to avoid that, but we no longer support any platforms -# where TYPALIGN_DOUBLE != MAXIMUM_ALIGNOF. -# -# We assume without checking that long's alignment is at least as strong as -# char, short, or int. 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_double - -if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then - AC_MSG_ERROR([alignment of 'long' is greater than the alignment of 'double']) -fi -if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then - AC_MSG_ERROR([alignment of 'int64_t' is greater than the alignment of 'double']) -fi -AC_DEFINE_UNQUOTED(MAXIMUM_ALIGNOF, $MAX_ALIGNOF, [Define as the maximum alignment requirement of any C data type.]) - # Some compilers offer a 128-bit integer scalar type. PGAC_TYPE_128BIT_INT diff --git a/meson.build b/meson.build index 6d304f32fb0..c5fc29ed681 100644 --- a/meson.build +++ b/meson.build @@ -1771,33 +1771,12 @@ endif # Determine memory alignment requirements for the basic C data types. -alignof_types = ['short', 'int', 'long', 'double'] +alignof_types = ['short', 'int', 'long', 'int64_t', 'double'] foreach t : alignof_types - align = cc.alignment(t, args: test_c_args) + align = cc.alignment(t, args: test_c_args, prefix: '#include ') cdata.set('ALIGNOF_@0@'.format(t.to_upper()), align) endforeach -# Compute maximum alignment of any basic type. -# -# We require 'double' to have the strictest alignment among the basic types, -# because otherwise the C ABI might impose 8-byte alignment on some of the -# other C types that correspond to TYPALIGN_DOUBLE SQL types. That could -# cause a mismatch between the tuple layout and the C struct layout of a -# catalog tuple. We used to carefully order catalog columns such that any -# fixed-width, attalign=4 columns were at offsets divisible by 8 regardless -# of MAXIMUM_ALIGNOF to avoid that, but we no longer support any platforms -# where TYPALIGN_DOUBLE != MAXIMUM_ALIGNOF. -# -# We assume without checking that int64_t's alignment is at least as strong -# as long, char, short, or int. 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. -alignof_double = cdata.get('ALIGNOF_DOUBLE') -if cc.alignment('int64_t', args: test_c_args, prefix: '#include ') > alignof_double - error('alignment of int64_t is greater than the alignment of double') -endif -cdata.set('MAXIMUM_ALIGNOF', alignof_double) - cdata.set('SIZEOF_LONG', cc.sizeof('long', args: test_c_args)) cdata.set('SIZEOF_LONG_LONG', cc.sizeof('long long', args: test_c_args)) cdata.set('SIZEOF_VOID_P', cc.sizeof('void *', args: test_c_args)) diff --git a/src/include/c.h b/src/include/c.h index 7136102e5ff..b6a7330c88f 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -565,33 +565,6 @@ typedef uint32 bits32; /* >= 32 bits */ #define UINT64_FORMAT "%" PRIu64 #define OID8_FORMAT "%" PRIu64 -/* - * 128-bit signed and unsigned integers - * 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) -#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 - /* Historical names for limits in . */ #define PG_INT8_MIN INT8_MIN #define PG_INT8_MAX INT8_MAX @@ -802,6 +775,33 @@ typedef NameData *Name; */ #define lengthof(array) (sizeof (array) / sizeof ((array)[0])) +/* + * Compute maximum alignment of any basic type. + * + * We require 'double' to have the strictest alignment among the basic types, + * because otherwise the C ABI might impose 8-byte alignment on some of the + * other C types that correspond to TYPALIGN_DOUBLE SQL types. That could + * cause a mismatch between the tuple layout and the C struct layout of a + * catalog tuple. We used to carefully order catalog columns such that any + * fixed-width, attalign=4 columns were at offsets divisible by 8 regardless + * of MAXIMUM_ALIGNOF to avoid that, but we no longer support any platforms + * where TYPALIGN_DOUBLE != MAXIMUM_ALIGNOF. + * + * We assume without checking that the alignments of int64_t and long are at + * least as strong as char, short, or int. 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. + */ + +static_assert(ALIGNOF_LONG <= ALIGNOF_DOUBLE, + "alignment of 'long' is greater than the alignment of 'double'"); + +static_assert(ALIGNOF_INT64_T <= ALIGNOF_DOUBLE, + "alignment of 'int64_t' is greater than the alignment of 'double'"); + +/* The maximum alignment requirement of any C data type */ +#define MAXIMUM_ALIGNOF ALIGNOF_DOUBLE + /* ---------------- * Alignment macros: align a length or address appropriately for a given type. * The fooALIGN() macros round up to a multiple of the required alignment, @@ -1102,6 +1102,33 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName, #define INVERT_COMPARE_RESULT(var) \ ((var) = ((var) < 0) ? 1 : -(var)) +/* + * 128-bit signed and unsigned integers + * 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) +#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 + /* * Use this, not "char buf[BLCKSZ]", to declare a field or local variable * holding a page buffer, if that page might be accessed as a page. Otherwise diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 339268dc8ef..b42cf0df5cc 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -547,9 +547,6 @@ /* Define to 1 if you have __get_cpuid_count. */ #undef HAVE__GET_CPUID_COUNT -/* Define as the maximum alignment requirement of any C data type. */ -#undef MAXIMUM_ALIGNOF - /* Define bytes to use libc memset(). */ #undef MEMSET_LOOP_LIMIT base-commit: 7ebb64c557570647e3fcf6f5f1549e882ed26489 -- 2.52.0