Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

design flaw: self-hosted compiler uses its own stack for comptime function calls, resulting in stack overflow when the host system does not provide a large enough stack #13724

Open
andrewrk opened this issue Dec 1, 2022 · 5 comments
Labels
bug Observed behavior contradicts documented or intended behavior enhancement Solving this issue will likely involve adding new logic or components to the codebase. frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Dec 1, 2022

zig version: 0.11.0-dev.407+34fa6a1e0

Ideally this code would produce a compile error: comptime execution exceeded 1000 branches. However,

const assert = @import("std").debug.assert;

fn fibonacci(index: i32) i32 {
    //if (index < 2) return index;
    return fibonacci(index - 1) + fibonacci(index - 2);
}

test "fibonacci" {
    comptime {
        try assert(fibonacci(7) == 13);
    }
}

This causes a segfault in many cases due to stack overflow. It cannot be solved by asking for more stack space for these reasons:

  • Some systems or environments do not support this, or otherwise make it awkward.
  • There can always be adversarial code that causes a stack overflow instead of a proper error message simply by using @setEvalBranchQuota.

Until this is fixed I am unfortunately going to have to edit the corresponding code snippet from the language reference:

zig/doc/langref.html.in

Lines 7032 to 7052 in a943422

{#code_begin|test_err|evaluation exceeded 1000 backwards branches#}
{#backend_stage1#}
const assert = @import("std").debug.assert;
fn fibonacci(index: i32) i32 {
//if (index < 2) return index;
return fibonacci(index - 1) + fibonacci(index - 2);
}
test "fibonacci" {
comptime {
try assert(fibonacci(7) == 13);
}
}
{#code_end#}
<p>
The compiler noticed that evaluating this function at compile-time took a long time,
and thus emitted a compile error and gave up. If the programmer wants to increase
the budget for compile-time computation, they can use a built-in function called
{#link|@setEvalBranchQuota#} to change the default number 1000 to something else.
</p>

@andrewrk andrewrk added bug Observed behavior contradicts documented or intended behavior frontend Tokenization, parsing, AstGen, Sema, and Liveness. labels Dec 1, 2022
@andrewrk andrewrk added this to the 0.11.0 milestone Dec 1, 2022
andrewrk added a commit that referenced this issue Dec 1, 2022
@Jarred-Sumner
Copy link
Contributor

once async is implemented what if you have a separate stack for calling comptime functions and then use nosuspend @asyncCall?

andrewrk added a commit that referenced this issue Dec 1, 2022
@Vexu
Copy link
Member

Vexu commented Dec 1, 2022

Duplicate of #12973

@Vexu Vexu marked this as a duplicate of #12973 Dec 1, 2022
@Vexu Vexu closed this as completed Dec 1, 2022
wooster0 pushed a commit to wooster0/zig that referenced this issue Dec 1, 2022
@Vexu
Copy link
Member

Vexu commented Dec 20, 2022

Not a duplicate since this is comptime and the other is an inline call.

@Inve1951
Copy link
Contributor

Inve1951 commented Mar 20, 2023

Here's another simple reproduction:

fn rec(comptime i: comptime_int) comptime_int {
    return if (i == 1e3) i else rec(i + 1);
}
test "comptime stack overflow" {
    // @setEvalBranchQuota(100_000);
    _ = rec(0);
}

I'd at least expect an error message indicating that there was a stack overflow (however that can be accomplished). Currently there's no output.

@andrewrk andrewrk modified the milestones: 0.11.0, 0.12.0 Jul 20, 2023
@andrewrk andrewrk added the enhancement Solving this issue will likely involve adding new logic or components to the codebase. label Jul 20, 2023
@matu3ba
Copy link
Contributor

matu3ba commented Aug 3, 2023

keywords to prevent duplicates: recursive, comptime, stack overflow, segfault

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior enhancement Solving this issue will likely involve adding new logic or components to the codebase. frontend Tokenization, parsing, AstGen, Sema, and Liveness.
Projects
None yet
Development

No branches or pull requests

5 participants