Skip to content

[Bug Report] Compiler crashes when compiling all() on iterating over a heterogenouos tuple #711

@MetalOxideSemi

Description

@MetalOxideSemi

Environment

  • Codon version: v0.19.3
  • OS: Debian bullseye

Description

Codon compiler crashes with a segmentation fault when compiling code that uses a generator expression with all() to iterate over a tuple of multiple class instances.

Steps to Reproduce

  1. Code
class A:
    def __init__(self, a: int):
        self.a = a
    
    def filter(self, x: int) -> bool:
        return x % self.a == 0
    
class B:
    def __init__(self, b: float):
        self.b = b
        
    def filter(self, x: int) -> bool:
        return x % self.b == 0

class FilterCombiner:
    def __init__(self, *args):
        self.filters = tuple(args)

    def filter(self, x: int) -> bool:
        return all(f.filter(x) for f in self.filters)

fc = FilterCombiner(A(2), B(3.0))
fc.filter(1)
  1. Run: ./codon run crash_on_filter.py

Expected Behavior

The code should compile and execute successfully, returning the result of the filter operation.

Actual Behavior

The compiler crashes with a segmentation fault:

[1]    1803306 segmentation fault (core dumped)  ./codon run temp/crash_on_filter.py

Debug Information

Using GDB, the crash occurs at:

Program received signal SIGSEGV, Segmentation fault.
codon::ast::TypecheckVisitor::visit (this=0x7fffffff7dd0, expr=0xe2af2f0)
    at codon/parser/visitors/typecheck/collections.cpp:144

Stack trace:

#0  codon::ast::TypecheckVisitor::visit (this=0x7fffffff7dd0, expr=0xe2af2f0)
    at codon/parser/visitors/typecheck/collections.cpp:144

Root cause location:
File: codon/parser/visitors/typecheck/collections.cpp:144

Function:

Expr *GeneratorExpr::getFinalExpr() {
  auto s = *(getFinalStmt());
  if (cast<ExprStmt>(s))
    return cast<ExprStmt>(s)->getExpr();
  return nullptr;
}

GDB inspection:

(gdb) p expr
$1 = (codon::ast::GeneratorExpr *) 0xe2af2f0

(gdb) p expr->getFinalExpr()
$2 = (codon::ast::Expr *) 0x0

The issue appears to be that getFinalExpr() returns nullptr, which is then dereferenced, causing the segmentation fault.

The crash occurs during type checking of the generator expression (f.filter(x) for f in self.filters) when used with all(). The GeneratorExpr::getFinalExpr() returns null, suggesting the generator expression's final statement is not properly initialized or handled during type checking when dealing with heterogeneous class types (A and B) stored in a tuple.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions