Skip to content

Commit 0286dec

Browse files
committed
Accept GMP|string|int union in GMP functions
This changes GMP functions to accept a GMP|string|int union with standard semantics (and thus also uses it in function signatures). Relative to the previous behavior, this means that GMP functions in weak mode now also accept float and null, and in strict mode no longer accept bool, and have full type information. Closes GH-6139.
1 parent e7e3099 commit 0286dec

36 files changed

+275
-332
lines changed

ext/gmp/gmp.c

+14-15
Original file line numberDiff line numberDiff line change
@@ -589,11 +589,8 @@ static int convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t a
589589
{
590590
switch (Z_TYPE_P(val)) {
591591
case IS_LONG:
592-
case IS_FALSE:
593-
case IS_TRUE: {
594-
mpz_set_si(gmpnumber, zval_get_long(val));
592+
mpz_set_si(gmpnumber, Z_LVAL_P(val));
595593
return SUCCESS;
596-
}
597594
case IS_STRING: {
598595
char *numstr = Z_STRVAL_P(val);
599596
zend_bool skip_lead = 0;
@@ -623,14 +620,16 @@ static int convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t a
623620

624621
return SUCCESS;
625622
}
626-
default:
627-
/* if unserializing */
628-
if (arg_pos == 0) {
629-
php_error_docref(NULL, E_WARNING, "Cannot convert variable of type %s to GMP", zend_zval_type_name(val));
623+
default: {
624+
zend_long lval;
625+
if (!zend_parse_arg_long_slow(val, &lval)) {
626+
zend_argument_type_error(arg_pos, "must be of type GMP|string|int, %s given", zend_zval_type_name(val));
630627
return FAILURE;
631628
}
632-
zend_argument_type_error(arg_pos, "must be of type GMP|string|int|bool, %s given", zend_zval_type_name(val));
633-
return FAILURE;
629+
630+
mpz_set_si(gmpnumber, lval);
631+
return SUCCESS;
632+
}
634633
}
635634
}
636635
/* }}} */
@@ -992,16 +991,16 @@ ZEND_FUNCTION(gmp_export)
992991
ZEND_FUNCTION(gmp_intval)
993992
{
994993
zval *gmpnumber_arg;
994+
mpz_ptr gmpnum;
995+
gmp_temp_t temp_a;
995996

996997
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &gmpnumber_arg) == FAILURE){
997998
RETURN_THROWS();
998999
}
9991000

1000-
if (IS_GMP(gmpnumber_arg)) {
1001-
RETVAL_LONG(mpz_get_si(GET_GMP_FROM_ZVAL(gmpnumber_arg)));
1002-
} else {
1003-
RETVAL_LONG(zval_get_long(gmpnumber_arg));
1004-
}
1001+
FETCH_GMP_ZVAL(gmpnum, gmpnumber_arg, temp_a, 1);
1002+
RETVAL_LONG(mpz_get_si(gmpnum));
1003+
FREE_GMP_TEMP(temp_a);
10051004
}
10061005
/* }}} */
10071006

ext/gmp/gmp.stub.php

+85-202
Original file line numberDiff line numberDiff line change
@@ -6,222 +6,105 @@ class GMP
66
{
77
}
88

9-
/** @param int|bool|string $number */
10-
function gmp_init($number, int $base = 0): GMP {}
9+
function gmp_init(int|string $number, int $base = 0): GMP {}
1110

1211
function gmp_import(string $data, int $word_size = 1, int $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN): GMP {}
1312

