From dfabb8cf02e796ea13f107756314794df5e568c0 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 28 Oct 2026 19:17:19 +0000 Subject: [PATCH 1/2] tree: alignof is always available As we now require C11 --- Zend/Zend.m4 | 7 ++----- configure.ac | 13 ------------ ext/hash/hash.c | 18 +++++------------ ext/standard/crypt_sha256.c | 40 ++++++++++--------------------------- ext/standard/crypt_sha512.c | 39 ++++++++++-------------------------- 5 files changed, 27 insertions(+), 90 deletions(-) diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 377cf40b12bd..da696fefe5c6 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -382,6 +382,7 @@ AC_DEFUN([ZEND_CHECK_ALIGNMENT], [AC_RUN_IFELSE([AC_LANG_SOURCE([ #include #include +#include typedef union _mm_align_test { void *ptr; @@ -389,11 +390,7 @@ typedef union _mm_align_test { long lng; } mm_align_test; -#if (defined (__GNUC__) && __GNUC__ >= 2) -#define ZEND_MM_ALIGNMENT (__alignof__ (mm_align_test)) -#else -#define ZEND_MM_ALIGNMENT (sizeof(mm_align_test)) -#endif +#define ZEND_MM_ALIGNMENT (alignof(mm_align_test)) int main(void) { diff --git a/configure.ac b/configure.ac index d0321145e492..abfddd1f28e4 100644 --- a/configure.ac +++ b/configure.ac @@ -493,19 +493,6 @@ PHP_CHECK_AVX512_SUPPORTS dnl Check AVX512 VBMI PHP_CHECK_AVX512_VBMI_SUPPORTS -dnl Check for __alignof__ support in the compiler -AC_CACHE_CHECK([whether the compiler supports __alignof__], -[php_cv_have_alignof], -[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [ - int align = __alignof__(int); - (void)align; -])], -[php_cv_have_alignof=yes], -[php_cv_have_alignof=no])]) -AS_VAR_IF([php_cv_have_alignof], [yes], - [AC_DEFINE([HAVE_ALIGNOF], [1], - [Define to 1 if the compiler supports '__alignof__'.])]) - dnl Check for structure members. AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[#include ]) AC_CHECK_MEMBERS(m4_normalize([ diff --git a/ext/hash/hash.c b/ext/hash/hash.c index a950d824700f..1a7e1026c4bb 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -26,18 +26,10 @@ #include "zend_exceptions.h" #include "zend_interfaces.h" #include "zend_smart_str.h" +#include #include "hash_arginfo.h" -#ifdef PHP_WIN32 -# define __alignof__ __alignof -#else -# ifndef HAVE_ALIGNOF -# include -# define __alignof__(type) offsetof (struct { char c; type member;}, member) -# endif -#endif - static HashTable php_hash_hashtable; zend_class_entry *php_hashcontext_ce; static zend_object_handlers php_hashcontext_handlers; @@ -138,16 +130,16 @@ static size_t parse_serialize_spec( /* parse size */ if (*spec == 's' || *spec == 'S') { *sz = 2; - alignment = __alignof__(uint16_t); /* usually 2 */ + alignment = alignof(uint16_t); /* usually 2 */ } else if (*spec == 'l' || *spec == 'L') { *sz = 4; - alignment = __alignof__(uint32_t); /* usually 4 */ + alignment = alignof(uint32_t); /* usually 4 */ } else if (*spec == 'q' || *spec == 'Q') { *sz = 8; - alignment = __alignof__(uint64_t); /* usually 8 */ + alignment = alignof(uint64_t); /* usually 8 */ } else if (*spec == 'i' || *spec == 'I') { *sz = sizeof(int); - alignment = __alignof__(int); /* usually 4 */ + alignment = alignof(int); /* usually 4 */ } else { ZEND_ASSERT(*spec == 'b' || *spec == 'B'); *sz = 1; diff --git a/ext/standard/crypt_sha256.c b/ext/standard/crypt_sha256.c index 3f3d9cdeb03c..62e3b687e2cd 100644 --- a/ext/standard/crypt_sha256.c +++ b/ext/standard/crypt_sha256.c @@ -8,17 +8,9 @@ #include #include -#ifdef PHP_WIN32 -# define __alignof__ __alignof -#else -# ifndef HAVE_ALIGNOF -# include -# define __alignof__(type) offsetof (struct { char c; type member;}, member) -# endif -#endif - #include #include +#include #ifdef PHP_WIN32 # include @@ -260,14 +252,7 @@ static void sha256_process_bytes(const void *buffer, size_t len, struct sha256_c /* Process available complete blocks. */ if (len >= 64) { -/* To check alignment gcc has an appropriate operator. Other -compilers don't. */ -#if __GNUC__ >= 2 -# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0) -#else -# define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint32_t) != 0) -#endif - if (UNALIGNED_P (buffer)) + if ((uintptr_t)buffer % alignof(uint32_t) != 0) while (len > 64) { sha256_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx); buffer = (const char *) buffer + 64; @@ -317,13 +302,8 @@ static const char b64t[64] ZEND_NONSTRING = char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int buflen) { -#ifdef PHP_WIN32 - ZEND_SET_ALIGNED(32, unsigned char alt_result[32]); - ZEND_SET_ALIGNED(32, unsigned char temp_result[32]); -#else - ZEND_SET_ALIGNED(__alignof__ (uint32_t), unsigned char alt_result[32]); - ZEND_SET_ALIGNED(__alignof__ (uint32_t), unsigned char temp_result[32]); -#endif + ZEND_SET_ALIGNED(alignof(uint32_t), unsigned char alt_result[32]); + ZEND_SET_ALIGNED(alignof(uint32_t), unsigned char temp_result[32]); struct sha256_ctx ctx; struct sha256_ctx alt_ctx; @@ -371,15 +351,15 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b SET_ALLOCA_FLAG(use_heap_key); SET_ALLOCA_FLAG(use_heap_salt); - if ((uintptr_t)key % __alignof__ (uint32_t) != 0) { - tmp_key = (char *) do_alloca(key_len + __alignof__(uint32_t), use_heap_key); - key = copied_key = memcpy(tmp_key + __alignof__(uint32_t) - (uintptr_t)tmp_key % __alignof__(uint32_t), key, key_len); + if ((uintptr_t)key % alignof(uint32_t) != 0) { + tmp_key = (char *) do_alloca(key_len + alignof(uint32_t), use_heap_key); + key = copied_key = memcpy(tmp_key + alignof(uint32_t) - (uintptr_t)tmp_key % alignof(uint32_t), key, key_len); } - if ((uintptr_t)salt % __alignof__(uint32_t) != 0) { - tmp_salt = (char *) do_alloca(salt_len + 1 + __alignof__(uint32_t), use_heap_salt); + if ((uintptr_t)salt % alignof(uint32_t) != 0) { + tmp_salt = (char *) do_alloca(salt_len + 1 + alignof(uint32_t), use_heap_salt); salt = copied_salt = - memcpy(tmp_salt + __alignof__(uint32_t) - (uintptr_t)tmp_salt % __alignof__ (uint32_t), salt, salt_len); + memcpy(tmp_salt + alignof(uint32_t) - (uintptr_t)tmp_salt % alignof(uint32_t), salt, salt_len); copied_salt[salt_len] = 0; } diff --git a/ext/standard/crypt_sha512.c b/ext/standard/crypt_sha512.c index 4a308e2f9af2..9201153a4229 100644 --- a/ext/standard/crypt_sha512.c +++ b/ext/standard/crypt_sha512.c @@ -7,17 +7,10 @@ #include #include -#ifdef PHP_WIN32 -# define __alignof__ __alignof -#else -# ifndef HAVE_ALIGNOF -# include -# define __alignof__(type) offsetof (struct { char c; type member;}, member) -# endif -#endif #include #include +#include #ifdef PHP_WIN32 # include @@ -294,14 +287,7 @@ sha512_process_bytes(const void *buffer, size_t len, struct sha512_ctx *ctx) { /* Process available complete blocks. */ if (len >= 128) { #ifndef _STRING_ARCH_unaligned -/* To check alignment gcc has an appropriate operator. Other - compilers don't. */ -# if __GNUC__ >= 2 -# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0) -# else -# define UNALIGNED_P(p) (((uintptr_t) p) % sizeof(uint64_t) != 0) -# endif - if (UNALIGNED_P(buffer)) + if ((uintptr_t)buffer % alignof(uint64_t) != 0) while (len > 128) { sha512_process_block(memcpy(ctx->buffer, buffer, 128), 128, ctx); buffer = (const char *) buffer + 128; @@ -355,13 +341,8 @@ static const char b64t[64] ZEND_NONSTRING = char * php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen) { -#ifdef PHP_WIN32 - ZEND_SET_ALIGNED(64, unsigned char alt_result[64]); - ZEND_SET_ALIGNED(64, unsigned char temp_result[64]); -#else - ZEND_SET_ALIGNED(__alignof__ (uint64_t), unsigned char alt_result[64]); - ZEND_SET_ALIGNED(__alignof__ (uint64_t), unsigned char temp_result[64]); -#endif + ZEND_SET_ALIGNED(alignof(uint64_t), unsigned char alt_result[64]); + ZEND_SET_ALIGNED(alignof(uint64_t), unsigned char temp_result[64]); struct sha512_ctx ctx; struct sha512_ctx alt_ctx; size_t salt_len; @@ -409,15 +390,15 @@ php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen) SET_ALLOCA_FLAG(use_heap_key); SET_ALLOCA_FLAG(use_heap_salt); - if ((uintptr_t)key % __alignof__ (uint64_t) != 0) { - tmp_key = (char *) do_alloca(key_len + __alignof__ (uint64_t), use_heap_key); + if ((uintptr_t)key % alignof(uint64_t) != 0) { + tmp_key = (char *) do_alloca(key_len + alignof(uint64_t), use_heap_key); key = copied_key = - memcpy(tmp_key + __alignof__(uint64_t) - (uintptr_t)tmp_key % __alignof__(uint64_t), key, key_len); + memcpy(tmp_key + alignof(uint64_t) - (uintptr_t)tmp_key % alignof(uint64_t), key, key_len); } - if ((uintptr_t)salt % __alignof__ (uint64_t) != 0) { - tmp_salt = (char *) do_alloca(salt_len + 1 + __alignof__(uint64_t), use_heap_salt); - salt = copied_salt = memcpy(tmp_salt + __alignof__(uint64_t) - (uintptr_t)tmp_salt % __alignof__(uint64_t), salt, salt_len); + if ((uintptr_t)salt % alignof(uint64_t) != 0) { + tmp_salt = (char *) do_alloca(salt_len + 1 + alignof(uint64_t), use_heap_salt); + salt = copied_salt = memcpy(tmp_salt + alignof(uint64_t) - (uintptr_t)tmp_salt % alignof(uint64_t), salt, salt_len); copied_salt[salt_len] = 0; } From a3331768d7528eb956d18be871d8eb3b084e8a69 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 29 Oct 2026 15:54:09 +0000 Subject: [PATCH 2/2] use alignas instead of ZEND_SET_ALIGNED() when possible Sadly we cannot fully remove ZEND_SET_ALIGNED() as alignas is not allowed in typedefs. --- Zend/zend_string.c | 2 +- ext/opcache/ZendAccelerator.h | 2 +- ext/random/random.c | 2 +- ext/standard/crypt_sha256.c | 4 ++-- ext/standard/crypt_sha512.c | 4 ++-- ext/standard/string.c | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Zend/zend_string.c b/Zend/zend_string.c index ec97616a54fd..daf952e4af0a 100644 --- a/Zend/zend_string.c +++ b/Zend/zend_string.c @@ -53,7 +53,7 @@ ZEND_API zend_string *zend_one_char_string[256]; ZEND_API zend_string **zend_known_strings = NULL; /* this is read-only, so it's ok */ -ZEND_SET_ALIGNED(16, static const char zend_hexconvtab[]) = "0123456789abcdef"; +alignas(16) static const char zend_hexconvtab[] = "0123456789abcdef"; static zend_always_inline void zend_bin2hex_impl(char *out, const unsigned char *in, size_t in_len, const char *hexconvtab) { diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 5fd34441c402..1eedee04f02b 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -292,7 +292,7 @@ typedef struct _zend_accel_shared_globals { const void **jit_exit_groups; /* Interned Strings Support (must be the last element) */ - ZEND_SET_ALIGNED(ZEND_STRING_TABLE_POS_ALIGNMENT, zend_string_table interned_strings); + alignas(ZEND_STRING_TABLE_POS_ALIGNMENT) zend_string_table interned_strings; } zend_accel_shared_globals; #ifdef ZEND_WIN32 diff --git a/ext/random/random.c b/ext/random/random.c index fe4176418e41..5d341ef4cb73 100644 --- a/ext/random/random.c +++ b/ext/random/random.c @@ -316,7 +316,7 @@ PHPAPI void *php_random_default_status(void) /* }}} */ /* this is read-only, so it's ok */ -ZEND_SET_ALIGNED(16, static const char hexconvtab[]) = "0123456789abcdef"; +alignas(16) static const char hexconvtab[] = "0123456789abcdef"; /* {{{ php_random_bin2hex_le */ /* stolen from standard/string.c */ diff --git a/ext/standard/crypt_sha256.c b/ext/standard/crypt_sha256.c index 62e3b687e2cd..9e6614058ef5 100644 --- a/ext/standard/crypt_sha256.c +++ b/ext/standard/crypt_sha256.c @@ -302,8 +302,8 @@ static const char b64t[64] ZEND_NONSTRING = char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int buflen) { - ZEND_SET_ALIGNED(alignof(uint32_t), unsigned char alt_result[32]); - ZEND_SET_ALIGNED(alignof(uint32_t), unsigned char temp_result[32]); + alignas(uint32_t) unsigned char alt_result[32]; + alignas(uint32_t) unsigned char temp_result[32]; struct sha256_ctx ctx; struct sha256_ctx alt_ctx; diff --git a/ext/standard/crypt_sha512.c b/ext/standard/crypt_sha512.c index 9201153a4229..64a744ef3268 100644 --- a/ext/standard/crypt_sha512.c +++ b/ext/standard/crypt_sha512.c @@ -341,8 +341,8 @@ static const char b64t[64] ZEND_NONSTRING = char * php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen) { - ZEND_SET_ALIGNED(alignof(uint64_t), unsigned char alt_result[64]); - ZEND_SET_ALIGNED(alignof(uint64_t), unsigned char temp_result[64]); + alignas(uint64_t) unsigned char alt_result[64]; + alignas(uint64_t) unsigned char temp_result[64]; struct sha512_ctx ctx; struct sha512_ctx alt_ctx; size_t salt_len; diff --git a/ext/standard/string.c b/ext/standard/string.c index f52fe97e65a5..e3f0143c5ca0 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4076,7 +4076,7 @@ PHPAPI zend_string *php_addslashes(zend_string *str) /* {{{ */ zend_string *php_addslashes_sse42(zend_string *str) # endif { - ZEND_SET_ALIGNED(16, static const char slashchars[16]) = "\'\"\\\0"; + alignas(16) static const char slashchars[16] = "\'\"\\\0"; __m128i w128, s128; uint32_t res = 0; /* maximum string length, worst case situation */