[Bug c++/94671] New: Wrong behavior with operator new overloading when using O2 for optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94671 Bug ID: 94671 Summary: Wrong behavior with operator new overloading when using O2 for optimization Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: b...@odd-e.com Target Milestone: --- This bug is a similar bug as an earlier reported in clang: https://bugs.llvm.org/show_bug.cgi?id=15541 When having the overloaded new operator defined in other cpp or in a lib, g++ with O2 optimizes a new operation without assignment (or assignment to local or static), and it will not call the overloaded new at all. The following code will reproduce the problem. --- test.cpp: --- #include #define CHECK(expect, actual) std::cout << "EXPECT:" << expect << "\tACTUAL:"< #include #include extern bool newCalled; bool newCalled = false; void* operator new (size_t size) throw (std::bad_alloc) { newCalled = true; return malloc(size); } --- I know this is an optimization (it doesn't happen with -O0)... but it does break the C++ standard.
[Bug c++/94671] Wrong behavior with operator new overloading when using O2 for optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94671 --- Comment #2 from Bas Vodde --- Oh wow, does this mean that it is the choice of the compiler to actually call an overloaded operator new ? That is interesting. Thanks. I'd still consider it highly surprising behavior, at least it was for me...
[Bug c++/94671] Wrong behavior with operator new overloading when using O2 for optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94671 --- Comment #4 from Bas Vodde --- The newCalled to true in the example was the simplest way to show the behavior. This bug came up in a open source project called CppuTest. This has the functionality to detect memory leaks and does so by overloading the operator new. For each operator new, it keeps accounting information. When an operator new gets optimized by the compiler, the framework can't keep track of the accounting information and the delete call will report that non-allocated memory was deleted. I assume this is an useful and perfectly legit way of overloading operator new/delete. This behavior was caught when running the automated test of the framework, which failed in the debian build when updating to gcc10: https://people.debian.org/~doko/logs/gcc10-20200225/cpputest_3.8-7_unstable_gcc10.log
[Bug c++/94671] Wrong behavior with operator new overloading when using O2 for optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94671 --- Comment #5 from Bas Vodde --- In the case we found this, it mostly uses the overload for accounting and thus it doesn't cause a serious problem ('just' a test failure). If you use the overloaded new/delete for providing your own memory management, then this would potentially cause a serious problems.
[Bug c++/94671] Wrong behavior with operator new overloading when using O2 for optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94671 --- Comment #9 from Bas Vodde --- Hi Jonathan, You are right, I was drawing much too many conclusions there. I should have waited with that comment until I slept :) Sorry for that. And it has been a while since I read the proposal, it has been years since we hit this problem in clang. Let me experiment a bit and see why gcc now behaves differently than clang, and whether that can cause a non-optimized placement delete to called on a replace operator new. Otherwise, I still find it odd behavior but less harmful as I wrongly stated in the previous comment.
[Bug c++/57632] New: Operator new overloads with stdc++11 enabled looses exception specifier (MacOsX)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57632 Bug ID: 57632 Summary: Operator new overloads with stdc++11 enabled looses exception specifier (MacOsX) Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: b...@odd-e.com G++ on MacOsX acts different when enabling the new c++11 related to operator new overloads. If I compile the following code: #include "stdlib.h" #include void* operator new(size_t mem) throw(std::bad_alloc); void* operator new(size_t mem) throw(std::bad_alloc); Then when compiling g++ new.cpp, it compiles fine. But when I compile g++ -std=c++11 new.cpp, then it results in this error: new.cpp:6:52: error: declaration of ‘void* operator new(size_t) throw (std::bad_alloc)’ has a different exception specifier void* operator new(size_t mem) throw(std::bad_alloc); ^ new.cpp:5:7: error: from previous declaration ‘void* operator new(std::size_t)’ void* operator new(size_t mem) throw(std::bad_alloc); ^ I've not been able to replicate this under linux and digging into it a bit, it seems to relate to the c++config.h definitions of _GLIBCXX_THROW.
[Bug c++/57632] Operator new overloads with stdc++11 enabled looses exception specifier (MacOsX)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57632 --- Comment #3 from Bas Vodde --- Thanks for the comments. I understand the problems in implementing a compiler, when this is also unclear in the language itself. Whatever is decided related to this, it would probably be a good idea to give a better error message. Right now, the error message is telling the user that the operator new *with* an exception specifier doesn't have one and that they are different, even though the two lines are exactly the same. It is a bit confusing. It would be good though to solve this in a way that both works with C++11 and C++03 as it came up when compiling a piece of code that is used by multiple compilers and by both language versions.