1--TEST--
2Test binary operands exposing the same behavior at compile as at run time
3--INI--
4memory_limit=256M
5--FILE--
6<?php
7
8$operands = [
9	"==",
10	"!=",
11	"===",
12	"!==",
13	"<",
14	"<=",
15	">",
16	">=",
17	"<=>",
18	"+",
19	"-",
20	"*",
21	"/",
22	"%",
23	"**",
24	".",
25	"|",
26	"&",
27	"^",
28	"or",
29	"and",
30	"xor",
31	"||",
32	"&&",
33];
34
35$input = [
36	0,
37	1,
38	2,
39	-1,
40	2.0,
41	2.1,
42	-2.0,
43	-2.1,
44	PHP_INT_MAX,
45	PHP_INT_MIN,
46	PHP_INT_MAX * 2,
47	PHP_INT_MIN * 2,
48	INF,
49	NAN,
50	[],
51	[1, 2],
52	[1, 2, 3],
53	[1 => 2, 0 => 1],
54	[1, 'a' => 2],
55	[1, 4],
56	[1, 'a'],
57	[1, 2 => 2],
58	[1, [ 2 ]],
59	null,
60	false,
61	true,
62	"",
63	" ",
64	"banana",
65	"Banana",
66	"banan",
67	"0",
68	"200",
69	"20",
70	"20a",
71	" \t\n\r\v\f20",
72	"20  ",
73	"2e1",
74	"2e150",
75	"9179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368",
76	"-9179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368",
77	"0.1",
78	"-0.1",
79	"1e-1",
80	"-20",
81	"-20.0",
82	"0x14",
83	(string) PHP_INT_MAX * 2,
84	(string) PHP_INT_MIN * 2,
85];
86
87function makeParam($param) {
88	if ($param === PHP_INT_MIN) {
89		return "PHP_INT_MIN";
90	}
91	if ($param === PHP_INT_MAX) {
92		return "PHP_INT_MAX";
93	}
94	if (is_string($param)) {
95		return '"' . strtr($param, ["\t" => '\t', "\n" => '\n', "\r" => '\r', "\v" => '\v', "\f" => '\f', '$' => '\$', '"' => '\"']) . '"';
96	}
97	return "(" . str_replace("\n", "", var_export($param, true)) . ")";
98}
99
100$c = 0;
101$f = 0;
102
103function prepareLine($op1, $op2, $cmp, $operator) {
104
105	$op1_p = makeParam($op1);
106	$op2_p = makeParam($op2);
107
108	$error = "echo '" . addcslashes("$op1_p $operator $op2_p", "\\'") . '\', "\n"; $f++;';
109
110	$compare = "@($op1_p $operator $op2_p)";
111	$line = "\$c++; ";
112	try {
113		$result = makeParam($cmp());
114		$line .= "if (" . ($result === "(NAN)" ? "!is_nan($compare)" : "$compare !== $result") . ") { $error }";
115	} catch (Error $e) {
116		if (get_class($e) == "Error") {
117			return "// exempt $op1_p $operator $op2_p from checking, it generates a compile time error";
118		}
119		$msg = makeParam($e->getMessage());
120		$line .= "try { $compare; $error } catch (Error \$e) { if (\$e->getMessage() !== $msg) { $error } }";
121	}
122	return $line;
123}
124
125$filename = __DIR__ . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php';
126$file = fopen($filename, "w");
127
128fwrite($file, "<?php\n");
129
130foreach ($input as $left) {
131	foreach ($input as $right) {
132		foreach ($operands as $operand) {
133			$line = prepareLine($left, $right, function() use ($left, $right, $operand) {
134				return eval("return @(\$left $operand \$right);");
135			}, $operand);
136			fwrite($file, $line . "\n");
137		}
138	}
139}
140
141fclose($file);
142
143include $filename;
144
145if($c === 0) {
146	echo "Completely failed\n";
147} else {
148	echo "Failed: $f\n";
149}
150?>
151===DONE===
152--CLEAN--
153<?php
154$fl = __DIR__ . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php';
155@unlink($fl);
156?>
157--EXPECT--
158Failed: 0
159===DONE===
160