]> granicus.if.org Git - php/commitdiff
Promote warning related to operator overloading in ext/gmp to an exception
authorMáté Kocsis <kocsismate@woohoolabs.com>
Mon, 25 May 2020 15:12:52 +0000 (17:12 +0200)
committerMáté Kocsis <kocsismate@woohoolabs.com>
Mon, 25 May 2020 15:26:33 +0000 (17:26 +0200)
ext/gmp/gmp.c
ext/gmp/gmp.stub.php
ext/gmp/gmp_arginfo.h
ext/gmp/tests/gmp_pow.phpt
ext/gmp/tests/gmp_pow2.phpt [new file with mode: 0644]
ext/gmp/tests/overloading.phpt

index a14c65f2978dfa39d3c9cc6dede78f4ae70a18b4..b6b3811a68a9ea1efd569b40448684f3fe1bf85c 100644 (file)
@@ -332,12 +332,16 @@ static zend_object *gmp_clone_obj(zend_object *obj) /* {{{ */
 }
 /* }}} */
 
-static void shift_operator_helper(gmp_binary_ui_op_t op, zval *return_value, zval *op1, zval *op2) {
+static void shift_operator_helper(gmp_binary_ui_op_t op, zval *return_value, zval *op1, zval *op2, zend_uchar opcode) {
        zend_long shift = zval_get_long(op2);
 
        if (shift < 0) {
-               php_error_docref(NULL, E_WARNING, "Shift cannot be negative");
-               RETVAL_FALSE;
+               zend_throw_error(
+                       zend_ce_value_error, "%s must be greater than or equal to 0",
+                       opcode == ZEND_POW ? "Exponent" : "Shift"
+               );
+               ZVAL_UNDEF(return_value);
+               return;
        } else {
                mpz_ptr gmpnum_op, gmpnum_result;
                gmp_temp_t temp;
@@ -372,17 +376,17 @@ static int gmp_do_operation_ex(zend_uchar opcode, zval *result, zval *op1, zval
        case ZEND_MUL:
                DO_BINARY_UI_OP(mpz_mul);
        case ZEND_POW:
-               shift_operator_helper(mpz_pow_ui, result, op1, op2);
+               shift_operator_helper(mpz_pow_ui, result, op1, op2, opcode);
                return SUCCESS;
        case ZEND_DIV:
                DO_BINARY_UI_OP_EX(mpz_tdiv_q, gmp_mpz_tdiv_q_ui, 1);
        case ZEND_MOD:
                DO_BINARY_UI_OP_EX(mpz_mod, gmp_mpz_mod_ui, 1);
        case ZEND_SL:
-               shift_operator_helper(mpz_mul_2exp, result, op1, op2);
+               shift_operator_helper(mpz_mul_2exp, result, op1, op2, opcode);
                return SUCCESS;
        case ZEND_SR:
-               shift_operator_helper(mpz_fdiv_q_2exp, result, op1, op2);
+               shift_operator_helper(mpz_fdiv_q_2exp, result, op1, op2, opcode);
                return SUCCESS;
        case ZEND_BW_OR:
                DO_BINARY_OP(mpz_ior);
@@ -520,7 +524,7 @@ static ZEND_GINIT_FUNCTION(gmp)
 ZEND_MINIT_FUNCTION(gmp)
 {
        zend_class_entry tmp_ce;
-       INIT_CLASS_ENTRY(tmp_ce, "GMP", NULL);
+       INIT_CLASS_ENTRY(tmp_ce, "GMP", class_GMP_methods);
        gmp_ce = zend_register_internal_class(&tmp_ce);
        gmp_ce->create_object = gmp_create_object;
        gmp_ce->serialize = gmp_serialize;
@@ -1261,8 +1265,8 @@ ZEND_FUNCTION(gmp_pow)
        }
 
        if (exp < 0) {
-               php_error_docref(NULL, E_WARNING, "Negative exponent not supported");
-               RETURN_FALSE;
+               zend_argument_value_error(2, "must be greater than or equal to 0");
+               RETURN_THROWS();
        }
 
        if (Z_TYPE_P(base_arg) == IS_LONG && Z_LVAL_P(base_arg) >= 0) {
index a95616aa4eaf8f12223c3379ee3695962b3b74ea..bfa4ba93ee155e4ad2032041d6d439f6e702a432 100644 (file)
@@ -2,6 +2,10 @@
 
 /** @generate-function-entries */
 
+class GMP
+{
+}
+
 /** @param int|bool|string $number */
 function gmp_init($number, int $base = 0): GMP|false {}
 
index b0309824d4ae0a7a1775f344e830f61a84e24d35..4cb06da28ef42176c6954a3b2251e7c1f243bcad 100644 (file)
@@ -289,3 +289,8 @@ static const zend_function_entry ext_functions[] = {
        ZEND_FE(gmp_binomial, arginfo_gmp_binomial)
        ZEND_FE_END
 };
+
+
+static const zend_function_entry class_GMP_methods[] = {
+       ZEND_FE_END
+};
index 449f6686671569ae980ea5896e61e02feeedc437..523150765dc9f2ee4ef23adc8f9c4615a0eb2b71 100644 (file)
@@ -10,11 +10,19 @@ var_dump(gmp_strval(gmp_pow(-2,10)));
 var_dump(gmp_strval(gmp_pow(-2,11)));
 var_dump(gmp_strval(gmp_pow("2",10)));
 var_dump(gmp_strval(gmp_pow("2",0)));
-var_dump(gmp_strval(gmp_pow("2",-1)));
+try {
+    gmp_pow("2", -1);
+} catch (ValueError $exception) {
+    echo $exception->getMessage() . "\n";
+}
 var_dump(gmp_strval(gmp_pow("-2",10)));
 var_dump(gmp_strval(gmp_pow(20,10)));
 var_dump(gmp_strval(gmp_pow(50,10)));
-var_dump(gmp_strval(gmp_pow(50,-5)));
+try {
+    gmp_pow(50,-5);
+} catch (ValueError $exception) {
+    echo $exception->getMessage() . "\n";
+}
 
 $n = gmp_init("20");
 var_dump(gmp_strval(gmp_pow($n,10)));
@@ -36,15 +44,11 @@ string(4) "1024"
 string(5) "-2048"
 string(4) "1024"
 string(1) "1"
-
-Warning: gmp_pow(): Negative exponent not supported in %s on line %d
-string(1) "0"
+gmp_pow(): Argument #2 ($exp) must be greater than or equal to 0
 string(4) "1024"
 string(14) "10240000000000"
 string(17) "97656250000000000"
-
-Warning: gmp_pow(): Negative exponent not supported in %s on line %d
-string(1) "0"
+gmp_pow(): Argument #2 ($exp) must be greater than or equal to 0
 string(14) "10240000000000"
 string(14) "10240000000000"
 gmp_pow(): Argument #2 ($exp) must be of type int, array given
diff --git a/ext/gmp/tests/gmp_pow2.phpt b/ext/gmp/tests/gmp_pow2.phpt
new file mode 100644 (file)
index 0000000..e1007e8
--- /dev/null
@@ -0,0 +1,35 @@
+--TEST--
+Test pow() with gmp object
+--SKIPIF--
+<?php if (!extension_loaded("gmp")) print "skip"; ?>
+--FILE--
+<?php
+
+$n = gmp_init(2);
+var_dump(pow($n, 10));
+var_dump($n ** 10);
+
+try {
+    pow($n, -10);
+} catch (ValueError $exception) {
+    echo $exception->getMessage() . "\n";
+}
+
+try {
+    $n ** -10;
+} catch (ValueError $exception) {
+    echo $exception->getMessage() . "\n";
+}
+
+?>
+--EXPECTF--
+object(GMP)#%d (1) {
+  ["num"]=>
+  string(4) "1024"
+}
+object(GMP)#%d (1) {
+  ["num"]=>
+  string(4) "1024"
+}
+Exponent must be greater than or equal to 0
+Exponent must be greater than or equal to 0
index 3520f58bdce4714b8efd69037aaf87fbab3e45b7..c38b1eaf821a93357418f1e47fe46356847a4274 100644 (file)
@@ -53,8 +53,17 @@ var_dump(42 << $b);
 var_dump($a >> 2);
 var_dump(-$a >> 2);
 
-var_dump($a << -1);
-var_dump($a >> -1);
+try {
+    $a << -1;
+} catch (ValueError $exception) {
+    echo $exception->getMessage() . "\n";
+}
+
+try {
+    $a >> -1;
+} catch (ValueError $exception) {
+    echo $exception->getMessage() . "\n";
+}
 
 var_dump(~$a);
 var_dump(-$a);
@@ -237,12 +246,8 @@ object(GMP)#%d (1) {
   ["num"]=>
   string(3) "-11"
 }
-
-Warning: main(): Shift cannot be negative in %s on line %d
-bool(false)
-
-Warning: main(): Shift cannot be negative in %s on line %d
-bool(false)
+Shift must be greater than or equal to 0
+Shift must be greater than or equal to 0
 object(GMP)#%d (1) {
   ["num"]=>
   string(3) "-43"