Commit b2dd3bc
committed
[mypyc] Fix memory leak when borrowing property getter return values
`is_native_attr_ref()` decides whether an attribute access can safely
use a borrowed reference (skipping DECREF). It used `has_attr(name) and
not get_method(name)` — the idea being: if there's an attribute but no
method, it's a struct field (safe to borrow).
However, `has_attr()` checks both `ir.attributes` (struct fields) and
`ir.property_types` (properties), and is populated during the
preparation phase (always complete). `get_method()` checks `ir.methods`,
which is populated during the compilation phase, one module at a time.
When modules within an SCC are compiled in nondeterministic order (set
iteration of `scc.mod_ids`), `ir.methods` may not be populated for a
cross-module class yet. `get_method()` then returns None for a property
getter that hasn't been compiled, causing `is_native_attr_ref` to
incorrectly return True — treating the property as a plain struct field.
Property getters are method calls that return new owned references (the
getter INCREFs before returning). Marking the result as borrowed skips
the DECREF, leaking one reference per call.
The fix checks `ir.attributes` directly (struct fields only, always
populated during preparation) instead of the unreliable `has_attr()` +
`not get_method()` combination. Properties are never in `ir.attributes`,
so they will always correctly return False.
Note: the underlying issue is that modules within an SCC are compiled in
nondeterministic order, and `ir.methods` is not populated until a
module's function bodies are compiled. Any code that reads `ir.methods`
during compilation of a different module in the same SCC could have
similar order-dependent bugs.1 parent 818e932 commit b2dd3bc
2 files changed
Lines changed: 45 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1467 | 1467 | | |
1468 | 1468 | | |
1469 | 1469 | | |
1470 | | - | |
1471 | | - | |
| 1470 | + | |
1472 | 1471 | | |
1473 | 1472 | | |
1474 | 1473 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6000 | 6000 | | |
6001 | 6001 | | |
6002 | 6002 | | |
| 6003 | + | |
| 6004 | + | |
| 6005 | + | |
| 6006 | + | |
| 6007 | + | |
| 6008 | + | |
| 6009 | + | |
| 6010 | + | |
| 6011 | + | |
| 6012 | + | |
| 6013 | + | |
| 6014 | + | |
| 6015 | + | |
| 6016 | + | |
| 6017 | + | |
| 6018 | + | |
| 6019 | + | |
| 6020 | + | |
| 6021 | + | |
| 6022 | + | |
| 6023 | + | |
| 6024 | + | |
| 6025 | + | |
| 6026 | + | |
| 6027 | + | |
| 6028 | + | |
| 6029 | + | |
| 6030 | + | |
| 6031 | + | |
| 6032 | + | |
| 6033 | + | |
| 6034 | + | |
| 6035 | + | |
| 6036 | + | |
| 6037 | + | |
| 6038 | + | |
| 6039 | + | |
| 6040 | + | |
| 6041 | + | |
| 6042 | + | |
| 6043 | + | |
| 6044 | + | |
| 6045 | + | |
| 6046 | + | |
0 commit comments