Bug 98160 - [11 Regression] ICE in default_tree_printer at gcc/tree-diagnostic.c:270 since r11-5732-gdce6c58db87ebf7f
Summary: [11 Regression] ICE in default_tree_printer at gcc/tree-diagnostic.c:270 sinc...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 11.0
: P1 normal
Target Milestone: 11.0
Assignee: Martin Liška
URL:
Keywords: diagnostic, ice-on-valid-code, patch
Depends on:
Blocks: spec
  Show dependency treegraph
 
Reported: 2020-12-06 09:10 UTC by Martin Liška
Modified: 2023-06-15 07:21 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 10.2.0
Known to fail: 11.0
Last reconfirmed: 2020-12-06 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Liška 2020-12-06 09:10:40 UTC
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
Comment 1 Martin Sebor 2020-12-07 00:32:36 UTC
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 ();
      |               ~~~~~~~~~~~~~~^~
Comment 3 GCC Commits 2020-12-14 20:31:07 UTC
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.
Comment 4 Martin Sebor 2020-12-14 20:35:12 UTC
Fixed in r11-6028.
Comment 5 Tamar Christina 2020-12-16 13:42:01 UTC
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
Comment 6 Martin Liška 2020-12-16 14:49:02 UTC
I can confirm that and I'm going to reduce that.
Comment 7 Martin Liška 2020-12-16 15:01:03 UTC
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
Comment 8 Martin Liška 2020-12-16 15:02:46 UTC
(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.
Comment 9 Martin Liška 2020-12-23 17:10:17 UTC
I've just sent a patch for it:
https://gcc.gnu.org/pipermail/gcc-patches/2020-December/562476.html
Comment 10 GCC Commits 2020-12-23 23:38:34 UTC
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.
Comment 11 Martin Sebor 2020-12-23 23:50:02 UTC
It should be fixed now for real.
Comment 12 GCC Commits 2023-06-14 09:43:07 UTC
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.
Comment 13 GCC Commits 2023-06-15 07:21:03 UTC
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++.