Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Native mode: a runtime zero divisor or PHP_INT_MIN % -1 kills the process (SIGFPE)

クローズ
#142 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 2 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
cpp, php
領域
compilers

調査の方向性

Start with the native-mode lowering for %, /, << and >>, comparing its runtime behavior with php::fn::intdiv() and the existing static undefined-behavior checks. Use the issue's zero-divisor, PHP_INT_MIN, and invalid-shift examples with UBSan; done means runtime cases no longer terminate the process and produce the specified PHP errors or result.

索引モデルが issue の本文から書いたものです。

説明

Since 0.8.0 native int storage is the default, so % and / on plain int values lower to the raw C++ operators. When the divisor is only known at runtime, PHP's catchable errors become a crash of the whole process:

<?php
function mod(int $a, int $b): int { return $a % $b; }
function main(): void
{
    try {
        var_dump(mod(5, 0));
    } catch (DivisionByZeroError $e) {
        echo $e->getMessage(), "\n";      // PHP: "Modulo by zero"
    }
}
Floating point exception (core dumped)
runtime operation (int params) PHP TypePHP native mode
$a % $b, $b = 0 DivisionByZeroError SIGFPE, process dies
$a / $b, $b = 0 DivisionByZeroError SIGFPE
PHP_INT_MIN % -1 0 SIGFPE
PHP_INT_MIN / -1 float(9.2233720368547758E+18) SIGFPE
$a << $b, $b = 64 0 1 (x86 masks the count)
$a << $b, $b = -1 ArithmeticError PHP_INT_MIN

I understand this is the documented trade-off ("Native std::int overflow and integer division behavior — Intentional Rule"), that use varint_types keeps PHP semantics, and that #45's guards were moved to varint mode on purpose in 2166e1a. The compiler already rejects all of these when they are statically detectable ("has undefined behavior in C++ native mode"), which suggests the runtime form is a gap rather than a goal. A few points that may be worth weighing now that native is the default:

  • Overflow vs. crash. Overflow and integer division change a value; these cases terminate the process, bypass try/catch, and in a server take every request with them. A zero divisor coming from input is common.
  • They are undefined behavior, not just a different result. With --sanitize undefined UBSan reports each of them (division by zero, division of -9223372036854775808 by -1 cannot be represented, shift exponent 64 is too large, shift exponent -1 is negative), so the optimizer is free to assume they never happen.
  • The guard is cheap. php::fn::intdiv() already implements exactly these checks; for %// it is one well-predicted compare on the divisor, and it can be skipped whenever the divisor is a non-zero, non--1 constant, which the compiler already knows. Shifts need one compare on the count.

Would you accept a change that keeps native storage and native arithmetic, but adds these runtime checks to %, /, << and >> (throwing the same DivisionByZeroError / ArithmeticError as PHP, and returning 0 for PHP_INT_MIN % -1)? If raw speed matters for specific code, std::int() could remain the explicit no-check opt-in, as it is today for constant divisors. Happy to implement it with benchmarks if that direction is acceptable.

主要言語
PHP
スター
1.4k
フォーク
80
平均マージ
1日 8時間
マージ済み PR(30日)
26

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

swoole/typephp のほかの issue

swoole/typephp の issue をすべて見る

似ている issue

PHP の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。