[php-src] master: ext/gmp: expose the possibility of being a prime in `gmp_prevprime` (#22907)

Weilin Du via GitHub <[email protected]> Tue, 28 Jul 2026 19:09:48 +0000
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Weilin Du (LamentXU123)
Committer: GitHub (web-flow)
Pusher: LamentXU123
Date: 2026-07-29T03:09:44+08:00

Commit: https://github.com/php/php-src/commit/645966449554ac7c048125b01616358327277bd8
Raw diff: https://github.com/php/php-src/commit/645966449554ac7c048125b01616358327277bd8.diff

ext/gmp: expose the possibility of being a prime in `gmp_prevprime` (#22907)

Follow up #22807 to expose the "definitelyPrime" parameter in the
gmp_prevprime function to indicate the possibility of whether the outputted
number is actually a prime.

Changed paths:
  M  NEWS
  M  UPGRADING
  M  ext/gmp/gmp.c
  M  ext/gmp/gmp.stub.php
  M  ext/gmp/gmp_arginfo.h
  M  ext/gmp/tests/gmp_prevprime.phpt


Diff:

diff --git a/NEWS b/NEWS
index ebba48ca7037..0c2fd04ad469 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP                                                                        NEWS
 ?? ??? ????, PHP 8.6.0beta1
 
 - GMP:
+  . Added optional $definitely_prime output parameter to gmp_prevprime().
+    (Weilin Du)
   . Added gmp_powm_sec(). (Weilin Du)
 
 30 Jul 2026, PHP 8.6.0alpha3
diff --git a/UPGRADING b/UPGRADING
index 7c9473d07b7d..d8c8a953766a 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -275,9 +275,11 @@ PHP 8.6 UPGRADE NOTES
   . Added gmp_powm_sec() for side-channel quiet modular exponentiation.
     Requires GNU MP 5.0.0 or later.
   . Added gmp_prevprime() to get the largest prime smaller than the given
-    number. A ValueError is thrown if no such prime exists. This function is
-    available only when PHP is built against GNU MP 6.3.0 or later; it is not
-    available on official Windows builds using MPIR.
+    number. The optional $definitely_prime output parameter indicates whether
+    the returned number is definitely prime, as opposed to probably prime.
+    A ValueError is thrown if no such prime exists. This function is available
+    only when PHP is built against GNU MP 6.3.0 or later; it is not available
+    on official Windows builds using MPIR.
 
 - Intl:
   . Added Locale::getDisplayKeyword() and Locale::getDisplayKeywordValue(),
diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c
index bf0a77666b6f..4a81026d451b 100644
--- a/ext/gmp/gmp.c
+++ b/ext/gmp/gmp.c
@@ -1087,10 +1087,13 @@ GMP_UNARY_OP_FUNCTION(nextprime);
 ZEND_FUNCTION(gmp_prevprime)
 {
 	mpz_ptr gmpnum_a, gmpnum_result;
+	zval *definitely_prime = NULL;
 	int res;
 
-	ZEND_PARSE_PARAMETERS_START(1, 1)
+	ZEND_PARSE_PARAMETERS_START(1, 2)
 		GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum_a)
+		Z_PARAM_OPTIONAL
+		Z_PARAM_ZVAL(definitely_prime)
 	ZEND_PARSE_PARAMETERS_END();
 
 	if (mpz_cmp_ui(gmpnum_a, 2) <= 0) {
@@ -1106,6 +1109,9 @@ ZEND_FUNCTION(gmp_prevprime)
 	INIT_GMP_RETVAL(gmpnum_result);
 	res = mpz_prevprime(gmpnum_result, gmpnum_a);
 	ZEND_ASSERT(res);
+	if (definitely_prime) {
+		ZEND_TRY_ASSIGN_REF_BOOL(definitely_prime, res == 2);
+	}
 }
 /* }}} */
 #endif
diff --git a/ext/gmp/gmp.stub.php b/ext/gmp/gmp.stub.php
index f2ea15481748..e9c3d51ad41d 100644
--- a/ext/gmp/gmp.stub.php
+++ b/ext/gmp/gmp.stub.php
@@ -188,7 +188,8 @@ function gmp_hamdist(GMP|int|string $num1, GMP|int|string $num2): int {}
 function gmp_nextprime(GMP|int|string $num): GMP {}
 
 #ifdef HAVE___GMPZ_PREVPRIME
-function gmp_prevprime(GMP|int|string $num): GMP {}
+/** @param bool $definitely_prime */
+function gmp_prevprime(GMP|int|string $num, &$definitely_prime = null): GMP {}
 #endif
 
 function gmp_binomial(GMP|int|string $n, int $k): GMP {}
diff --git a/ext/gmp/gmp_arginfo.h b/ext/gmp/gmp_arginfo.h
index 60eec94bb5cf..dddaa7e528c9 100644
--- a/ext/gmp/gmp_arginfo.h
+++ b/ext/gmp/gmp_arginfo.h
@@ -1,5 +1,5 @@
 /* This is a generated file, edit gmp.stub.php instead.
- * Stub hash: 57d016aed930bb41ff4357917e3ae8abd612e973 */
+ * Stub hash: 743a4be1078abfa29294336564126ace8c194cbe */
 
 ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_gmp_init, 0, 1, GMP, 0)
 	ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_STRING, NULL)
@@ -190,6 +190,7 @@ ZEND_END_ARG_INFO()
 #if defined(HAVE___GMPZ_PREVPRIME)
 ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_gmp_prevprime, 0, 1, GMP, 0)
 	ZEND_ARG_OBJ_TYPE_MASK(0, num, GMP, MAY_BE_LONG|MAY_BE_STRING, NULL)
+	ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, definitely_prime, "null")
 ZEND_END_ARG_INFO()
 #endif
 
diff --git a/ext/gmp/tests/gmp_prevprime.phpt b/ext/gmp/tests/gmp_prevprime.phpt
index 42c08566c413..541a62f918d5 100644
--- a/ext/gmp/tests/gmp_prevprime.phpt
+++ b/ext/gmp/tests/gmp_prevprime.phpt
@@ -19,16 +19,42 @@ foreach ([-1, 0, 1, 2] as $value) {
     }
 }
 
+$definitelyPrime = null;
+try {
+    var_dump(gmp_prevprime(2, $definitelyPrime));
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
+var_dump($definitelyPrime);
+
 var_dump(gmp_strval(gmp_prevprime(3)));
 var_dump(gmp_strval(gmp_prevprime(4)));
 var_dump(gmp_strval(gmp_prevprime(10000)));
 
+$definitelyPrime = null;
+var_dump(gmp_strval(gmp_prevprime(3, $definitelyPrime)));
+var_dump($definitelyPrime);
+
+$probablePrime = gmp_nextprime(gmp_pow(10, 80));
+$definitelyPrime = null;
+$previousPrime = gmp_prevprime(gmp_add($probablePrime, 1), $definitelyPrime);
+var_dump(gmp_cmp($previousPrime, $probablePrime) === 0);
+var_dump(is_bool($definitelyPrime));
+var_dump($definitelyPrime === (gmp_prob_prime($previousPrime) === 2));
+
 ?>
 --EXPECT--
 gmp_prevprime(): Argument #1 ($num) must be greater than 2
 gmp_prevprime(): Argument #1 ($num) must be greater than 2
 gmp_prevprime(): Argument #1 ($num) must be greater than 2
 gmp_prevprime(): Argument #1 ($num) must be greater than 2
+gmp_prevprime(): Argument #1 ($num) must be greater than 2
+NULL
 string(1) "2"
 string(1) "3"
 string(4) "9973"
+string(1) "2"
+bool(true)
+bool(true)
+bool(true)
+bool(true)