14-
/** @param GMP|int|bool|string $gmpnumber */
15-
function gmp_export($gmpnumber, int $word_size = 1, int $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN): string {}
16-
17-
/** @param GMP|int|bool|string $gmpnumber */
18-
function gmp_intval($gmpnumber): int {}
19-
20-
/** @param GMP|int|bool|string $gmpnumber */
21-
function gmp_strval($gmpnumber, int $base = 10): string {}
22-
23-
/**
24-
* @param GMP|int|bool|string $a
25-
* @param GMP|int|bool|string $b
26-
*/
27-
function gmp_add($a, $b): GMP {}
28-
29-
/**
30-
* @param GMP|int|bool|string $a
31-
* @param GMP|int|bool|string $b
32-
*/
33-
function gmp_sub($a, $b): GMP {}
34-
35-
/**
36-
* @param GMP|int|bool|string $a
37-
* @param GMP|int|bool|string $b
38-
*/
39-
function gmp_mul($a, $b): GMP {}
40-
41-
/**
42-
* @param GMP|int|bool|string $a
43-
* @param GMP|int|bool|string $b
44-
*/
45-
function gmp_div_qr($a, $b, int $round = GMP_ROUND_ZERO): array {}
46-
47-
/**
48-
* @param GMP|int|bool|string $a
49-
* @param GMP|int|bool|string $b
50-
*/
51-
function gmp_div_q($a, $b, int $round = GMP_ROUND_ZERO): GMP {}
52-
53-
/**
54-
* @param GMP|int|bool|string $a
55-
* @param GMP|int|bool|string $b
56-
*/
57-
function gmp_div_r($a, $b, int $round = GMP_ROUND_ZERO): GMP {}
58-
59-
/**
60-
* @param GMP|int|bool|string $a
61-
* @param GMP|int|bool|string $b
62-
* @alias gmp_div_q
63-
*/
64-
function gmp_div($a, $b, int $round = GMP_ROUND_ZERO): GMP {}
65-
66-
/**
67-
* @param GMP|int|bool|string $a
68-
* @param GMP|int|bool|string $b
69-
*/
70-
function gmp_mod($a, $b): GMP {}
71-
72-
/**
73-
* @param GMP|int|bool|string $a
74-
* @param GMP|int|bool|string $b
75-
*/
76-
function gmp_divexact($a, $b): GMP {}
77-
78-
/** @param GMP|int|bool|string $a */
79-
function gmp_neg($a): GMP {}
80-
81-
/** @param GMP|int|bool|string $a */
82-
function gmp_abs($a): GMP {}
83-
84-
/** @param GMP|int|bool|string $a */
85-
function gmp_fact($a): GMP {}
86-
87-
/** @param GMP|int|bool|string $a */
88-
function gmp_sqrt($a): GMP {}
89-
90-
/** @param GMP|int|bool|string $a */
91-
function gmp_sqrtrem($a): array {}
92-
93-
/** @param GMP|int|bool|string $a */
94-
function gmp_root($a, int $nth): GMP {}
95-
96-
/** @param GMP|int|bool|string $a */
97-
function gmp_rootrem($a, int $nth): array {}
98-
99-
/** @param GMP|int|bool|string $base */
100-
function gmp_pow($base, int $exp): GMP {}
101-
102-
/**
103-
* @param GMP|int|bool|string $base
104-
* @param GMP|int|bool|string $exp
105-
* @param GMP|int|bool|string $mod
106-
*/
107-
function gmp_powm($base, $exp, $mod): GMP {}
108-
109-
/** @param GMP|int|bool|string $a */
110-
function gmp_perfect_square($a): bool {}
111-
112-
/** @param GMP|int|bool|string $a */
113-
function gmp_perfect_power($a): bool {}
114-
115-
/** @param GMP|int|bool|string $a */
116-
function gmp_prob_prime($a, int $reps = 10): int {}
117-
118-
/**
119-
* @param GMP|int|bool|string $a
120-
* @param GMP|int|bool|string $b
121-
*/
122-
function gmp_gcd($a, $b): GMP {}
123-
124-
/**
125-
* @param GMP|int|bool|string $a
126-
* @param GMP|int|bool|string $b
127-
*/
128-
function gmp_gcdext($a, $b): array {}
129-
130-
/**
131-
* @param GMP|int|bool|string $a
132-
* @param GMP|int|bool|string $b
133-
*/
134-
function gmp_lcm($a, $b): GMP {}
135-
136-
/**
137-
* @param GMP|int|bool|string $a
138-
* @param GMP|int|bool|string $b
139-
*/
140-
function gmp_invert($a, $b): GMP|false {}
141-
142-
/**
143-
* @param GMP|int|bool|string $a
144-
* @param GMP|int|bool|string $b
145-
*/
146-
function gmp_jacobi($a, $b): int {}
147-
148-
/**
149-
* @param GMP|int|bool|string $a
150-
* @param GMP|int|bool|string $b
151-
*/
152-
function gmp_legendre($a, $b): int {}
153-
154-
/**
155-
* @param GMP|int|bool|string $a
156-
* @param GMP|int|bool|string $b
157-
*/
158-
function gmp_kronecker($a, $b): int {}
159-
160-
/**
161-
* @param GMP|int|bool|string $a
162-
* @param GMP|int|bool|string $b
163-
*/
164-
function gmp_cmp($a, $b): int {}
165-
166-
/** @param GMP|int|bool|string $a */
167-
function gmp_sign($a): int {}
168-
169-
/** @param GMP|int|bool|string $seed */
170-
function gmp_random_seed($seed): void {}
13+
function gmp_export(GMP|int|string $gmpnumber, int $word_size = 1, int $options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN): string {}
14+
15+
function gmp_intval(GMP|int|string $gmpnumber): int {}
16+
17+
function gmp_strval(GMP|int|string $gmpnumber, int $base = 10): string {}
18+
19+
function gmp_add(GMP|int|string $a, GMP|int|string $b): GMP {}
20+
21+
function gmp_sub(GMP|int|string $a, GMP|int|string $b): GMP {}
22+
23+
function gmp_mul(GMP|int|string $a, GMP|int|string $b): GMP {}
24+
25+
function gmp_div_qr(GMP|int|string $a, GMP|int|string $b, int $round = GMP_ROUND_ZERO): array {}
26+
27+
function gmp_div_q(GMP|int|string $a, GMP|int|string $b, int $round = GMP_ROUND_ZERO): GMP {}
28+
29+
function gmp_div_r(GMP|int|string $a, GMP|int|string $b, int $round = GMP_ROUND_ZERO): GMP {}
30+
31+
/** @alias gmp_div_q */
32+
function gmp_div(GMP|int|string $a, GMP|int|string $b, int $round = GMP_ROUND_ZERO): GMP {}
33+
34+
function gmp_mod(GMP|int|string $a, GMP|int|string $b): GMP {}
35+
36+
function gmp_divexact(GMP|int|string $a, GMP|int|string $b): GMP {}
37+
38+
function gmp_neg(GMP|int|string $a): GMP {}
39+
40+
function gmp_abs(GMP|int|string $a): GMP {}
41+
42+
function gmp_fact(GMP|int|string $a): GMP {}
43+
44+
function gmp_sqrt(GMP|int|string $a): GMP {}
45+
46+
function gmp_sqrtrem(GMP|int|string $a): array {}
47+
48+
function gmp_root(GMP|int|string $a, int $nth): GMP {}
49+
50+
function gmp_rootrem(GMP|int|string $a, int $nth): array {}
51+
52+
function gmp_pow(GMP|int|string $base, int $exp): GMP {}
53+
54+
function gmp_powm(GMP|int|string $base, GMP|int|string $exp, GMP|int|string $mod): GMP {}
55+
56+
function gmp_perfect_square(GMP|int|string $a): bool {}
57+
58+
function gmp_perfect_power(GMP|int|string $a): bool {}
59+
60+
function gmp_prob_prime(GMP|int|string $a, int $reps = 10): int {}
61+
62+
function gmp_gcd(GMP|int|string $a, GMP|int|string $b): GMP {}
63+
64+
function gmp_gcdext(GMP|int|string $a, GMP|int|string $b): array {}
65+
66+
function gmp_lcm(GMP|int|string $a, GMP|int|string $b): GMP {}
67+
68+
function gmp_invert(GMP|int|string $a, GMP|int|string $b): GMP|false {}
69+
70+
function gmp_jacobi(GMP|int|string $a, GMP|int|string $b): int {}
71+
72+
function gmp_legendre(GMP|int|string $a, GMP|int|string $b): int {}
73+
74+
function gmp_kronecker(GMP|int|string $a, GMP|int|string $b): int {}
75+
76+
function gmp_cmp(GMP|int|string $a, GMP|int|string $b): int {}
77+
78+
function gmp_sign(GMP|int|string $a): int {}
79+
80+
function gmp_random_seed(GMP|int|string $seed): void {}
17181

