Skip to content

AsyncSignalSetterReturnMisread ​

warning native off by default quick-fix PHP ≥ 7.1

Group: Probable bugs

Query the signal state after changing it.

Example ​

php
<?php
if (!pcntl_async_signals(true)) { throw new RuntimeException(); }

Reported:

  • line 2: Query the signal state after changing it.

Detection ​

This is an opt-in policy. Truthiness, previous-state checks, raw wait-status comparisons and dispatch acknowledgements can be intentional; enabling this rule requests explicit handling of the contract described below.

  • D1. Report a resolved pcntl_async_signals setter with a proven nonnull scalar argument used directly in a truthiness or negation condition. Getter calls, null and unknown enable values are excluded. A standalone negated if condition may be repaired by moving the setter before the if and testing the getter.
  • Resolve builtin functions, extension classes, method receivers, constants and named arguments. Follow unchanged locals and aliases only within the same bounded lexical scope. Require a reachable path; merge branch facts only when all incoming paths establish them.
  • Emit one finding at the violating operation, not one per evidence statement. Rebinding, writes, by-reference escape and unresolved calls that can mutate relevant state remove proof. When the proof is inconclusive, nothing is reported.

Exceptions (no report) ​

Getter-mode null is resolved through unchanged locals and parentheses. A fix that inserts a statement requires a statement list: the file top level, a namespace body in either its semicolon or braced form, a braced or alternative-syntax block, or a switch case. Withhold it when the if is the unbraced body of another statement.

  • Exclude shadowed builtins, unresolved receivers, incomplete syntax and unknown prerequisite facts. An extension function name alone does not prove an application function is that builtin.
  • A dominating valid guard or repair described in Detection prevents the finding. Both legacy noinspection and custos-ignore forms suppress this ID.

Fix ​

For a standalone if condition that is exactly !setter, move the original setter to a preceding expression statement and test a zero-argument getter with the original polarity. Comparisons of the setter result against a boolean are previous-state checks that D1 does not report, so they are never rewritten. No fix for elseif, nested short-circuit conditions, assignments, comments across moved ranges or expressions evaluated conditionally.

All edits use exact byte ranges and preserve comments and evaluation order. Offer no fix when its stated prerequisites cannot be proven or the replacement is unsupported by the configured PHP version.

PHP versions ​

Requires PHP 7.1 or later and the referenced extension API. Respect method-specific introduction versions within PHP 5.3–8.5; unsupported optional APIs cannot establish facts. Named arguments require PHP 8.0 or later.

Configure ​

In custos.json:

json
{
  "rules": {
    "AsyncSignalSetterReturnMisread": {
      "enabled": true
    }
  }
}

Suppress ​

Before the statement or declaration (or the first statement of the file):

php
// @custos-ignore AsyncSignalSetterReturnMisread

Released under the MIT License. Native rules and rules modeled on Php Inspections (EA Extended); independent clean-room implementation.