digitalmars.D.bugs - [Issue 4595] New: Accessing non-static member of a null reference compiles
- d-bugmail puremagic.com (32/32) Aug 07 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (13/13) Aug 07 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (13/13) Aug 07 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (27/27) Aug 07 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (8/10) Aug 07 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (28/28) Aug 07 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (17/18) Aug 07 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (8/10) Aug 07 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (10/10) Aug 08 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (11/11) Aug 08 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (7/7) Aug 08 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (6/6) Sep 21 2010 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (22/22) Dec 18 2011 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (16/28) Sep 17 2013 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (47/50) Sep 19 2013 http://d.puremagic.com/issues/show_bug.cgi?id=4595
- d-bugmail puremagic.com (10/18) Sep 19 2013 http://d.puremagic.com/issues/show_bug.cgi?id=4595
http://d.puremagic.com/issues/show_bug.cgi?id=4595 Summary: Accessing non-static member of a null reference compiles Product: D Version: D2 Platform: Other OS/Version: Windows Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: andrej.mitrovich gmail.com 17:02:48 PDT --- This should not compile, DMD should detect that I'm trying to access a member of a null reference (stated in TDPL): class A { int x = 42; } unittest { A a; a.x = 5; } void main() { } Runtime error: object.Error: Access Violation -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 17:05:41 PDT --- And an additional example: class A { int x; } unittest { A a; assert(__traits(compiles, a.x = 5)); } void main() { } Compiles and runs succesfully. assert should fail. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 nfxjfg gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED CC| |nfxjfg gmail.com Resolution| |INVALID You're obviously free to cause all access violation you want. dmd never prevented that, and no non-nullable references feature is planned. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 bearophile_hugs eml.cc changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bearophile_hugs eml.cc You are mostly right nfxjfg, but please don't be harsh with people that use their time to submit problems in Bugzilla :-) See enhancement request bug 4571 for a start of a proposal about non-null types modifier in D. It needs more work, of course. And even if D will never have non-null references in its type system, DMD is already able to catch cases like this, if you compile it with -O: class Foo { int x; } void main() { Foo f; f.x = 5; } dmd 2.047 doesn't show a run-time sefault, it prints at compile-time: test.d(4): Error: null dereference in function _Dmain So adding few more logic to the compiler to catch other common cases of uninitialized bugs is not inconceivable. The case shown in this bug reports are well within the capabilities of a short analysis, good lint tools are able to warn against far more complex cases. So I think this enhancement request should be reopened. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595dmd 2.047 doesn't show a run-time sefault, it prints at compile-time: test.d(4): Error: null dereference in function _DmainI'd consider that a codegen bug. What if my program's semantics depend on the segfault? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 Jonathan M Davis <jmdavisProg gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jmdavisProg gmail.com 20:37:32 PDT --- No offense, but relying on a segfault seems rather silly. And if you really need one, I'm sure that you could easily produce one which the compiler can't catch (probably all it would take would be a function which returned null being used to initialize the variable rather than just declaring the variable). I think that it's perfectly reasonable for dmd to catch simple and obvious cases where a null reference or pointer is going to be dereferenced. In other to scream at you if do something like that and force you to initialize the variable. D goes the route of default initialization to the closest thing to an error value rather than forcing you to initialize variables before they're used, but I think that it's perfectly reasonable for the compiler to catch simple and obvious cases and scream at you about them. I believe that the main reason that dmd doesn't do it in the general case is because it's too hard for the compiler to accurately catch more complex cases without making the compiler much more complex in its code flow analysis (and Walter doesn't want that kind of complexity). There's no question that you cannot rely on the compiler to catch all of the references and pointers that you forgot to initialize, but I see nothing wrong with it catching some of them. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 bearophile_hugs eml.cc changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|INVALID | Severity|normal |enhancementWhat if my program's semantics depend on the segfault?That means relying on undefined or OS/machine-dependant behaviour. You are not programming in D any more. I reopen this, but as enhancement request, because while I don't think that Walter will implement this very soon, it's a legit feature request for a D compiler to catch at compile-time one more case of uninitialized object reference. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595That means relying on undefined or OS/machine-dependant behaviour. You are not programming in D any more.Then what is supposed to happen on a null reference access in D according to your opinion? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 07 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 Generally the D program stops, some things happen deterministically inside the GC and the D code and the underlying C runtime, some events happen to the threads of your D code in a partially deterministic way, but then what exactly happens is specified by the Operating System and Memory Management Unit of your computer. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 08 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 09:16:57 PDT --- This is not a feature request. The TDPL specifically states that in *simple* cases such as these, DMD should flag this as an error. Otherwise if it can't figure out if it indeed is a null-reference, it will compile and let the user handle it. I usually compile with all warnings on. Thanks for the -O trick, bearophile. I never thought adding optimizations can catch bugs like that. :) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 08 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 With -O -unittest DMD is already able to catch the first of the two shown cases (it doesn't catch the case with __traits(compiles, a.x = 5). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 08 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 See also bug 4906 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 21 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4595 Andrei Alexandrescu <andrei metalanguage.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrei metalanguage.com Summary|Accessing non-static member |[tdpl] Accessing non-static |of a null reference |member of a null reference |compiles |compiles 20:20:09 PST --- Failing unittest in TDPL: unittest { class A { int x; } A a; assert(!__traits(compiles, a.x = 5)); } Such programs must be statically rejected, guaranteed if there's no intervening flow in between definition and first use. We can work on improving that later, but for now let's get the obvious case out of the way. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 18 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4595 12:54:33 PDT ---Failing unittest in TDPL: unittest { class A { int x; } A a; assert(!__traits(compiles, a.x = 5)); } Such programs must be statically rejected, guaranteed if there's no intervening flow in between definition and first use. We can work on improving that later, but for now let's get the obvious case out of the way.After a few years of D use, I actually find the above will create problems. We often use traits like these to check whether something is compilable, even if the object is left uninitialized. For example if you want to check whether method "foo" of object "c" is callable with an int type: static assert(__traits(compiles, c.foo(1))); Making this fail now because of flow analysis could hurt code that does unittesting. I think a runtime exception is sufficient right now, and the OP feature could be part of some specialized flow-analysis tool. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 17 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4595 ---After a few years of D use, I actually find the above will create problems. We often use traits like these to check whether something is compilable, even if the object is left uninitialized.Today, code flow analysis for class ctor call (super(...) and this(...)) behaves as follows. class Foo { this(int) {} } class Bar : Foo { this() { static assert(is(typeof(super(0)))); static if (is(typeof(super(0)))) {} // inside typeof(), code flow analysis never works. super(1); // OK static assert(is(typeof(super(0)))); static if (is(typeof(super(0)))) {} // also OK super(2); // Error: multiple constructor call } this(int) { static assert( __traits(compiles, super(1))); // inside __traits(compiles), code flow analysis is enabled. super(1); // Error: multiple constructor call static assert(!__traits(compiles, super(2))); // The _second_ super call makes error. super(3); // Error: multiple constructor call } } This is expected behavior, from my compiler-internal knowledge. - `is(typeof(exp))` tests that the exp has valid type or not. For type calculation, the code flow analysis and its validation result is just unnecessary. - `__traits(compiles, exp)` tests the exact validness of `exp` at there. In other words, `__traits(compiles)` converts the error occurrence on the `exp` semantic analysis to the compile-time boolean value. In there, code flow analysis is enabled, and the errors will be counted normally. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 19 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4595 03:52:35 PDT ---- `is(typeof(exp))` tests that the exp has valid type or not. For type calculation, the code flow analysis and its validation result is just unnecessary. - `__traits(compiles, exp)` tests the exact validness of `exp` at there. In other words, `__traits(compiles)` converts the error occurrence on the `exp` semantic analysis to the compile-time boolean value. In there, code flow analysis is enabled, and the errors will be counted normally.Well that explains why sometimes is(typeof()) works where __traits(compiles) doesn't. But as far as I know none of this is properly documented, and it's probably why people file bugs when a difference in behavior is found. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 19 2013