D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 7303 - Erroneous closure behavior
Summary: Erroneous closure behavior
Status: RESOLVED DUPLICATE of issue 1841
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Linux
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-01-17 05:14 UTC by Vladimir Matveev
Modified: 2012-11-12 02:42 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Vladimir Matveev 2012-01-17 05:14:16 UTC
Consider this code:

module test;

import std.stdio;

class C {
    public int x;

    this(int x) {
        this.x = x;
    }
}

void delegate() test(int n) {
    C c = new C(n);

    void inner() {
        writeln(c.x);
    }

    return () { inner(); };
}

void main(string[] args) {
    auto d1 = test(12);
    auto d2 = test(13);
    d1();
    d2();
}

It prints 13 two times, though it should print first 12, then 13.

I found this problem while trying to create simple test case for the following similar closure-related error. I'm using gtkd to create UI for my program. This code

    TextBuffer logBuffer = logTextView.getBuffer();

    void logln(string s) {
        TextIter it = new TextIter();
        logBuffer.getEndIter(it);
        logBuffer.insert(it, s ~ "\n");
    }

    auto computeHandler = (Button aux) {
        logln("Compute pressed.");
    };

    auto singlePlotHandler = (Button aux) {
        logln("Single pressed.");
    };

    auto comparePlotHandler = (Button aux) {
        logln("Compare pressed.");
    };

segfaults when any of the *Handler closures are called (from the gtk event handling code). This happens because logBuffer variable used in logln function is null, though it shouldn't. If I use logBuffer in any way in any of the closures, the code works fine.

It seems that there's a problem in closed variables detection in both programs. In simple test case it does not crash the program because of its simplicity, but in the second one stack is overwritten many times after the delegates are created, so no wonder it fails.

I'm using dmd v2.057 on x86_64 linux system.
Comment 1 Don 2012-01-17 07:54:43 UTC
Duplicate of bug 1841?
Comment 2 Denis Shelomovskii 2012-11-12 02:38:43 UTC
(In reply to comment #1)
> Duplicate of bug 1841?

Yes. The closure isn't detected. Writing `&c` from `test.inner` showsw it is on stack but must be in heap.
Comment 3 Denis Shelomovskii 2012-11-12 02:39:46 UTC
(In reply to comment #1)
> Duplicate of bug 1841?

Yes. The closure isn't detected. Writing `&c` from `test.inner` showsw it is on stack but must be in heap.
Comment 4 Denis Shelomovskii 2012-11-12 02:42:25 UTC

*** This issue has been marked as a duplicate of issue 1841 ***