mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Use built-ins for addition and subtraction on Windows (GH-17472)
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/>
This commit is contained in:
parent
abfa377fae
commit
7512685767
5 changed files with 70 additions and 2 deletions
|
@ -36,6 +36,7 @@
|
|||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <intsafe.h>
|
||||
#include <float.h>
|
||||
|
||||
#define strcasecmp(s1, s2) _stricmp(s1, s2)
|
||||
|
|
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 " +
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue