On 01/17/2017 11:43 AM, Jan Hubicka wrote:
>>
>> gcc/testsuite/ChangeLog:
>>
>> 2017-01-12  Martin Liska  <mli...@suse.cz>
>>
>>      PR ipa/71207
>>      * g++.dg/ipa/pr71207.C: New test.
>>
>> gcc/ChangeLog:
>>
>> 2017-01-12  Martin Liska  <mli...@suse.cz>
>>
>>      PR ipa/71207
>>      * ipa-polymorphic-call.c (contains_type_p): Fix wrong
>>      assumption, add comment and renamed otr_type to inner_type.
>> ---
>>  gcc/ipa-polymorphic-call.c         | 22 ++++++++++----------
>>  gcc/testsuite/g++.dg/ipa/pr71207.C | 42 
>> ++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 53 insertions(+), 11 deletions(-)
>>  create mode 100644 gcc/testsuite/g++.dg/ipa/pr71207.C
>>
>> diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
>> index da64ce4c6e0..c13fc858c86 100644
>> --- a/gcc/ipa-polymorphic-call.c
>> +++ b/gcc/ipa-polymorphic-call.c
>> @@ -446,15 +446,15 @@ no_useful_type_info:
>>      }
>>  }
>>  
>> -/* Return true if OUTER_TYPE contains OTR_TYPE at OFFSET.
>> -   CONSIDER_PLACEMENT_NEW makes function to accept cases where OTR_TYPE can
>> +/* Return true if OUTER_TYPE contains INNER_TYPE at OFFSET.
>> +   CONSIDER_PLACEMENT_NEW makes function to accept cases where INNER_TYPE 
>> can
>>     be built within OUTER_TYPE by means of placement new.  CONSIDER_BASES 
>> makes
>> -   function to accept cases where OTR_TYPE appears as base of OUTER_TYPE or 
>> as
>> +   function to accept cases where INNER_TYPE appears as base of OUTER_TYPE 
>> or as
>>     base of one of fields of OUTER_TYPE.  */
>>  
>>  static bool
>>  contains_type_p (tree outer_type, HOST_WIDE_INT offset,
>> -             tree otr_type,
>> +             tree inner_type,
> 
> I would actually keep otr_type (or change it consistently in all cases).
> otr comes from OBJ_TYPE_REF and is used thorough the code (not my invention,
> comming from original binfo walking routine).
> 
> OK with that change.  I bleive I added the size check only to cut the 
> recurision
> early which is not a big deal.

Ok, applied without the renaming as r244530. I guess you added that to cut the 
recursion.

Would it be fine to install the patch to active branches after proper testing?
Thanks,
Martin

>>               bool consider_placement_new,
>>               bool consider_bases)
>>  {
>> @@ -463,18 +463,18 @@ contains_type_p (tree outer_type, HOST_WIDE_INT offset,
>>    /* Check that type is within range.  */
>>    if (offset < 0)
>>      return false;
>> -  if (TYPE_SIZE (outer_type) && TYPE_SIZE (otr_type)
>> -      && 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;
>> +
>> +  /* PR ipa/71207
>> +     As OUTER_TYPE can be a type which has a diamond virtual inheritance,
>> +     it's not necessary that INNER_TYPE will fit within OUTER_TYPE with
>> +     a given offset.  It can happen that INNER_TYPE also contains a base 
>> object,
>> +     however it would point to the same instance in the OUTER_TYPE.  */
>>  
>>    context.offset = offset;
>>    context.outer_type = TYPE_MAIN_VARIANT (outer_type);
>>    context.maybe_derived_type = false;
>>    context.dynamic = false;
>> -  return context.restrict_to_inner_class (otr_type, consider_placement_new,
>> +  return context.restrict_to_inner_class (inner_type, 
>> consider_placement_new,
>>                                        consider_bases);
>>  }
>>  
>> diff --git a/gcc/testsuite/g++.dg/ipa/pr71207.C 
>> b/gcc/testsuite/g++.dg/ipa/pr71207.C
>> new file mode 100644
>> index 00000000000..19a03998460
>> --- /dev/null
>> +++ b/gcc/testsuite/g++.dg/ipa/pr71207.C
>> @@ -0,0 +1,42 @@
>> +/* PR ipa/71207 */
>> +/* { dg-do run } */
>> +
>> +class Class1
>> +{
>> +public:
>> +  Class1() {};
>> +  virtual ~Class1() {};
>> +
>> +protected:
>> +  unsigned Field1;
>> +};
>> +
>> +class Class2 : public virtual Class1
>> +{
>> +};
>> +
>> +class Class3 : public virtual Class1
>> +{
>> +public:
>> +  virtual void Method1() = 0;
>> +
>> +  void Method2()
>> +  {
>> +    Method1();
>> +  }
>> +};
>> +
>> +class Class4 : public Class2, public virtual Class3
>> +{
>> +public:
>> +  Class4() {};
>> +  virtual void Method1() {};
>> +};
>> +
>> +int main()
>> +{
>> +  Class4 var1;
>> +  var1.Method2();
>> +
>> +  return 0;
>> +}
>> -- 
>> 2.11.0
>>
> 

Reply via email to