https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71892
Bug ID: 71892 Summary: Recent optimization changes introduce bugs Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kern at sibbald dot com Target Milestone: --- The optimizations that you made to g++ 6.0 are not reasonable since they create programming bugs. This applies to two optimizations you have made. One disallowing this to be tested against NULL and the second elimination of what you determine to be unnecessary memory clearing with memset. In both case, the assumptions you make are not valid and thus these optimizations should not be made at low levels such as -O2 and below. First the case of testing this == NULL. You state: "When optimizing, GCC now assumes the this pointer can never be null, which is guaranteed by the language rules." This seems to be incorrect to me. "this" is nothing but a pointer to the class structure and at least in the case of non-virtual methods this can be zero, and it is often useful for it to be zero, and it is even more useful for a class implementer to be able to know if his method is being called with an uninitialized class. For example, if one has an optional list implemented as a class(as is the case in Bacula), rather than testing everywhere in the code whether or not the list pointer is NULL, it is more efficient to do so in the class. In our case, we return a zero in the size() method and thus there is no need in perhaps hundreds of places to test for a NULL pointer because it is done in the class. Another more important use of testing for this == NULL is for a class author to be able to know if the class has been initialized. If so, the method can continue, and if not the class writer can take appropriate action and avoid a seg fault. With your optimization, you explicitly remove this feature from the C++ language. The second case is you do not generate code in a overridden new operator when memset() is used to zero the memory. You are assuming that memory has already been zeroed, but we are overridding new specifically to use our own memory allocator that guarantees that the memory is non-zero. While your optimization may be appropriate at higher levels of optimization, it is not appropriate at -O2 which is used by many programs. I maintain that it is irresponsible to implement the above two unsafe optimizations at levels -O2 and below. I am fully aware that we could test for the compiler level and add new command line options, but that is a lot of unnecessary work, and in the mean time, g++ is not generating the code that corresponds to what we wrote (i.e. it is generating incorrect code and introducing seg faults in many programs). Please implement these "optimizations" if you must at higher optimization levels and leave levels -O2 and -O1 with only optimizations that are safe and do not modify the behavior of the program as written.