Thread overview
[Issue 15292] [REG2.068.0] Segmentation fault with self-referencing struct / inout / alias this
Nov 05, 2015
Vladimir Panteleev
Nov 16, 2015
Kenji Hara
Nov 19, 2015
Kenji Hara
November 05, 2015
https://issues.dlang.org/show_bug.cgi?id=15292

Vladimir Panteleev <thecybershadow@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[REG2.068.0] Segmentation   |[REG2.068.0] Segmentation
                   |fault with self-referencing |fault with self-referencing
                   |struct                      |struct / inout / alias this

--- Comment #1 from Vladimir Panteleev <thecybershadow@gmail.com> ---
Reduced:

//////// test.d ////////
struct NullableRef(T)
{
    inout(T) get() inout
    {
        assert(false);
    }

    alias get this;
}

struct Node
{
    NullableRef!Node n;
}
////////////////////////

--
November 16, 2015
https://issues.dlang.org/show_bug.cgi?id=15292

--- Comment #2 from Kenji Hara <k.hara.pg@gmail.com> ---
(In reply to Vladimir Panteleev from comment #1)
> Reduced:
> 
> //////// test.d ////////
> struct NullableRef(T)
> {
>     inout(T) get() inout
>     {
>         assert(false);
>     }
> 
>     alias get this;
> }
> 
> struct Node
> {
>     NullableRef!Node n;
> }
> ////////////////////////

An infinite recursive analysis happens in the implicitly generated member function:

    bool Node.__xopEquals(ref const Node p, ref const Node q)
    {
        return p == q;
    }

The equality test p == q is expanded to p.tupleof == q.tupleof, and it's equivalent with p.n == q.n.

Because of the alias-this definition in NuallbeRef!Node, the comparison is delegated to the return of get member function, then it's rewritten to p.n.get() == q.n.get(). Finally, we'll go into an endless circle.

Now I have a local patch to detect the circle. But I'm yet not sure how compiler should work for the following code.

    void main()
    {
        Node node;
        assert(node == node);    // ?
    }

I think the Node equality should be either:
  1. make an error
  2. implicitly fallback to bitwise comparison

--
November 19, 2015
https://issues.dlang.org/show_bug.cgi?id=15292

Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #3 from Kenji Hara <k.hara.pg@gmail.com> ---
https://github.com/D-Programming-Language/dmd/pull/5274

--
November 19, 2015
https://issues.dlang.org/show_bug.cgi?id=15292

github-bugzilla@puremagic.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--
November 19, 2015
https://issues.dlang.org/show_bug.cgi?id=15292

--- Comment #4 from github-bugzilla@puremagic.com ---
Commits pushed to stable at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/2f0cc57aa71a6ff67f27ec3727841ec756c843fb
fix Issue 15292 - Segmentation fault with self-referencing struct / inout /
alias this

If you read the `expr.aliasthis` to `expr.tupleof`, you could understand that the mechanism to detect recursive tupleof expansion is same with for alias-this'es.

https://github.com/D-Programming-Language/dmd/commit/dff37b9526d154f844f7a35340015ef3e93975d3 Merge pull request #5274 from 9rnsr/fix15292

[REG2.068.0] Issue 15292 - Segmentation fault with self-referencing struct / inout / alias this

--
December 01, 2015
https://issues.dlang.org/show_bug.cgi?id=15292

--- Comment #5 from github-bugzilla@puremagic.com ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/2f0cc57aa71a6ff67f27ec3727841ec756c843fb
fix Issue 15292 - Segmentation fault with self-referencing struct / inout /
alias this

https://github.com/D-Programming-Language/dmd/commit/dff37b9526d154f844f7a35340015ef3e93975d3 Merge pull request #5274 from 9rnsr/fix15292

--