diff --git a/phpunit/src/CompilerBaseApiTest.php b/phpunit/src/CompilerBaseApiTest.php index 8cdf666c..03d48d9a 100644 --- a/phpunit/src/CompilerBaseApiTest.php +++ b/phpunit/src/CompilerBaseApiTest.php @@ -216,6 +216,20 @@ class CompilerBaseApiTest extends TestCase $this->assertSame('ZEND_LONG_MIN', $this->invokeMethod('genCValue', PHP_INT_MIN)); } + public function testGeneratedCValuesAreAlwaysSourceCodeStrings(): void + { + $this->assertSame((string) M_E, $this->invokeMethod('genCValue', M_E)); + $this->assertSame('1', $this->invokeMethod('genCValue', true)); + $this->assertSame('0', $this->invokeMethod('genCValue', false)); + + $code = $this->invokeMethod( + 'parseConstFetch', + new \PhpParser\Node\Expr\ConstFetch(new \PhpParser\Node\Name('M_E')) + ); + $this->assertIsString($code); + $this->assertSame((string) M_E, $code); + } + public function testWindowsIntegerLiteralSuffixForInternalConstants(): void { $this->setPropertyValue('platform', new Windows()); diff --git a/src/Generator/Utils.php b/src/Generator/Utils.php index 9327324b..1b9e98f7 100644 --- a/src/Generator/Utils.php +++ b/src/Generator/Utils.php @@ -25,16 +25,16 @@ trait Utils return $value . $this->getPlatform()->getIntegerLiteralSuffix(); } - protected function genCValue(mixed $value): mixed + protected function genCValue(mixed $value): string { if (is_int($value)) { return $this->genIntegerLiteral($value); } if (is_float($value)) { - return $value; + return (string) $value; } if (is_bool($value)) { - return $value ? 1 : 0; + return $value ? '1' : '0'; } if (is_string($value)) { return $this->genCharPtr($value); diff --git a/src/Parser/ConstantExpressionTrait.php b/src/Parser/ConstantExpressionTrait.php index 3e9af57c..8e79a8f3 100644 --- a/src/Parser/ConstantExpressionTrait.php +++ b/src/Parser/ConstantExpressionTrait.php @@ -147,7 +147,7 @@ trait ConstantExpressionTrait return $this->isInternalConstant($name) && is_scalar($this->internalConstants[$name]); } - protected function getInternalScalarConstantValue(string $name): string|int|float + protected function getInternalScalarConstantValue(string $name): string { $value = $this->internalConstants[$name]; if (is_int($value)) { diff --git a/src/Translator.php b/src/Translator.php index c1bb45b7..f922e759 100644 --- a/src/Translator.php +++ b/src/Translator.php @@ -822,7 +822,10 @@ CODE; if ($this->literalStrings) { $code .= Type::STR . ' ' . self::LITERAL_STRINGS . '[] = {' . PHP_EOL; foreach ($this->literalStrings as $str => $index) { - $code .= Type::STR . '{ZEND_STRL("' . $this->escapeString($str) . '"), true}, // [' . $index . ']' . PHP_EOL; + // PHP converts canonical integer-string array keys (for + // example "0" and "-1") to int. literalStrings only accepts + // strings, so restore the original key type at this boundary. + $code .= Type::STR . '{ZEND_STRL("' . $this->escapeString((string) $str) . '"), true}, // [' . $index . ']' . PHP_EOL; } $code .= '};' . PHP_EOL . PHP_EOL; } else {