Jump to page: 1 2
Thread overview
[Issue 13468] std.algorithm.canFind(null) fails with class
[Issue 13468] Wrong code when comparing class reference with typeof(null)
Nov 11, 2014
yebblies
September 13, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

murphyslaw480@gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |murphyslaw480@gmail.com

--
October 02, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh@quickfur.ath.cx

--- Comment #1 from hsteoh@quickfur.ath.cx ---
Found the cause of the bug. The problem is that when comparing two class references, the default predicate attempts to compare two class references with ==, which appears to dereference a NULL and cause a segfault. If "a is b" is used as predicate instead, there is no crash. Next is to find out why == doesn't handle null pointers correctly...

--
October 02, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

--- Comment #2 from hsteoh@quickfur.ath.cx ---
Actually it's quite simple. The expression a == b, in the case of classes, is lowered into a.opEquals(b). Since a is null when find/canFind gets to a null element in the array, opEquals is invoked with a null this pointer, with disastrous consequences.

--
October 02, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

--- Comment #3 from hsteoh@quickfur.ath.cx ---
Workaround:

Instead of using the default predicate "a==b" with null (i.e., effectively "a == null"), use this instead:

    if (canFind!"a is null"(b)) { ... }

--
October 02, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

--- Comment #4 from hsteoh@quickfur.ath.cx ---
Alternate syntax:

    if (canFind!((a) => a is null)(b)) { ... }

--
October 02, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
          Component|Phobos                      |DMD

--- Comment #5 from hsteoh@quickfur.ath.cx ---
Apparently I made a total fool of myself. The *real* reason for the bug is not
a.opEquals(b), but is caused by using == to compare a class reference to an
instance of typeof(null).

Specifically, this code works:
----------
class C { }
bool fun(C e, C needle)
{
    return (e == needle);
}
void main()
{
    fun(null, null);
}
----------

But this code segfaults:
----------
class C { }
bool fun(C e, typeof(null) needle)
{
    return (e == needle);
}
void main()
{
    fun(null, null);
}
----------

The only difference is that the segfaulting case takes `typeof(null)` as parameter. Comparing class references with null is actually OK; what's *not* OK is comparing them with an instance of typeof(null). I think this is a compiler bug.

--
October 02, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|std.algorithm.canFind(null) |Wrong code when comparing
                   |fails with class            |class reference with
                   |                            |typeof(null)

--
October 02, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

--- Comment #6 from hsteoh@quickfur.ath.cx ---
Looking at the disassembly, in the first (working) case, Object.opEquals() is
called directly. In the second (segfaulting) case, it appears to be doing a
lookup of the vtable (or perhaps typeinfo?) of either C or typeof(null) and
dereferencing it without checking for null.

--
November 11, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

yebblies <yebblies@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull
                 CC|                            |yebblies@gmail.com
           Hardware|x86_64                      |All
                 OS|Linux                       |All

--- Comment #7 from yebblies <yebblies@gmail.com> ---
Pull to essentially treat typeof(null) == class as typeof(null) is class.

https://github.com/D-Programming-Language/dmd/pull/4135

--
November 12, 2014
https://issues.dlang.org/show_bug.cgi?id=13468

github-bugzilla@puremagic.com changed:

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

--
« First   ‹ Prev
1 2