aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2020-04-20 15:25:50 +0200
committerJan Hubicka <jh@suse.cz>2020-04-20 15:25:50 +0200
commit48c82310947355665d628d4d1c8e736df9987574 (patch)
tree08aeb9c41a0be02b7c2ebda0771730d22e843f81 /gcc
parentaeb430aadc3c91af50095be924365981d85f8b8a (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/ipa-comdats.c9
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/torture/pr94582.C87
-rw-r--r--gcc/tree-inline.c1
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 ();