Visitor for finding defined registers. Note that this only deals with registers and not temporaries, on the assumption that we never access temporaries when they might be undefined. If strict_errors is True, then we regard any use of LoadErrorValue as making a register undefine
| 300 | |
| 301 | |
| 302 | class DefinedVisitor(BaseAnalysisVisitor[Value]): |
| 303 | """Visitor for finding defined registers. |
| 304 | |
| 305 | Note that this only deals with registers and not temporaries, on |
| 306 | the assumption that we never access temporaries when they might be |
| 307 | undefined. |
| 308 | |
| 309 | If strict_errors is True, then we regard any use of LoadErrorValue |
| 310 | as making a register undefined. Otherwise we only do if |
| 311 | `undefines` is set on the error value. |
| 312 | |
| 313 | This lets us only consider the things we care about during |
| 314 | uninitialized variable checking while capturing all possibly |
| 315 | undefined things for refcounting. |
| 316 | """ |
| 317 | |
| 318 | def __init__(self, strict_errors: bool = False) -> None: |
| 319 | self.strict_errors = strict_errors |
| 320 | |
| 321 | def visit_branch(self, op: Branch) -> GenAndKill[Value]: |
| 322 | return _EMPTY |
| 323 | |
| 324 | def visit_return(self, op: Return) -> GenAndKill[Value]: |
| 325 | return _EMPTY |
| 326 | |
| 327 | def visit_unreachable(self, op: Unreachable) -> GenAndKill[Value]: |
| 328 | return _EMPTY |
| 329 | |
| 330 | def visit_register_op(self, op: RegisterOp) -> GenAndKill[Value]: |
| 331 | return _EMPTY |
| 332 | |
| 333 | def visit_assign(self, op: Assign) -> GenAndKill[Value]: |
| 334 | # Loading an error value may undefine the register. |
| 335 | if isinstance(op.src, LoadErrorValue) and (op.src.undefines or self.strict_errors): |
| 336 | return set(), {op.dest} |
| 337 | else: |
| 338 | return {op.dest}, set() |
| 339 | |
| 340 | def visit_assign_multi(self, op: AssignMulti) -> GenAndKill[Value]: |
| 341 | # Array registers are special and we don't track the definedness of them. |
| 342 | return _EMPTY |
| 343 | |
| 344 | def visit_set_mem(self, op: SetMem) -> GenAndKill[Value]: |
| 345 | return _EMPTY |
| 346 | |
| 347 | |
| 348 | def analyze_maybe_defined_regs( |
no outgoing calls
no test coverage detected
searching dependent graphs…