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