D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 8293 - Small amount of static analysis to avoid certain destructor bugs
Summary: Small amount of static analysis to avoid certain destructor bugs
Status: RESOLVED MOVED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-06-25 04:34 UTC by bearophile_hugs
Modified: 2022-08-16 11:40 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2012-06-25 04:34:59 UTC
A short thread in D.learn about a core.exception.InvalidMemoryOperationError:
http://forum.dlang.org/thread/js649p$1707$1@digitalmars.com

Caused by this code:

class X {
    string[string] s;
    this() {
        s["s"] = "S";
    }
    ~this() {
        s.remove("s");
    }
}
void main() {
    X x = new X();
}



Jonathan M Davis:

> you should never do anything in a class' destructor/finalizer which 
> could ever trigger the GC in any way.

In past I have seen other similar bugs discussed in D.learn.

I think a small amount of static analysis code added to the D front-end can statically avoid every bug of this kind. This code has to look inside ~this(){} and work recursively (like purity and nothrow enforcement do), searching for functions that perform GC activity.

(This is a bit different from the enforcement of the @noheap annotation I have suggested in Issue 5219 because it's OK to manage C-heap memory inside the destructor, while @noheap looks for C-heap activity too (malloc/realloc/calloc)).
Comment 1 yebblies 2013-01-16 18:59:22 UTC
The problem is that using the gc in a destructor is perfectly valid for two reasons:
- InvalidMemoryOperationError is just an implementation deficiency
- You can manually call the destructor

The first reason will go away eventually.
Comment 2 Marco Leise 2013-06-18 15:27:46 UTC
(In reply to comment #1)
> - You can manually call the destructor

Which more or less means that if such an object is allocated with new, there must always be a pointer to it to prevent automatic collection. Because it has to be manually destroyed to be safe.
Or can the GC be improved in this regard?
Comment 3 Vladimir Panteleev 2017-07-02 18:51:39 UTC
(In reply to Marco Leise from comment #2)
> Which more or less means that if such an object is allocated with new, there
> must always be a pointer to it to prevent automatic collection. Because it
> has to be manually destroyed to be safe.
> Or can the GC be improved in this regard?

Just use C malloc. This is what RefCounted!T does.
Comment 4 RazvanN 2022-08-16 11:40:15 UTC
This should be the job of a third party tool. It's not the compiler's job to check for things like this.