www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 15056] New: [REG2.068] Unstored RAII struct return yields


          Issue ID: 15056
           Summary: [REG2.068] Unstored RAII struct return yields bogus
                    error: "cannot mix core.std.stdlib.alloca() and
                    exception handling"
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Keywords: rejects-valid
          Severity: regression
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: Marco.Leise gmx.de

This code snippet illustrates the problem. This would compile on 2.067.1:

1) ---------------------
import core.stdc.stdlib;

struct S
    ~this() {}

S foo(void* p = alloca(1234))
    return S();

int main()
    return 0;

With a little change to "main" it compiles again:

void main()
    S s = foo();

Both the removal of a return statement and the storage into an unused variable
are now necessary to work with alloca() in this fashion.
Here is another (complete) test case where RAII and alloca() can't be used in
the same function.

2) ---------------------
int main()
    import core.stdc.stdlib;
    struct S { ~this() nothrow {}}
    S s;
    return 1;

The use case of 1) is to enable a called function to allocate dynamic memory
from its caller's stack or use malloc() if the memory requirement is large. The
return value is then a RAII struct that - upon destruction - calls free() iff
malloc() was used and does nothing if alloca() was used. This idiom allows for
concise code that executes extremely fast and uses the least possible amount of
stack memory, but must not be used in loops because alloca()'s allocations can
only be released by returning from a function. It is a foundation of my "fast"
library on GitHub.

This broke once before due to the inliner:
The test case added back then can probably just be extended to cover this new

Sep 13 2015