Since the revision 523.xalancbmk_r is broken with -O2 -flto. There's a reduced test-case: $ cat 1.ii namespace xercesc_2_7 { class MemoryManager; class XMemory { public: void *operator new(unsigned long, MemoryManager *); void operator delete(void *, MemoryManager *); }; class XMLPlatformUtils { public: static MemoryManager *fgMemoryManager; }; class XMLMutex : public XMemory { public: XMLMutex(); }; void gValidatorMutex() { new (XMLPlatformUtils::fgMemoryManager) XMLMutex; } } // namespace xercesc_2_7 $ cat 2.ii namespace xercesc_2_7 { class MemoryManager; class XMemory { void *operator new(unsigned long, MemoryManager *); }; class MemoryManager { public: virtual void *allocate(); }; void *XMemory::operator new(unsigned long, MemoryManager *manager) { long headerSize(sizeof(MemoryManager)); void *block = manager->allocate(); return block + headerSize; } } // namespace xercesc_2_7 $ g++ 1.ii 2.ii -flto -O2 -shared 2.ii: In static member function 'static void* xercesc_2_7::XMemory::operator new(long unsigned int, xercesc_2_7::MemoryManager*)': 2.ii:13:16: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith] 13 | return block + headerSize; | ~~~~~~^~~~~~~~~~~~ 1.ii: In function 'gValidatorMutex': 1.ii:16:66: warning: 'operator delete' called on pointer '_12' with nonzero offset 8 [-Wfree-nonheap-object] 16 | void gValidatorMutex() { new (XMLPlatformUtils::fgMemoryManager) XMLMutex; } | ^ ' during RTL pass: expand Segmentation fault 0xcc206f crash_signal /home/marxin/Programming/gcc/gcc/toplev.c:327 0xd1c6dd default_tree_printer(pretty_printer*, text_info*, char const*, int, bool, bool, bool, bool*, char const**) /home/marxin/Programming/gcc/gcc/tree-diagnostic.c:270 0xd1c6dd default_tree_printer(pretty_printer*, text_info*, char const*, int, bool, bool, bool, bool*, char const**) /home/marxin/Programming/gcc/gcc/tree-diagnostic.c:247 0x180574c pp_format(pretty_printer*, text_info*) /home/marxin/Programming/gcc/gcc/pretty-print.c:1475 0x17e95a6 diagnostic_report_diagnostic(diagnostic_context*, diagnostic_info*) /home/marxin/Programming/gcc/gcc/diagnostic.c:1216 0x17ec107 diagnostic_impl /home/marxin/Programming/gcc/gcc/diagnostic.c:1366 0x17ec107 inform(unsigned int, char const*, ...) /home/marxin/Programming/gcc/gcc/diagnostic.c:1445 0x811dc3 warn_dealloc_offset /home/marxin/Programming/gcc/gcc/builtins.c:13206 0x82003d maybe_emit_free_warning(tree_node*) /home/marxin/Programming/gcc/gcc/builtins.c:13344 0x838ece initialize_argument_information /home/marxin/Programming/gcc/gcc/calls.c:2629 0x838ece expand_call(tree_node*, rtx_def*, int) /home/marxin/Programming/gcc/gcc/calls.c:4009 0x96bb54 expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool) /home/marxin/Programming/gcc/gcc/expr.c:11252 0x84cb3d expand_expr /home/marxin/Programming/gcc/gcc/expr.h:282 0x84cb3d expand_call_stmt /home/marxin/Programming/gcc/gcc/cfgexpand.c:2831 0x84cb3d expand_gimple_stmt_1 /home/marxin/Programming/gcc/gcc/cfgexpand.c:3835 0x84cb3d expand_gimple_stmt /home/marxin/Programming/gcc/gcc/cfgexpand.c:3999 0x851ffa expand_gimple_basic_block /home/marxin/Programming/gcc/gcc/cfgexpand.c:6043 0x853b66 execute /home/marxin/Programming/gcc/gcc/cfgexpand.c:6727 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. lto-wrapper: fatal error: g++ returned 1 exit status compilation terminated. /usr/bin/ld: error: lto-wrapper failed collect2: error: ld returned 1 exit status
The test case actually exposes two bugs: besides the ICE, the more interesting problem is the false positive. The warning considers pointers with positive offsets invalid arguments to all deallocation functions. That's fair for arguments to pairs of calls to allocation and deallocation functions but not necessarily when just the deallocator is known and not also the allocator the pointer was obtained from. A simple test case for that, reduced from the two translation units in comment #0, is below: $ cat t.C && gcc -O2 -S -Wall t.C struct MemoryManager { void* allocate (); }; struct XMemory { void* operator new (__SIZE_TYPE__, MemoryManager *mgr) { void *p = mgr->allocate (); return (char*)p + sizeof(MemoryManager); } void operator delete (void*, MemoryManager*); }; struct XMLMutex: XMemory { XMLMutex(); }; void gValidatorMutex (MemoryManager *mgr) { new (mgr) XMLMutex; } t.C: In function ‘void gValidatorMutex(MemoryManager*)’: t.C:18:55: warning: ‘static void XMemory::operator delete(void*, MemoryManager*)’ called on pointer ‘<unknown>’ with nonzero offset 1 [-Wfree-nonheap-object] 18 | void gValidatorMutex (MemoryManager *mgr) { new (mgr) XMLMutex; } | ^~~~~~~~ t.C:7:29: note: returned from a call to ‘void* MemoryManager::allocate()’ 7 | void *p = mgr->allocate (); | ~~~~~~~~~~~~~~^~
Patch: https://gcc.gnu.org/pipermail/gcc-patches/2020-December/561378.html
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>: https://gcc.gnu.org/g:fe7f75cf16783589eedbab597e6d0b8d35d7e470 commit r11-6028-gfe7f75cf16783589eedbab597e6d0b8d35d7e470 Author: Martin Sebor <msebor@redhat.com> Date: Mon Dec 14 13:30:00 2020 -0700 Correct/improve maybe_emit_free_warning (PR middle-end/98166, PR c++/57111, PR middle-end/98160). Resolves: PR middle-end/98166 - bogus -Wmismatched-dealloc on user-defined allocator and inlining PR c++/57111 - 57111 - Generalize -Wfree-nonheap-object to delete PR middle-end/98160 - ICE in default_tree_printer at gcc/tree-diagnostic.c:270 gcc/ChangeLog: PR middle-end/98166 PR c++/57111 PR middle-end/98160 * builtins.c (check_access): Call tree_inlined_location fndecl_alloc_p): Handle BUILT_IN_ALIGNED_ALLOC and BUILT_IN_GOMP_ALLOC. call_dealloc_p): Remove unused function. (new_delete_mismatch_p): Call valid_new_delete_pair_p and rework. (matching_alloc_calls_p): Handle built-in deallocation functions. (warn_dealloc_offset): Corrct the handling of user-defined operators delete. (maybe_emit_free_warning): Avoid assuming expression is a decl. Simplify. * doc/extend.texi (attribute malloc): Update. * tree-ssa-dce.c (valid_new_delete_pair_p): Factor code out into valid_new_delete_pair_p in tree.c. * tree.c (tree_inlined_location): Define new function. (valid_new_delete_pair_p): Define. * tree.h (tree_inlined_location): Declare. (valid_new_delete_pair_p): Declare. gcc/c-family/ChangeLog: PR middle-end/98166 PR c++/57111 PR middle-end/98160 * c-attribs.c (maybe_add_noinline): New function. (handle_malloc_attribute): Call it. Use ATTR_FLAG_INTERNAL. Implicitly add attribute noinline to functions not declared inline and warn on those. libstdc++-v3/ChangeLog: * testsuite/ext/vstring/requirements/exception/basic.cc: Suppress a false positive warning. * testsuite/ext/vstring/requirements/exception/propagation_consistent.cc: Same. gcc/testsuite/ChangeLog: PR middle-end/98166 PR c++/57111 PR middle-end/98160 * g++.dg/warn/Wmismatched-dealloc-2.C: Adjust test of expected warning. * g++.dg/warn/Wmismatched-new-delete.C: Same. * gcc.dg/Wmismatched-dealloc.c: Same. * c-c++-common/Wfree-nonheap-object-2.c: New test. * c-c++-common/Wfree-nonheap-object-3.c: New test. * c-c++-common/Wfree-nonheap-object.c: New test. * c-c++-common/Wmismatched-dealloc.c: New test. * g++.dg/warn/Wfree-nonheap-object-3.C: New test. * g++.dg/warn/Wfree-nonheap-object-4.C: New test. * g++.dg/warn/Wmismatched-dealloc-2.C: New test. * g++.dg/warn/Wmismatched-new-delete-2.C: New test. * g++.dg/warn/Wmismatched-new-delete.C: New test. * gcc.dg/Wmismatched-dealloc-2.c: New test. * gcc.dg/Wmismatched-dealloc-3.c: New test. * gcc.dg/Wmismatched-dealloc.c: New test.
Fixed in r11-6028.
Unfortunately I can still reproduce this with 483.xalancbmk on spec2006. It seems to indeed happen only with -flto so I have no idea how to reduce it.. As of g:8833eab4461b4b7050f06a231c3311cc1fa87523 I still get during RTL pass: expand BinFileInputStream.cpp: In member function 'makeStream': BinFileInputStream.cpp:145:1: internal compiler error: Segmentation fault 145 | } | ^ 0xbf7a33 crash_signal ../../gcc-fsf/gcc/toplev.c:327 0x6e34f4 tree_check(tree_node*, char const*, int, char const*, tree_code) ../../gcc-fsf/gcc/tree.h:3337 0x6e34f4 warn_dealloc_offset ../../gcc-fsf/gcc/builtins.c:13413 0x701927 maybe_emit_free_warning(tree_node*) ../../gcc-fsf/gcc/builtins.c:13586 0x71264b initialize_argument_information ../../gcc-fsf/gcc/calls.c:2629 0x71264b expand_call(tree_node*, rtx_def*, int) ../../gcc-fsf/gcc/calls.c:4009 0x852887 expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool) ../../gcc-fsf/gcc/expr.c:11276 0x72881b expand_expr ../../gcc-fsf/gcc/expr.h:282 0x72881b expand_call_stmt ../../gcc-fsf/gcc/cfgexpand.c:2831 0x72881b expand_gimple_stmt_1 ../../gcc-fsf/gcc/cfgexpand.c:3835 0x72881b expand_gimple_stmt ../../gcc-fsf/gcc/cfgexpand.c:3999 0x72ddd3 expand_gimple_basic_block ../../gcc-fsf/gcc/cfgexpand.c:6036 0x73019f execute ../../gcc-fsf/gcc/cfgexpand.c:6720
I can confirm that and I'm going to reduce that.
New reduced test-case: $ cat 1.ii namespace xercesc_2_5 { class MemoryManager; class XMemory { void *operator new(unsigned long, MemoryManager *); }; class MemoryManager { public: virtual void *allocate(); }; void *XMemory::operator new(unsigned long, MemoryManager *manager) { long headerSize(sizeof(MemoryManager)); void *block = manager->allocate(); return block + headerSize; } } // namespace xercesc_2_5 $ cat 2.ii namespace xercesc_2_5 { class MemoryManager; class XMemory { public: void *operator new(unsigned long, MemoryManager *); void operator delete(void *, MemoryManager *); }; class XMLPlatformUtils { public: static MemoryManager *fgMemoryManager; }; class ValueStackOf : public XMemory { public: ValueStackOf(int, bool); }; class XPathMatcherStack { XPathMatcherStack(); ValueStackOf *fContextStack; }; XPathMatcherStack::XPathMatcherStack() : fContextStack(new (XMLPlatformUtils::fgMemoryManager) ValueStackOf(8, XMLPlatformUtils::fgMemoryManager)) {} } // namespace xercesc_2_5 $ g++ 1.ii 2.ii -O2 -flto=16 -shared 1.ii: In static member function 'static void* xercesc_2_5::XMemory::operator new(long unsigned int, xercesc_2_5::MemoryManager*)': 1.ii:13:16: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith] 13 | return block + headerSize; | ~~~~~~^~~~~~~~~~~~ during RTL pass: expand 2.ii: In member function '__ct_base ': 2.ii:22:74: internal compiler error: Segmentation fault 22 | ValueStackOf(8, XMLPlatformUtils::fgMemoryManager)) {} | ^ 0xcce44f crash_signal /home/marxin/Programming/gcc/gcc/toplev.c:327 0x81da08 tree_check(tree_node*, char const*, int, char const*, tree_code) /home/marxin/Programming/gcc/gcc/tree.h:3337 0x81da08 warn_dealloc_offset /home/marxin/Programming/gcc/gcc/builtins.c:13413 0x836127 maybe_emit_free_warning(tree_node*) /home/marxin/Programming/gcc/gcc/builtins.c:13586 0x84545e initialize_argument_information /home/marxin/Programming/gcc/gcc/calls.c:2629 0x84545e expand_call(tree_node*, rtx_def*, int) /home/marxin/Programming/gcc/gcc/calls.c:4009 0x978104 expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool) /home/marxin/Programming/gcc/gcc/expr.c:11276 0x8590cd expand_expr /home/marxin/Programming/gcc/gcc/expr.h:282 0x8590cd expand_call_stmt /home/marxin/Programming/gcc/gcc/cfgexpand.c:2831 0x8590cd expand_gimple_stmt_1 /home/marxin/Programming/gcc/gcc/cfgexpand.c:3835 0x8590cd expand_gimple_stmt /home/marxin/Programming/gcc/gcc/cfgexpand.c:3999 0x85e5fa expand_gimple_basic_block /home/marxin/Programming/gcc/gcc/cfgexpand.c:6036 0x8600b6 execute /home/marxin/Programming/gcc/gcc/cfgexpand.c:6720 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. make: *** [/tmp/cc3Mo9q4.mk:2: /tmp/ccFzg763.ltrans0.ltrans.o] Error 1 lto-wrapper: fatal error: make returned 2 exit status compilation terminated. /usr/bin/ld: error: lto-wrapper failed collect2: error: ld returned 1 exit status
(In reply to Martin Sebor from comment #4) > Fixed in r11-6028. Even the original test-case still ICEs after this revision. I'm testing r11-6147 right now.
I've just sent a patch for it: https://gcc.gnu.org/pipermail/gcc-patches/2020-December/562476.html
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>: https://gcc.gnu.org/g:0df311657dc8c2a7f6ce3464c9d9ae5d5033840c commit r11-6329-g0df311657dc8c2a7f6ce3464c9d9ae5d5033840c Author: Martin Sebor <msebor@redhat.com> Date: Wed Dec 23 16:34:12 2020 -0700 PR middle-end/98160 - ICE in warn_dealloc_offset on member placement new and delete gcc/ChangeLog: PR middle-end/98160 * builtins.c (warn_dealloc_offset): Avoid assuming calls are made through declared functions and not pointers. gcc/testsuite/ChangeLog: PR middle-end/98160 * g++.dg/warn/pr98160.C: New test.
It should be fixed now for real.
The master branch has been updated by Thomas Schwinge <tschwinge@gcc.gnu.org>: https://gcc.gnu.org/g:9c03391ba447ff86038d6a34c90ae737c3915b5f commit r14-1805-g9c03391ba447ff86038d6a34c90ae737c3915b5f Author: Thomas Schwinge <thomas@codesourcery.com> Date: Wed Jun 7 16:24:26 2023 +0200 Tighten 'dg-warning' alternatives in 'c-c++-common/Wfree-nonheap-object{,-2,-3}.c' ..., added in commit fe7f75cf16783589eedbab597e6d0b8d35d7e470 "Correct/improve maybe_emit_free_warning (PR middle-end/98166, PR c++/57111, PR middle-end/98160)". These use alternatives like, for example, "AB|CDE|FG", but what really must've been meant is "A(B|C)D(E|F)G". The former variant also does "work": it matches any of "AB", or "CDE", or "FG", which are components of the latter variant. (That means, the former variant matches too loosely.) gcc/testsuite/ * c-c++-common/Wfree-nonheap-object-2.c: Tighten 'dg-warning' alternatives. * c-c++-common/Wfree-nonheap-object-3.c: Likewise. * c-c++-common/Wfree-nonheap-object.c: Likewise.
The master branch has been updated by Thomas Schwinge <tschwinge@gcc.gnu.org>: https://gcc.gnu.org/g:df071fbd467f0cb3711119ef41d74792fc5e6c8c commit r14-1838-gdf071fbd467f0cb3711119ef41d74792fc5e6c8c Author: Thomas Schwinge <thomas@codesourcery.com> Date: Wed Jun 7 17:12:01 2023 +0200 Fix 'dg-warning' in 'c-c++-common/Wfree-nonheap-object-3.c' for C++ [...]/c-c++-common/Wfree-nonheap-object-3.c:57:24: warning: 'malloc (dealloc_float)' attribute ignored with deallocation functions declared 'inline' [-Wattributes] [...]/c-c++-common/Wfree-nonheap-object-3.c:51:1: note: deallocation function declared here [...]/c-c++-common/Wfree-nonheap-object-3.c: In function 'void test_nowarn_int(int)': [...]/c-c++-common/Wfree-nonheap-object-3.c:25:20: warning: 'void __builtin_free(void*)' called on pointer 'p' with nonzero offset 4 [-Wfree-nonheap-object] [...]/c-c++-common/Wfree-nonheap-object-3.c:24:24: note: returned from 'int* alloc_int(int)' [...]/c-c++-common/Wfree-nonheap-object-3.c: In function 'void test_nowarn_long(int)': [...]/c-c++-common/Wfree-nonheap-object-3.c:45:18: warning: 'void dealloc_long(long int*)' called on pointer '<unknown>' with nonzero offset 8 [-Wfree-nonheap-object] [...]/c-c++-common/Wfree-nonheap-object-3.c:44:26: note: returned from 'long int* alloc_long(int)' In function 'void dealloc_float(float*)', inlined from 'void test_nowarn_float(int)' at [...]/c-c++-common/Wfree-nonheap-object-3.c:68:19: [...]/c-c++-common/Wfree-nonheap-object-3.c:53:18: warning: 'void __builtin_free(void*)' called on pointer '<unknown>' with nonzero offset 8 [-Wfree-nonheap-object] [...]/c-c++-common/Wfree-nonheap-object-3.c: In function 'void test_nowarn_float(int)': [...]/c-c++-common/Wfree-nonheap-object-3.c:67:28: note: returned from 'float* alloc_float(int)' PASS: c-c++-common/Wfree-nonheap-object-3.c -std=gnu++98 (test for warnings, line 25) FAIL: c-c++-common/Wfree-nonheap-object-3.c -std=gnu++98 (test for warnings, line 45) PASS: c-c++-common/Wfree-nonheap-object-3.c -std=gnu++98 (test for warnings, line 51) PASS: c-c++-common/Wfree-nonheap-object-3.c -std=gnu++98 (test for warnings, line 53) PASS: c-c++-common/Wfree-nonheap-object-3.c -std=gnu++98 (test for warnings, line 57) FAIL: c-c++-common/Wfree-nonheap-object-3.c -std=gnu++98 (test for excess errors) Excess errors: [...]/c-c++-common/Wfree-nonheap-object-3.c:45:18: warning: 'void dealloc_long(long int*)' called on pointer '<unknown>' with nonzero offset 8 [-Wfree-nonheap-object] ..., that is: decorated 'void dealloc_long(long int*)' instead of plain 'dealloc_long' -- similar to how all the other 'dg-warning's allow for the decorated function signature in addition to the plain one. This issue was latent since the test case was added in commit fe7f75cf16783589eedbab597e6d0b8d35d7e470 "Correct/improve maybe_emit_free_warning (PR middle-end/98166, PR c++/57111, PR middle-end/98160)", and was finally exposed by my recent commit 9c03391ba447ff86038d6a34c90ae737c3915b5f "Tighten 'dg-warning' alternatives in 'c-c++-common/Wfree-nonheap-object{,-2,-3}.c'". gcc/testsuite/ * c-c++-common/Wfree-nonheap-object-3.c: Fix 'dg-warning' for C++.