Skip to content

basicblock_addop Assertion #109627

Closed
Closed

Description

@15r10nk

Bug report

Bug description:

I found the following error with the latest cpython 3.12 from git (4a0c118), which I build myself with --with-pydebug enabled.

source:

def get_namespace_uri():
    while element and something:
        try:
            return something
        except:
            pass

output (Python 3.12.0rc3+):

python3: Python/flowgraph.c:114: basicblock_addop: Assertion `0 <= oparg && oparg < (1 << 30)' failed.

CPython versions tested on:

3.12

Operating systems tested on:

Linux

Linked PRs

Activity

  1. JelleZijlstra commented on Sep 20, 2023

    @JelleZijlstra
    Member

    Confirmed on main, 3.11 is fine. cc @iritkatriel for flowgraph.c.

    I'll try to bisect but not sure I'll have time to finish the bisect.

  2. iritkatriel commented on Sep 20, 2023

    @iritkatriel
    Member

    I'm looking. I don't think bisecting will help - the jump targets labels are new so you'll probably get to the large PR that added them.

  3. added 2 commits that reference this issue on Sep 20, 2023
  4. iritkatriel commented on Sep 20, 2023

    @iritkatriel
    Member

    In order to ensure that function exits have a line number, the compiler duplicates small exit blocks which (1) do not have a line number in any instruction and (2) have more than one predecessor. Since these blocks are jump targets (at least one predecessor reaches this block via a jump or exception), they need to have labels assigned to them. This was missing, and is added in the attached PR.

    This begs the question "how did this ever work?"

    The assertion that fails here is in a piece of code that transforms a conditional backwards jump into a conditional forward jump followed by an unconditional backward jump (because all backward jumps are unconditional). It is this code that asserted the label. In general the labels are not that useful this late in the compiler's process, they are mostly used in the code generation phase, before we have the CFG with a direct pointer from a jump to its target block.

    The typical case of a small basic block is the "return None" of a function, and it is not a target of a conditional backward branch - this is what made this edge case rare.

  5. iritkatriel commented on Sep 20, 2023

    @iritkatriel
    Member

    @15r10nk - Thank you for finding this and for the tiny repro.

  6. added 3 commits that reference this issue on Sep 20, 2023
  7. 15r10nk commented on Sep 21, 2023

    @15r10nk
    ContributorAuthor

    @iritkatriel thank you for fixing this bug.
    I would also like to mention that I automatically minimized the example with pysource-minimize. maybe you will find that useful too.

  8. added a commit that references this issue on Sep 22, 2023
  9. added a commit that references this issue on Sep 28, 2023
  10. added a commit that references this issue on Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.12only security fixes3.13only security fixesrelease-blockertype-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions