Skip to content

errdefer logic is not checked unless used #23288

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

Closed
Abstract-Everything opened this issue Mar 18, 2025 · 2 comments
Closed

errdefer logic is not checked unless used #23288

Abstract-Everything opened this issue Mar 18, 2025 · 2 comments
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@Abstract-Everything
Copy link

Zig Version

0.14.0

Steps to Reproduce and Observed Behavior

Note: I am not sure whether this is considered as a bug or not since it does not result in incorrect behaviour, but it does feel like it should not happen.

Run the following bash script:

mkdir /tmp/zig-issue/
cd /tmp/zig-issue/
zig init
echo 'fn f(a: u32) void { _ = a; }

fn e() !void {
    return error.E;
}

pub fn main() void {
    errdefer f();
    // try e();
}' > ./src/main.zig
zig build

This results in a successful build, even though the function call in errdefer f(); is invalid. Do note that uncommenting the try e(); line results in an error, as expected. Thus the issue seems that the compiler is not checking some semantics of the function call if it realises that the errdefer call never gets called. As stated above, this may not be considered a bug perse, but adding a try in a function only to then realise that a previous errdefer call is invalid seems wrong.

NOTE: This happens on 0.13.0 aswell, I was not sure whether the above field can take a list of versions

Expected Behavior

The compiler should output an error even if the errdefer is never called.

In terms of use case I encountered this because I was writing a resource acquisition function, I preemptively added an errdefer in case I later append more code to it, I then added another try statement later on and the call failed.

fn init(self: *S) !void {
  self.r = try acquire(1);
  errdefer release(self.r); // missed 1 as first parameter - see deinit()

  // later added another call and compilation failed
  try somethingelse();
}

fn deinit(self: *S) {
  release(1, self.r);
}
@Abstract-Everything Abstract-Everything added the bug Observed behavior contradicts documented or intended behavior label Mar 18, 2025
@tauoverpi
Copy link
Contributor

Duplicate of #2654

@mlugg
Copy link
Member

mlugg commented Mar 18, 2025

Working as intended.

@mlugg mlugg closed this as not planned Won't fix, can't repro, duplicate, stale Mar 18, 2025
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
Projects
None yet
Development

No branches or pull requests

3 participants