From 567700fddd2cbc1d90bb8f2acae81b3210dba2fb Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 6 Nov 2015 17:04:38 +0100 Subject: [PATCH] re PR ipa/68057 (450.soplex in SPEC CPU 2006 failed to build) PR ipa/68057 PR ipa/68220 * ipa-polymorphic-call.c (ipa_polymorphic_call_context::restrict_to_inner_type): Fix ordering issue when offset is out of range. (contains_type_p): Fix out of range check, clear dynamic flag. * g++.dg/lto/pr68057_0.C: New testcase. * g++.dg/lto/pr68057_1.C: New testcase. * g++.dg/torture/pr68220.C: New testcase. From-SVN: r229859 --- gcc/ChangeLog | 9 + gcc/ipa-polymorphic-call.c | 21 ++- gcc/testsuite/ChangeLog | 8 + gcc/testsuite/g++.dg/lto/pr68057_0.C | 23 +++ gcc/testsuite/g++.dg/lto/pr68057_1.C | 17 ++ gcc/testsuite/g++.dg/torture/pr68220.C | 238 +++++++++++++++++++++++++ 6 files changed, 309 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lto/pr68057_0.C create mode 100644 gcc/testsuite/g++.dg/lto/pr68057_1.C create mode 100644 gcc/testsuite/g++.dg/torture/pr68220.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bc2a9f66c62..48fbdae4e9d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-11-07 Jan Hubicka + + PR ipa/68057 + PR ipa/68220 + * ipa-polymorphic-call.c + (ipa_polymorphic_call_context::restrict_to_inner_type): Fix ordering + issue when offset is out of range. + (contains_type_p): Fix out of range check, clear dynamic flag. + 2015-11-06 Arnout Vandecappelle * config.gcc (e6500): Fix cpu_is_64bit typo. diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c index 2f284950d8d..5730e46069f 100644 --- a/gcc/ipa-polymorphic-call.c +++ b/gcc/ipa-polymorphic-call.c @@ -154,6 +154,8 @@ ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type, && tree_to_shwi (TYPE_SIZE (outer_type)) >= 0 && tree_to_shwi (TYPE_SIZE (outer_type)) <= offset) { + bool der = maybe_derived_type; /* clear_outer_type will reset it. */ + bool dyn = dynamic; clear_outer_type (otr_type); type = otr_type; cur_offset = 0; @@ -162,7 +164,7 @@ ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type, For dynamic types, we really do not have information about size of the memory location. It is possible that completely different type is stored after outer_type. */ - if (!maybe_derived_type && !dynamic) + if (!der && !dyn) { clear_speculation (); invalid = true; @@ -425,8 +427,10 @@ no_useful_type_info: return true; } else - clear_speculation (); - return true; + { + clear_speculation (); + return true; + } } else { @@ -459,15 +463,18 @@ contains_type_p (tree outer_type, HOST_WIDE_INT offset, if (offset < 0) return false; if (TYPE_SIZE (outer_type) && TYPE_SIZE (otr_type) - && TREE_CODE (outer_type) == INTEGER_CST - && TREE_CODE (otr_type) == INTEGER_CST - && wi::ltu_p (wi::to_offset (outer_type), (wi::to_offset (otr_type) + offset))) + && TREE_CODE (TYPE_SIZE (outer_type)) == INTEGER_CST + && TREE_CODE (TYPE_SIZE (otr_type)) == INTEGER_CST + && wi::ltu_p (wi::to_offset (TYPE_SIZE (outer_type)), + (wi::to_offset (TYPE_SIZE (otr_type)) + offset))) return false; context.offset = offset; context.outer_type = TYPE_MAIN_VARIANT (outer_type); context.maybe_derived_type = false; - return context.restrict_to_inner_class (otr_type, consider_placement_new, consider_bases); + context.dynamic = false; + return context.restrict_to_inner_class (otr_type, consider_placement_new, + consider_bases); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ac4c3c5cf42..1fe39a4525a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-11-07 Jan Hubicka + + PR ipa/68057 + PR ipa/68220 + * g++.dg/lto/pr68057_0.C: New testcase. + * g++.dg/lto/pr68057_1.C: New testcase. + * g++.dg/torture/pr68220.C: New testcase. + 2015-11-06 Christophe Lyon * gcc.target/aarch64/advsimd-intrinsics/vtbX.c: Fix typos in diff --git a/gcc/testsuite/g++.dg/lto/pr68057_0.C b/gcc/testsuite/g++.dg/lto/pr68057_0.C new file mode 100644 index 00000000000..9894b9b1ce7 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr68057_0.C @@ -0,0 +1,23 @@ +// { dg-lto-do compile } +/* { dg-extra-ld-options { -O2 -Wno-odr -r -nostdlib } } */ +struct SPxPricer; +struct SoPlex { + virtual void setPricer(SPxPricer *); +}; +struct SPxPricer { + virtual void load(SoPlex *); +}; +struct SLUFactor { + SLUFactor(); + virtual ~SLUFactor(); +}; +struct SPxSolver : SoPlex { + SPxPricer pr; + SLUFactor slu; + SPxSolver(); +}; +struct A : SPxSolver {}; +A a; + +void SoPlex::setPricer(SPxPricer *p1) { p1->load(this); } + diff --git a/gcc/testsuite/g++.dg/lto/pr68057_1.C b/gcc/testsuite/g++.dg/lto/pr68057_1.C new file mode 100644 index 00000000000..f45a81ec88b --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr68057_1.C @@ -0,0 +1,17 @@ +struct SPxPricer; +struct SoPlex { + virtual void setPricer(SPxPricer *); +}; +struct SPxPricer { + virtual void load(SoPlex *); +}; +struct SLUFactor { + SLUFactor(); + virtual ~SLUFactor(); +}; +struct SPxSolver : SoPlex { + SPxPricer pr; + SLUFactor slu; + SPxSolver(); +}; +SPxSolver::SPxSolver() { setPricer(&pr); } diff --git a/gcc/testsuite/g++.dg/torture/pr68220.C b/gcc/testsuite/g++.dg/torture/pr68220.C new file mode 100644 index 00000000000..3b27653219c --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr68220.C @@ -0,0 +1,238 @@ +// { dg-do compile } +namespace mpl { +template struct lambda; +template struct if_ { typedef T3 type; }; +template struct arg { + template struct apply { typedef U1 type; }; +}; +template struct begin_impl; +template struct begin { + typedef typename Sequence::tag tag_; + typedef typename begin_impl::template apply::type type; +}; +template struct O1_size_impl; +} +template struct long_ { static const long value = N; }; +namespace mpl { +template +struct O1_size + : O1_size_impl::template apply {}; +typedef arg<1> _1; +template struct protect : T {}; +template struct apply_wrap1 : F::template apply {}; +template +struct apply_wrap2 : F::template apply {}; +template struct apply_wrap5 : F::template apply {}; +template +struct resolve_bind_arg; +template struct replace_unnamed_arg { typedef T type; }; +template struct bind1 { + template struct apply { + typedef typename apply_wrap1::type type; + }; +}; +template +struct resolve_bind_arg, U1, U2, U3, U4, U5> { + typedef typename apply_wrap5>::type type; +}; +template struct bind2 { + template struct apply { + typedef resolve_bind_arg>::type, U1, + U2, int, int, int> t2; + typedef typename apply_wrap2::type + type; + }; +}; +template struct quote_impl { typedef T type; }; +template