17282
function gmp_random_bits(int $bits): GMP {}
17383

174-
/**
175-
* @param GMP|int|bool|string $min
176-
* @param GMP|int|bool|string $max
177-
**/
178-
function gmp_random_range($min, $max): GMP {}
179-
180-
/**
181-
* @param GMP|int|bool|string $a
182-
* @param GMP|int|bool|string $b
183-
*/
184-
function gmp_and($a, $b): GMP {}
185-
186-
/**
187-
* @param GMP|int|bool|string $a
188-
* @param GMP|int|bool|string $b
189-
*/
190-
function gmp_or($a, $b): GMP {}
191-
192-
/** @param GMP|int|bool|string $a */
193-
function gmp_com($a): GMP {}
194-
195-
/**
196-
* @param GMP|int|bool|string $a
197-
* @param GMP|int|bool|string $b
198-
*/
199-
function gmp_xor($a, $b): GMP {}
84+
function gmp_random_range(GMP|int|string $min, GMP|int|string $max): GMP {}
85+
86+
function gmp_and(GMP|int|string $a, GMP|int|string $b): GMP {}
87+
88+
function gmp_or(GMP|int|string $a, GMP|int|string $b): GMP {}
89+
90+
function gmp_com(GMP|int|string $a): GMP {}
91+
92+
function gmp_xor(GMP|int|string $a, GMP|int|string $b): GMP {}
20093

