From 672d9f8eab3e81bd80098fc5b16eac116eec7658 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 27 Mar 2017 07:35:44 +0000 Subject: [PATCH] re PR tree-optimization/80171 (ICE (Segmentation fault) with optimization) 2017-03-27 Richard Biener PR middle-end/80171 * gimple-fold.c (fold_ctor_reference): Properly guard against NULL return value from canonicalize_constructor_val. * g++.dg/torture/pr80171.C: New testcase. From-SVN: r246490 --- gcc/ChangeLog | 6 + gcc/gimple-fold.c | 7 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/g++.dg/torture/pr80171.C | 183 +++++++++++++++++++++++++ 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr80171.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1e4df00c695..3ef30163ab9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-03-27 Richard Biener + + PR middle-end/80171 + * gimple-fold.c (fold_ctor_reference): Properly guard against + NULL return value from canonicalize_constructor_val. + 2017-03-25 Uros Bizjak PR target/80180 diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 9fd45d103a4..3094b54c109 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -6239,9 +6239,12 @@ fold_ctor_reference (tree type, tree ctor, unsigned HOST_WIDE_INT offset, && !compare_tree_int (TYPE_SIZE (TREE_TYPE (ctor)), size)) { ret = canonicalize_constructor_val (unshare_expr (ctor), from_decl); - ret = fold_unary (VIEW_CONVERT_EXPR, type, ret); if (ret) - STRIP_USELESS_TYPE_CONVERSION (ret); + { + ret = fold_unary (VIEW_CONVERT_EXPR, type, ret); + if (ret) + STRIP_USELESS_TYPE_CONVERSION (ret); + } return ret; } /* For constants and byte-aligned/sized reads try to go through diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd8d3d0abb6..65c8310a7f9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-27 Richard Biener + + PR middle-end/80171 + * g++.dg/torture/pr80171.C: New testcase. + 2017-03-26 John David Anglin * gcc.dg/torture/pr79732.c: Require alias support. diff --git a/gcc/testsuite/g++.dg/torture/pr80171.C b/gcc/testsuite/g++.dg/torture/pr80171.C new file mode 100644 index 00000000000..81f272583c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr80171.C @@ -0,0 +1,183 @@ +// { dg-do compile } + +template struct remove_reference; +template struct remove_reference<_Tp &> { typedef _Tp type; }; +template typename remove_reference<_Tp>::type move(_Tp &&p1) { + return static_cast::type &&>(p1); +} +void *operator new(__SIZE_TYPE__, void *p2) { return p2; } +struct Trans_NS__v1_GenericTlv { + virtual int getMinimumValueLength(); + virtual unsigned long getValueLength() const; +}; +struct IPv4NeighborAddressSubTlv; +struct Trans_NS__v1_GenericTlvBase : Trans_NS__v1_GenericTlv { + virtual bool operator==(const IPv4NeighborAddressSubTlv &) const; +}; +struct Trans_NS__v1_GenericUnsupportedTlv; +template struct backup_holder { + Trans_NS__v1_GenericUnsupportedTlv *backup_; + Trans_NS__v1_GenericUnsupportedTlv &get() { return *backup_; } +}; +template struct make_reference_content { + typedef IPv4NeighborAddressSubTlv type; +}; +template struct unwrap_recursive { + typedef IPv4NeighborAddressSubTlv type; +}; +template struct begin_impl; +template struct begin { + typedef typename Sequence::tag tag_; + typedef typename begin_impl::template apply::type type; +}; +struct long_ { + static const int value = 0; +}; +template struct O1_size_impl; +template +struct O1_size + : O1_size_impl::template apply {}; +template +struct apply_wrap2 : F::template apply {}; +template struct iter_fold_impl; +template +struct iter_fold_impl<0, First, ForwardOp> { + typedef typename apply_wrap2::type state; +}; +template struct iter_fold { + typedef + typename iter_fold_impl::value, + typename begin::type, ForwardOp>::state + type; +}; +template struct deref; +template struct pair { typedef T1 first; }; +struct make_initializer_node { + template struct apply { + struct initializer_node { + typedef typename deref::type recursive_enabled_T; + static int + initialize(void *p1, + typename unwrap_recursive::type) { + new (p1) typename make_reference_content::type; + } + }; + typedef pair type; + }; +}; +struct l_item { + typedef int tag; + typedef l_item type; + typedef long_ size; + typedef int item; +}; +template <> struct O1_size_impl { + template struct apply : List::size {}; +}; +template struct l_iter; +template struct deref> { + typedef typename Node::item type; +}; +template <> struct begin_impl { + template struct apply { + typedef l_iter type; + }; +}; +template +struct list : l_item {}; +template struct make_variant_list { typedef list type; }; +template T cast_storage(void *p1) { return *static_cast(p1); } +struct visitation_impl_step { + typedef Trans_NS__v1_GenericUnsupportedTlv type; +}; +template +void visitation_impl_invoke_impl(Visitor p1, VoidPtrCV p2, T *) { + backup_holder __trans_tmp_8 = + cast_storage>(p2); + p1.internal_visit(__trans_tmp_8, 0); +} +template +void visitation_impl_invoke(Visitor p1, VoidPtrCV p2, T p3, NoBackupFlag) { + visitation_impl_invoke_impl(p1, p2, p3); +} +template +void visitation_impl(Visitor p1, VoidPtrCV p2, NoBackupFlag, Which, step0 *) { + visitation_impl_invoke(p1, p2, static_cast(0), 0); +} +struct move_into { + move_into(void *); + template void internal_visit(backup_holder p1, int) { + T __trans_tmp_2 = p1.get(); + new (0) T(__trans_tmp_2); + } +}; +template struct variant { + struct initializer : iter_fold::type, + make_initializer_node>::type::first {}; + template void convert_construct(T p1, int) { + void *__trans_tmp_9 = this; + initializer::initialize(__trans_tmp_9, p1); + } + template variant(T p1) { convert_construct(p1, 0); } + variant(variant &&p1) { + move_into visitor(0); + p1.internal_apply_visitor(visitor); + } + template void internal_apply_visitor(Visitor p1) { + void *__trans_tmp_10 = this; + visitation_impl(p1, __trans_tmp_10, 0, 0, + static_cast(0)); + } +}; +template struct generic_element_tlvs; +template +struct generic_element_tlvs { + typedef variant variant_type; +}; +template struct Trans_NS__v1_GenericTlvContainer { + template void addTlv(const TlvClass &); +}; +template +template +void Trans_NS__v1_GenericTlvContainer::addTlv( + const TlvClass &p1) { + typename ElementTlvs::variant_type wrap(p1); + move(wrap); +} +template +struct Trans_NS__v1_GenericContainerEntryBase + : Trans_NS__v1_GenericTlvContainer {}; +template +struct Trans_NS__v1_GenericFixedLengthTlvBase : Trans_NS__v1_GenericTlvBase { + unsigned long getValueLength() const; +}; +struct Trans_NS__v1_GenericUnsupportedTlv : Trans_NS__v1_GenericTlv { + long getHeaderLengthconst; +}; +using isis_tlv_config = int; +template +using isis_element_tlvs = + generic_element_tlvs; +template +using ContainerEntryBase = Trans_NS__v1_GenericContainerEntryBase; +template +using FixedLengthTlvBase = Trans_NS__v1_GenericFixedLengthTlvBase; +struct IPv4NeighborAddressSubTlv + : FixedLengthTlvBase<0, IPv4NeighborAddressSubTlv, 0> { + bool operator==(const IPv4NeighborAddressSubTlv &) const; +}; +void test() { + ContainerEntryBase< + 0, int, + isis_element_tlvs< + FixedLengthTlvBase<0, int, 0>, FixedLengthTlvBase<0, int, 0>, + IPv4NeighborAddressSubTlv, FixedLengthTlvBase<0, int, 0>, + FixedLengthTlvBase<0, int, 0>, FixedLengthTlvBase<0, int, 0>>> + isEntry; + IPv4NeighborAddressSubTlv nbAddressSubTlv; + isEntry.addTlv(nbAddressSubTlv); +} -- 2.30.2