diff options
author | Jason Merrill <jason@redhat.com> | 2016-07-15 14:49:38 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-07-15 14:49:38 -0400 |
commit | de54de93fa4bf4740638e58f9aaab1e50026bacb (patch) | |
tree | 861ecdf4e032f243cb226623473bb28315a295b5 /gcc | |
parent | 4d031550cc895e3004f9cd23874877facc5d429a (diff) | |
download | gcc-de54de93fa4bf4740638e58f9aaab1e50026bacb.zip gcc-de54de93fa4bf4740638e58f9aaab1e50026bacb.tar.gz gcc-de54de93fa4bf4740638e58f9aaab1e50026bacb.tar.bz2 |
PR c++/71092 - ICE with array and constexpr.
* constexpr.c (cxx_eval_call_expression): Fail quietly when cgraph
threw away DECL_SAVED_TREE.
From-SVN: r238395
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-array17.C | 61 |
3 files changed, 77 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index eb96ea3..0c38195 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-07-15 Jason Merrill <jason@redhat.com> + PR c++/71092 + * constexpr.c (cxx_eval_call_expression): Fail quietly when cgraph + threw away DECL_SAVED_TREE. + PR c++/71117 Core 2189 * call.c (add_template_conv_candidate): Disable if there are diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index b9834a7..cb8ece0 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1504,9 +1504,19 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, } else { - if (!result || result == error_mark_node) + if (result && result != error_mark_node) + /* OK */; + else if (!DECL_SAVED_TREE (fun)) + { + /* When at_eof >= 2, cgraph has started throwing away + DECL_SAVED_TREE, so fail quietly. FIXME we get here because of + late code generation for VEC_INIT_EXPR, which needs to be + completely reconsidered. */ + gcc_assert (at_eof >= 2 && ctx->quiet); + *non_constant_p = true; + } + else { - gcc_assert (DECL_SAVED_TREE (fun)); tree body, parms, res; /* Reuse or create a new unshared copy of this function's body. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array17.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array17.C new file mode 100644 index 0000000..c6afa50 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array17.C @@ -0,0 +1,61 @@ +// PR c++/71092 +// { dg-do compile { target c++11 } } + +template <typename _Default> struct A { using type = _Default; }; +template <typename _Default, template <typename> class> +using __detected_or = A<_Default>; +template <typename _Default, template <typename> class _Op> +using __detected_or_t = typename __detected_or<_Default, _Op>::type; +template <typename _Tp> struct B { typedef _Tp value_type; }; +struct C { + template <typename _Tp> using __pointer = typename _Tp::pointer; +}; +template <typename _Alloc> struct J : C { + using pointer = __detected_or_t<typename _Alloc::value_type *, __pointer>; +}; +template <typename _T1> void _Construct(_T1 *) { new _T1; } +struct D { + template <typename _ForwardIterator, typename _Size> + static _ForwardIterator __uninit_default_n(_ForwardIterator p1, _Size) { + _Construct(p1); + } +}; +template <typename _ForwardIterator, typename _Size> +void __uninitialized_default_n(_ForwardIterator p1, _Size) { + D::__uninit_default_n(p1, 0); +} +template <typename _ForwardIterator, typename _Size, typename _Tp> +void __uninitialized_default_n_a(_ForwardIterator p1, _Size, _Tp) { + __uninitialized_default_n(p1, 0); +} +template <typename> struct __shared_ptr { + constexpr __shared_ptr() : _M_ptr(), _M_refcount() {} + int _M_ptr; + int _M_refcount; +}; +template <typename _Alloc> struct F { + typedef _Alloc _Tp_alloc_type; + struct G { + typename J<_Tp_alloc_type>::pointer _M_start; + G(_Tp_alloc_type); + }; + F(int, _Alloc p2) : _M_impl(p2) {} + G _M_impl; +}; +template <typename _Tp, typename _Alloc = B<_Tp>> struct K : F<_Alloc> { + typedef _Alloc allocator_type; + K(int, allocator_type p2 = allocator_type()) : F<_Alloc>(0, p2) { + __uninitialized_default_n_a(this->_M_impl._M_start, 0, 0); + } +}; +struct H { + H(); + struct I { + __shared_ptr<int> trigger[1]; + }; + __shared_ptr<int> resetTrigger_; + K<I> states_; + __shared_ptr<int> triggerManager_; +}; +__shared_ptr<int> a; +H::H() : states_(0), triggerManager_(a) {} |