This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix wrong assumption in contains_type_p (PR ipa/71207).
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: Martin Liška <mliska at suse dot cz>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jan Hubicka <hubicka at ucw dot cz>
- Date: Tue, 17 Jan 2017 11:43:38 +0100
- Subject: Re: [PATCH] Fix wrong assumption in contains_type_p (PR ipa/71207).
- Authentication-results: sourceware.org; auth=none
- References: <61727576-2f83-3155-c6dc-655e4770d79e@suse.cz>
>
> gcc/testsuite/ChangeLog:
>
> 2017-01-12 Martin Liska <mliska@suse.cz>
>
> PR ipa/71207
> * g++.dg/ipa/pr71207.C: New test.
>
> gcc/ChangeLog:
>
> 2017-01-12 Martin Liska <mliska@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.
> 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
>