Skip to content

fix(optimizer): keep argument side effects when folding is_int/is_float/is_bool - #21

Open
AlessioGiacobbe wants to merge 1 commit into
swoole:masterfrom
AlessioGiacobbe:fix/fold-side-effects
Open

fix(optimizer): keep argument side effects when folding is_int/is_float/is_bool#21
AlessioGiacobbe wants to merge 1 commit into
swoole:masterfrom
AlessioGiacobbe:fix/fold-side-effects

Conversation

@AlessioGiacobbe

Copy link
Copy Markdown
Contributor

Problem

doFoldSsaType folds a statically type-known is_int() / is_float() / is_bool() call to the literal true, discarding the argument expression entirely:

function intSource(): int { echo "int-called\n"; return 42; }

if (is_int(intSource())) { ... }   // compiles to if (true) — intSource() is never invoked

The compiled binary skips the call and its side effects silently vanish (verified: int-called / float-called / bool-called all missing from the compiled output, present under PHP).

Fix

Fold to a bare true only when the argument is a plain variable or scalar literal. For any other argument emit ((void)(expr), true) so the operand is still evaluated — the same pattern genIsNull already uses for native scalar operands a few lines below.

Tests

  • New tests/compiler/optimizations/is-type-fold-side-effects.phpt: typed function calls as arguments to all three predicates plus the plain-variable fold. Expected output generated from PHP 8.4; compiled output diffs clean.
  • tests/compiler/optimizations/ suite: 35 pass, the 2 failing SSA float-narrowing tests fail identically on master (pre-existing). No new PHPStan errors.

…at/is_bool

doFoldSsaType folded a statically type-known is_int()/is_float()/
is_bool() call to the literal `true`, discarding the argument entirely.
With `function f(): int`, `if (is_int(f()))` compiled to `if (true)`
and f() was never invoked — its side effects silently vanished.

Fold to a bare `true` only for plain variables and scalar literals;
for any other argument emit `((void)(expr), true)` so the operand is
still evaluated, mirroring how genIsNull already handles native scalar
operands.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant