Skip to content

Instantly share code, notes, and snippets.

@devdanzin
Created March 18, 2026 10:06
Show Gist options
  • Select an option

  • Save devdanzin/1053175c252bf8430cc2c2b96671d15f to your computer and use it in GitHub Desktop.

Select an option

Save devdanzin/1053175c252bf8430cc2c2b96671d15f to your computer and use it in GitHub Desktop.
codegen.c + compile.c + assemble.c: Ref leaks and error handling bugs in compiler

codegen.c + compile.c + assemble.c: Ref leaks and error handling bugs in compiler

Summary

6 bugs in the compiler pipeline:

  1. codegen.c:716: PyLong_FromLong result not NULL-checked, passed to ADDOP_LOAD_CONST. Also never DECREF'd.
  2. codegen.c:3280: RETURN_IF_ERROR(scope) leaks mangled from _PyCompile_MaybeMangle.
  3. codegen.c:792-818: mangled leaked on 7 macro early-return paths.
  4. codegen.c:669: Unchecked _PyCompile_PushFBlock return, error silently lost.
  5. compile.c:1096-1114: PyDict_GetItemRef new ref in orig never DECREF'd. Leaks on every inlined comprehension.
  6. assemble.c:420-421: ERROR without PyErr_NoMemory() on bytecode overflow.

Reproducer (compile.c comprehension leak)

import sys
before = sys.gettotalrefcount()
for i in range(10000):
    compile("[x for x in range(10)]", "<test>", "eval")
after = sys.gettotalrefcount()
print(f"Leaked {after - before} refs")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment