mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-17 05:10:28 +08:00
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.
This commit is contained in:
parent
aeb430aadc
commit
48c8231094
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
87
gcc/testsuite/g++.dg/torture/pr94582.C
Normal file
87
gcc/testsuite/g++.dg/torture/pr94582.C
Normal file
@ -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;
|
||||
}
|
||||
|
@ -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 ();
|
||||
|
Loading…
x
Reference in New Issue
Block a user