20194
function gmp_setbit(GMP $a, int $index, bool $set_clear = true): void {}
20295

20396
function gmp_clrbit(GMP $a, int $index): void {}
20497

205-
/** @param GMP|int|bool|string $a */
206-
function gmp_testbit($a, int $index): bool {}
98+
function gmp_testbit(GMP|int|string $a, int $index): bool {}
20799

208-
/** @param GMP|int|bool|string $a */
209-
function gmp_scan0($a, int $start): int {}
100+
function gmp_scan0(GMP|int|string $a, int $start): int {}
210101

211-
/** @param GMP|int|bool|string $a */
212-
function gmp_scan1($a, int $start): int {}
102+
function gmp_scan1(GMP|int|string $a, int $start): int {}
213103

214-
/** @param GMP|int|bool|string $a */
215-
function gmp_popcount($a): int {}
104+
function gmp_popcount(GMP|int|string $a): int {}
216105

217-
/**
218-
* @param GMP|int|bool|string $a
219-
* @param GMP|int|bool|string $b
220-
*/
221-
function gmp_hamdist($a, $b): int {}
106+
function gmp_hamdist(GMP|int|string $a, GMP|int|string $b): int {}
222107

223-
/** @param GMP|int|bool|string $a */
224-
function gmp_nextprime($a): GMP {}
108+
function gmp_nextprime(GMP|int|string $a): GMP {}
225109

226-
/** @param GMP|int|bool|string $a */
227-
function gmp_binomial($a, int $b): GMP {}
110+
function gmp_binomial(GMP|int|string $a, int $b): GMP {}

0 commit comments

Comments
 (0)