cppfront icon indicating copy to clipboard operation
cppfront copied to clipboard

[BUG] Lambda that use capture `i$` with lambda argument `n` inside if statement failed with assertion

Open filipsajdak opened this issue 2 years ago • 0 comments

Using capture and if failed if done in some order.

In this cpp2 code cppfront fail on if i$ + n < std::ssize(line$):

lex_process_line: (line: std::string) = {
    i := 0;
    peek := :(n : int) -> char = {
        if i$ + n < std::ssize(line$) {} // it triggers assertion
        return '\0';
    };
}

https://godbolt.org/z/bTvzW4P6z

On Compiler Explorer it fails with the error:

cppfront: source/cppfront.cpp:1561: void cpp2::cppfront::emit(cpp2::postfix_expression_node&, bool): Assertion `n.expr' failed.
Compiler returned: 139

On my setup, it fails with the error:

Assertion failed: (cap.capture_expr->cap_grp == &captures), function build_capture_lambda_intro_for, file cppfront.cpp, line 1495.

The issue can be solved by changing the order of variables in the if statement:

lex_process_line: (line: std::string) = {
    i := 0;
    peek := :(n : int) -> char = {
        if n + i$ < std::ssize(line$) {} // works
        return '\0';
    };
}

https://godbolt.org/z/h8PGEs39K

by using parentheses:

lex_process_line: (line: std::string) = {
    i := 0;
    peek := :(n : int) -> char = {
        if (i$ + n) < std::ssize(line$) {} // works
        return '\0';
    };
}

https://godbolt.org/z/4v7YxevY7

Replacing n with the constant also works:

lex_process_line: (line: std::string) = {
    i := 0;
    peek := :(n : int) -> char = {
        if i$ + 2 < std::ssize(line$) {} // works
        return '\0';
    };
}

https://godbolt.org/z/hcefPbers

My expectation is that cppfront does not crash. It should work with various orders of variables or should show the error message if there is some preferred order.

filipsajdak avatar Oct 13 '22 20:10 filipsajdak