D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 10409 - dtor / destructor not called for (rvalue) struct used in opApply
Summary: dtor / destructor not called for (rvalue) struct used in opApply
Status: REOPENED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P3 normal
Assignee: No Owner
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2013-06-18 16:09 UTC by Marco Leise
Modified: 2024-12-13 18:08 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Marco Leise 2013-06-18 16:09:26 UTC
This code

--- 8< ---------------

import core.stdc.stdio;

struct DestroyMe
{
	~this() { printf("~this() called\n"); }

	int opApply(in int delegate(int item) dg)
	{
		throw new Exception("Here we go!");
	}
}

void main()
{
	printf("Version with no dtor call:\n");
	try {
		foreach (item; DestroyMe()) {}
	} catch {}
	printf("Version with dtor call:\n");
	try {
		auto lvalue = DestroyMe();
		foreach (item; lvalue) {}
	} catch {}
}

--- >8 --------------

prints:
Version with no dtor call:
Version with dtor call:
~this() called

So the dtor call gets missed when the struct's scope is inside the foreach header. There is another open bug about struct destructors not being called on out parameters:
http://d.puremagic.com/issues/show_bug.cgi?id=6186
Comment 1 Kenji Hara 2013-07-07 23:13:36 UTC
I couldn't reproduce the issue on Windows7, by using release-dmd versions from 2.058 to 2.063.2. What version do you use?
Comment 2 Marco Leise 2013-07-08 02:54:27 UTC
(In reply to comment #1)
> I couldn't reproduce the issue on Windows7, by using release-dmd versions from
> 2.058 to 2.063.2. What version do you use?

I was using GDC and LDC. It really doesn't happen with DMD. I'll mark this as invalid and open new reports for the other compilers. Thanks for looking into this anyway!
Comment 3 Iain Buclaw 2013-07-08 11:34:09 UTC
From the backend's perspective, the frontend represents the code in this way:

try
{
    DestroyMe __sl5;
    DestroyMe.opApply (&__sl5, {.object=0B, .func=__foreachbody6});
    apply.DestroyMe.~this (&__sl5);
}
catch (struct Throwable &)
{
}


try
{
    struct DestroyMe lvalue;

    try
    {
        DestroyMe.opApply (&lvalue, {.object=0B, .func=__foreachbody8});
    }
    finally
    {
        apply.DestroyMe.~this (&lvalue);
    }
}
catch (struct Throwable &)
{
}


In this instance, you could either say that it is the job of the backend to wrap ExpDtorStatement's in try{} finally{} blocks, or fix the frontend to generate a matching representation.
Comment 4 Iain Buclaw 2013-07-08 12:15:06 UTC
(In reply to comment #3)
> In this instance, you could either say that it is the job of the backend to
> wrap ExpDtorStatement's in try{} finally{} blocks, or fix the frontend to
> generate a matching representation.

Hmmm... I meant Expression::toElemDtor.  :)
Comment 5 dlangBugzillaToGithub 2024-12-13 18:08:25 UTC
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/17594

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB