Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 13, 2014 [Issue 13468] std.algorithm.canFind(null) fails with class | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=13468 murphyslaw480@gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |murphyslaw480@gmail.com -- |
October 02, 2014 [Issue 13468] std.algorithm.canFind(null) fails with class | ||||
---|---|---|---|---|
| ||||
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 [Issue 13468] std.algorithm.canFind(null) fails with class | ||||
---|---|---|---|---|
| ||||
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 [Issue 13468] std.algorithm.canFind(null) fails with class | ||||
---|---|---|---|---|
| ||||
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 [Issue 13468] std.algorithm.canFind(null) fails with class | ||||
---|---|---|---|---|
| ||||
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 [Issue 13468] std.algorithm.canFind(null) fails with class | ||||
---|---|---|---|---|
| ||||
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 [Issue 13468] Wrong code when comparing class reference with typeof(null) | ||||
---|---|---|---|---|
| ||||
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 [Issue 13468] Wrong code when comparing class reference with typeof(null) | ||||
---|---|---|---|---|
| ||||
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 [Issue 13468] Wrong code when comparing class reference with typeof(null) | ||||
---|---|---|---|---|
| ||||
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 [Issue 13468] Wrong code when comparing class reference with typeof(null) | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=13468 github-bugzilla@puremagic.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution|--- |FIXED -- |
Copyright © 1999-2021 by the D Language Foundation