Skip to content

Commit

Permalink
Use built-ins for addition and subtraction on Windows (GH-17472)
Browse files Browse the repository at this point in the history
For Clang, we just need to define the respective macros, since these
built-ins are available in all supported Clang versions (>= 4.0.0,
currently)[1].

For MSVC (and possibly other compilers) we use the respective APIs of
intsafe.h[2] which are available as of Windows 7/Server 2008 R2.

This avoids the UB due to signed integer overflow that may happen with
our fallback implementations.

We also drop the superfluous SHORT_MAX definition from pdo_firebird.
This shouldn't be defined unconditionally, but since it is apparently
unused, we remove it altogether.

[1] <https://releases.llvm.org/4.0.0/tools/clang/docs/LanguageExtensions.html>
[2] <https://learn.microsoft.com/en-us/windows/win32/api/intsafe/>
  • Loading branch information
cmb69 authored Jan 15, 2025
1 parent abfa377 commit 7512685
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 2 deletions.
1 change: 1 addition & 0 deletions Zend/zend_config.w32.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <winsock2.h>
#include <windows.h>

#include <intsafe.h>
#include <float.h>

#define strcasecmp(s1, s2) _stricmp(s1, s2)
Expand Down
60 changes: 60 additions & 0 deletions Zend/zend_operators.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,22 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
} else {
Z_LVAL_P(op1) = llresult;
}
#elif defined(ZEND_WIN32) && SIZEOF_LONG == SIZEOF_ZEND_LONG
long lresult;
if (UNEXPECTED(FAILED(LongAdd(Z_LVAL_P(op1), 1, &lresult)))) {
/* switch to double */
ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0);
} else {
Z_LVAL_P(op1) = lresult;
}
#elif defined(ZEND_WIN32) && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG
long long llresult;
if (UNEXPECTED(FAILED(LongLongAdd(Z_LVAL_P(op1), 1, &llresult)))) {
/* switch to double */
ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0);
} else {
Z_LVAL_P(op1) = llresult;
}
#else
if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) {
/* switch to double */
Expand Down Expand Up @@ -642,6 +658,22 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
} else {
Z_LVAL_P(op1) = llresult;
}
#elif defined(ZEND_WIN32) && SIZEOF_LONG == SIZEOF_ZEND_LONG
long lresult;
if (UNEXPECTED(FAILED(LongSub(Z_LVAL_P(op1), 1, &lresult)))) {
/* switch to double */
ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0);
} else {
Z_LVAL_P(op1) = lresult;
}
#elif defined(ZEND_WIN32) && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG
long long llresult;
if (UNEXPECTED(FAILED(LongLongSub(Z_LVAL_P(op1), 1, &llresult)))) {
/* switch to double */
ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0);
} else {
Z_LVAL_P(op1) = llresult;
}
#else
if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
/* switch to double */
Expand Down Expand Up @@ -724,6 +756,20 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
} else {
ZVAL_LONG(result, llresult);
}
#elif defined(ZEND_WIN32) && SIZEOF_LONG == SIZEOF_ZEND_LONG
long lresult;
if (UNEXPECTED(FAILED(LongAdd(Z_LVAL_P(op1), Z_LVAL_P(op2), &lresult)))) {
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
} else {
ZVAL_LONG(result, lresult);
}
#elif defined(ZEND_WIN32) && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG
long long llresult;
if (UNEXPECTED(FAILED(LongLongAdd(Z_LVAL_P(op1), Z_LVAL_P(op2), &llresult)))) {
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
} else {
ZVAL_LONG(result, llresult);
}
#else
/*
* 'result' may alias with op1 or op2, so we need to
Expand Down Expand Up @@ -812,6 +858,20 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
} else {
ZVAL_LONG(result, llresult);
}
#elif defined(ZEND_WIN32) && SIZEOF_LONG == SIZEOF_ZEND_LONG
long lresult;
if (UNEXPECTED(FAILED(LongSub(Z_LVAL_P(op1), Z_LVAL_P(op2), &lresult)))) {
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
} else {
ZVAL_LONG(result, lresult);
}
#elif defined(ZEND_WIN32) && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG
long long llresult;
if (UNEXPECTED(FAILED(LongLongSub(Z_LVAL_P(op1), Z_LVAL_P(op2), &llresult)))) {
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
} else {
ZVAL_LONG(result, llresult);
}
#else
ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));

Expand Down
2 changes: 0 additions & 2 deletions ext/pdo_firebird/php_pdo_firebird_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
#define PDO_FB_DEF_TIME_FMT "%H:%M:%S"
#define PDO_FB_DEF_TIMESTAMP_FMT PDO_FB_DEF_DATE_FMT " " PDO_FB_DEF_TIME_FMT

#define SHORT_MAX (1 << (8*sizeof(short)-1))

#if SIZEOF_ZEND_LONG == 8 && !defined(PHP_WIN32)
# define LL_LIT(lit) lit ## L
#else
Expand Down
4 changes: 4 additions & 0 deletions win32/build/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ if (VS_TOOLSET) {
}
}
} else if (CLANG_TOOLSET) {
AC_DEFINE("PHP_HAVE_BUILTIN_SADDL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_saddl_overflow'.");
AC_DEFINE("PHP_HAVE_BUILTIN_SADDLL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_saddll_overflow'.");
AC_DEFINE("PHP_HAVE_BUILTIN_SSUBL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_ssubl_overflow'.");
AC_DEFINE("PHP_HAVE_BUILTIN_SSUBLL_OVERFLOW", 1, "Define to 1 if the compiler supports '__builtin_ssubll_overflow'.");
if (PHP_UNCRITICAL_WARN_CHOKE != "no") {
ADD_FLAG("CFLAGS", "-Wno-ignored-attributes -Wno-deprecated-declarations -Wno-missing-braces " +
"-Wno-logical-op-parentheses -Wno-msvc-include -Wno-invalid-source-encoding -Wno-unknown-pragmas " +
Expand Down
5 changes: 5 additions & 0 deletions win32/build/confutils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3318,6 +3318,11 @@ function toolset_setup_common_cflags()
var vc_ver = probe_binary(PATH_PROG('cl', null));
ADD_FLAG("CFLAGS"," -fms-compatibility -fms-compatibility-version=" + vc_ver + " -fms-extensions");
}

if (!CLANG_TOOLSET) {
/* clang uses __builtin_*() instead */
ADD_FLAG("CFLAGS", "/DENABLE_INTSAFE_SIGNED_FUNCTIONS");
}
}

function toolset_setup_intrinsic_cflags()
Expand Down

0 comments on commit 7512685

Please sign in to comment.