diff options
author | Jan Hubicka <jh@suse.cz> | 2020-04-20 15:25:50 +0200 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2020-04-20 15:25:50 +0200 |
commit | 48c82310947355665d628d4d1c8e736df9987574 (patch) | |
tree | 08aeb9c41a0be02b7c2ebda0771730d22e843f81 /gcc | |
parent | aeb430aadc3c91af50095be924365981d85f8b8a (diff) | |
download | gcc-48c82310947355665d628d4d1c8e736df9987574.zip gcc-48c82310947355665d628d4d1c8e736df9987574.tar.gz gcc-48c82310947355665d628d4d1c8e736df9987574.tar.bz2 |
Fix ICE on invalid calls_comdat_local flag [pr94582]
PR ipa/94582
* tree-inline.c (optimize_inline_calls): Recompute calls_comdat_local
flag.
* g++.dg/torture/pr94582.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ipa-comdats.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr94582.C | 87 | ||||
-rw-r--r-- | gcc/tree-inline.c | 1 |
5 files changed, 109 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 405037e..cc6c638 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-04-20 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/94582 + * tree-inline.c (optimize_inline_calls): Recompute calls_comdat_local + flag. + 2020-04-20 Martin Liska <mliska@suse.cz> * symtab.c (symtab_node::dump_references): Add space after diff --git a/gcc/ipa-comdats.c b/gcc/ipa-comdats.c index ced2572..feea458 100644 --- a/gcc/ipa-comdats.c +++ b/gcc/ipa-comdats.c @@ -376,6 +376,15 @@ ipa_comdats (void) true); } } + +#if 0 + /* Recompute calls comdat local flag. This need to be done after all changes + are made. */ + cgraph_node *function; + FOR_EACH_DEFINED_FUNCTION (function) + if (function->get_comdat_group ()) + function->calls_comdat_local = function->check_calls_comdat_local_p (); +#endif return 0; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 473295d..9ba21a0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-04-20 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/94582 + PR ipa/94582 + * g++.dg/torture/pr94582.C: New test. + 2020-04-20 Harald Anlauf <anlauf@gmx.de> PR fortran/93364 diff --git a/gcc/testsuite/g++.dg/torture/pr94582.C b/gcc/testsuite/g++.dg/torture/pr94582.C new file mode 100644 index 0000000..b06285a --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr94582.C @@ -0,0 +1,87 @@ +// { dg-do compile } +// { dg-additional-options "-fnon-call-exceptions -fno-inline-functions-called-once -fno-tree-sra --param early-inlining-insns=1" } +template <typename, typename> struct __replace_first_arg; +template <template <typename> class _Template, typename _Up, typename _Tp, + typename... _Types> +struct __replace_first_arg<_Template<_Tp, _Types...>, _Up> { + using type = _Template<_Up>; +}; +template <class> class min_pointer; +struct pointer_traits { + template <typename _Up> + using rebind = typename __replace_first_arg<min_pointer<int>, _Up>::type; +}; +template <typename, typename _Tp> +using __ptr_rebind = pointer_traits::rebind<_Tp>; +template <typename _Alloc> struct allocator_traits { + template <typename _Tp> + static auto construct(_Alloc, _Tp) noexcept -> decltype(0); +}; +template <typename _ForwardIterator, typename _Allocator> +void _Destroy(_ForwardIterator __last, _Allocator) { + _ForwardIterator __first; + for (; __first != __last;) + ; +} +template <typename _ForwardIterator, typename _Allocator> +void __uninitialized_default_a(_ForwardIterator __last, _Allocator __alloc) { + _ForwardIterator __first; + try { + for (; __first != __last;) + allocator_traits<_Allocator>::construct(__alloc, 0); + } catch (...) { + _Destroy(__first, __alloc); + } +} +template <typename _Ptr> struct _Deque_iterator { + typedef __ptr_rebind<_Ptr, __ptr_rebind<_Ptr, int>> _Map_pointer; +}; +template <typename _Alloc> class _Deque_base { +protected: + typedef _Alloc _Tp_alloc_type; + typedef _Deque_iterator<typename _Tp_alloc_type ::pointer> iterator; + _Deque_base(_Alloc, long); + typedef typename iterator::_Map_pointer _Map_pointer; + _Tp_alloc_type _M_get_Tp_allocator(); +}; +template <typename _Alloc> class deque : _Deque_base<_Alloc> { + typedef _Deque_base<_Alloc> _Base; + typedef typename _Base::_Map_pointer _Map_pointer; + typedef typename _Base::iterator iterator; + using _Base::_M_get_Tp_allocator; + +public: + deque(int, _Alloc __a) : _Base(__a, 0) { + _Map_pointer __cur; + try { + __uninitialized_default_a(__cur, _M_get_Tp_allocator()); + } catch (...) { + } + _M_destroy_data(begin(), end(), 0); + } + iterator begin(); + iterator end(); + template <typename _Alloc1> + void _M_destroy_data(iterator, iterator, _Alloc1) { + for (_Map_pointer __node;;) + _Destroy(__node, _M_get_Tp_allocator()); + } +}; +template <class T> class min_pointer { + T ptr_; + friend bool operator==(min_pointer x, min_pointer y) { + return x.ptr_ == y.ptr_; + } + friend bool operator!=(min_pointer x, min_pointer y) { return x == y; } +}; +template <class> class min_allocator { +public: + typedef int pointer; +}; +int foo() { + int n; + min_allocator<int> alloc; + deque<min_allocator<int>>(n, alloc); + return 1; +} + diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 26c23f5..69ca8e9 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -5469,6 +5469,7 @@ optimize_inline_calls (tree fn) number_blocks (fn); delete_unreachable_blocks_update_callgraph (id.dst_node, false); + id.dst_node->calls_comdat_local = id.dst_node->check_calls_comdat_local_p (); if (flag_checking) id.dst_node->verify (); |