Skip to content
  • Eric Blake's avatar
    bac5429c
    qapi: Detect base class loops · bac5429c
    Eric Blake authored
    
    
    It should be fairly obvious that qapi base classes need to
    form an acyclic graph, since QMP cannot specify the same
    key more than once, while base classes are included as flat
    members alongside other members added by the child.  But the
    old check_member_clash() parser function was not prepared to
    check for this, and entered an infinite recursion (at least
    until Python gives up, complaining about nesting too deep).
    
    Now that check_member_clash() has been recently removed,
    attempts at self-inheritance trigger an assertion failure
    introduced by commit ac88219a.  The obvious fix is to turn
    the assertion into a conditional.
    
    This patch includes both the tests (base-cycle-direct and
    base-cycle-indirect) and the fix, since the .err file output
    for the unfixed case is not useful (particularly when it was
    warning about unbounded recursion, as that limit may be
    platform-specific).
    
    We don't need to worry about cycles in flat unions (neither
    the base type nor the type of a variant can be a union) nor
    in alternates (alternate branches cannot themselves be an
    alternate).  But if we later allow a union type as a variant,
    we will still be okay, as QAPISchemaObjectTypeVariants.check()
    triggers the same QAPISchemaObjectType.check() that will
    detect any loops.
    
    Likewise, we need not worry about the case of diamond
    inheritance where the same class is used for a flat union base
    class and one of its variants; either both uses will introduce
    a collision in trying to insert the same member name twice, or
    the shared type is empty and changes nothing.
    
    Signed-off-by: default avatarEric Blake <eblake@redhat.com>
    Message-Id: <1449033659-25497-16-git-send-email-eblake@redhat.com>
    Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
    bac5429c
    qapi: Detect base class loops
    Eric Blake authored
    
    
    It should be fairly obvious that qapi base classes need to
    form an acyclic graph, since QMP cannot specify the same
    key more than once, while base classes are included as flat
    members alongside other members added by the child.  But the
    old check_member_clash() parser function was not prepared to
    check for this, and entered an infinite recursion (at least
    until Python gives up, complaining about nesting too deep).
    
    Now that check_member_clash() has been recently removed,
    attempts at self-inheritance trigger an assertion failure
    introduced by commit ac88219a.  The obvious fix is to turn
    the assertion into a conditional.
    
    This patch includes both the tests (base-cycle-direct and
    base-cycle-indirect) and the fix, since the .err file output
    for the unfixed case is not useful (particularly when it was
    warning about unbounded recursion, as that limit may be
    platform-specific).
    
    We don't need to worry about cycles in flat unions (neither
    the base type nor the type of a variant can be a union) nor
    in alternates (alternate branches cannot themselves be an
    alternate).  But if we later allow a union type as a variant,
    we will still be okay, as QAPISchemaObjectTypeVariants.check()
    triggers the same QAPISchemaObjectType.check() that will
    detect any loops.
    
    Likewise, we need not worry about the case of diamond
    inheritance where the same class is used for a flat union base
    class and one of its variants; either both uses will introduce
    a collision in trying to insert the same member name twice, or
    the shared type is empty and changes nothing.
    
    Signed-off-by: default avatarEric Blake <eblake@redhat.com>
    Message-Id: <1449033659-25497-16-git-send-email-eblake@redhat.com>
    Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
Loading