fix(gen_stub): spell PHP_INT_MIN constants with ZEND_LONG_MIN (#48) --skip-tests
getCExpr() emitted int class constants, property defaults and parameter defaults with strval(), so `const M = PHP_INT_MIN;` produced `ZVAL_LONG(&const_M_value, -9223372036854775808)`. C parses that as unary minus applied to the literal 9223372036854775808, which exceeds long long and is ill-formed, so the generated extension source does not compile. The expression path already handles this via genIntegerLiteral (ZEND_LONG_MIN); give the stub metadata path the same spelling. The float paths (17-digit round-trip, -0.0 sign, INF/NAN) were already fixed upstream in 2d81626a; the new test pins those literals down together with the int boundary values.master
parent
e259b3fbd1
commit
284abddba6
3 changed files with 64 additions and 0 deletions
@ -0,0 +1,16 @@ |
||||
<?php |
||||
|
||||
class IntMinConstants |
||||
{ |
||||
const MIN = PHP_INT_MIN; |
||||
const MAX = PHP_INT_MAX; |
||||
const NEGZ = -0.0; |
||||
const PI = M_PI; |
||||
|
||||
public int $floor = PHP_INT_MIN; |
||||
} |
||||
|
||||
function useIntMinDefault(int $x = PHP_INT_MIN): int |
||||
{ |
||||
return $x; |
||||
} |
||||
@ -0,0 +1,41 @@ |
||||
<?php |
||||
|
||||
use TypePhp\CompilerTest; |
||||
|
||||
/** |
||||
* Class-constant and property-default metadata must embed scalar values with |
||||
* exact, well-formed C literals: PHP_INT_MIN cannot be spelled as one |
||||
* negative literal ("-9223372036854775808" negates an out-of-range positive |
||||
* literal and is ill-formed), -0.0 must keep its sign, and doubles must |
||||
* round-trip at 17 significant digits. |
||||
*/ |
||||
final class ConstantMetadataLiteralTest extends \BaseTest |
||||
{ |
||||
public function testIntMinAndFloatConstantsEmitExactLiterals(): void |
||||
{ |
||||
$previous = ini_set('precision', '14'); |
||||
try { |
||||
global $translator; |
||||
$compiler = CompilerTest::create(TYPEPHP_ROOT_PATH); |
||||
$translator = $compiler; |
||||
$testFile = TYPEPHP_ROOT_PATH . '/phpunit/code/int-min-constant-metadata.php'; |
||||
$compiler->addFiles([$testFile]); |
||||
$compiler->prepareFile($testFile); |
||||
$compiler->convertFile($testFile); |
||||
$arginfoHeader = $compiler->getArgInfoHeaderFile($testFile); |
||||
$arginfo = file_get_contents($arginfoHeader); |
||||
} finally { |
||||
if ($previous !== false) { |
||||
ini_set('precision', $previous); |
||||
} |
||||
} |
||||
|
||||
self::assertIsString($arginfo); |
||||
self::assertStringContainsString('ZVAL_LONG(&const_MIN_value, ZEND_LONG_MIN);', $arginfo); |
||||
self::assertStringContainsString('ZVAL_LONG(&const_MAX_value, 9223372036854775807);', $arginfo); |
||||
self::assertStringContainsString('ZVAL_LONG(&property_floor_default_value, ZEND_LONG_MIN);', $arginfo); |
||||
self::assertStringContainsString('ZVAL_DOUBLE(&const_NEGZ_value, -0.0);', $arginfo); |
||||
self::assertStringContainsString('ZVAL_DOUBLE(&const_PI_value, 3.1415926535897931);', $arginfo); |
||||
self::assertStringNotContainsString('-9223372036854775808', $arginfo); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue