This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][C++] Fix PR37742


On Wed, Oct 15, 2008 at 9:56 PM, Richard Guenther <rguenther@suse.de> wrote:
>
> This PR exposes that we do not properly preserve conversions to restrict
> qualified pointers.  Which is because we strip qualifiers before checking
> for them.  Oops.  That's easily fixed.
>
> Follows a fix for the gimplifier to not, if a temporary for the
> conversion to a restrict qualified pointer is required, create a
> not restrict qualified temporary for that ...
>
> Follows a fix for the C++ frontend to not drop all qualifiers for
> the type of the RESULT_DECL.  In particular we shouldn't drop
> restrict qualifiers.  All other qualifiers are harmless, as for
> the temporary decl types.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?

Ping!  The C++ parts need approval.

Thanks,
Richard.

> Thanks,
> Richard.
>
>
> 2008-10-14  Richard Guenther  <rguenther@suse.de>
>
>        PR middle-end/37742
>        * tree-ssa.c (useless_type_conversion_p_1): Check different restrict
>        qualified pointer conversion before stripping qualifiers.
>        * gimplify.c (create_tmp_from_val): Use correctly qualified type.
>
>        cp/
>        * decl.c (start_preparsed_function): Use the correct type for
>        building the RESULT_DECL.
>
>        * gcc.c-torture/compile/pr37742.c: New testcase.
>        * g++.dg/pr37742.C: Likewise.
>        * gcc.dg/tree-ssa/forwprop-7.c: Check for two volatile loads.
>
> Index: gcc/tree-ssa.c
> ===================================================================
> *** gcc/tree-ssa.c.orig 2008-10-15 22:30:21.000000000 +0200
> --- gcc/tree-ssa.c      2008-10-15 22:30:25.000000000 +0200
> ***************
> *** 1071,1077 ****
>  static bool
>  useless_type_conversion_p_1 (tree outer_type, tree inner_type)
>  {
> !   /* Qualifiers on value types do not matter.  */
>    inner_type = TYPE_MAIN_VARIANT (inner_type);
>    outer_type = TYPE_MAIN_VARIANT (outer_type);
>
> --- 1071,1088 ----
>  static bool
>  useless_type_conversion_p_1 (tree outer_type, tree inner_type)
>  {
> !   /* Do the following before stripping toplevel qualifiers.  */
> !   if (POINTER_TYPE_P (inner_type)
> !       && POINTER_TYPE_P (outer_type))
> !     {
> !       /* Do not lose casts to restrict qualified pointers.  */
> !       if ((TYPE_RESTRICT (outer_type)
> !          != TYPE_RESTRICT (inner_type))
> !         && TYPE_RESTRICT (outer_type))
> !       return false;
> !     }
> !
> !   /* From now on qualifiers on value types do not matter.  */
>    inner_type = TYPE_MAIN_VARIANT (inner_type);
>    outer_type = TYPE_MAIN_VARIANT (outer_type);
>
> ***************
> *** 1142,1153 ****
>        /* We do not care for const qualification of the pointed-to types
>         as const qualification has no semantic value to the middle-end.  */
>
> -       /* Do not lose casts to restrict qualified pointers.  */
> -       if ((TYPE_RESTRICT (outer_type)
> -          != TYPE_RESTRICT (inner_type))
> -         && TYPE_RESTRICT (outer_type))
> -       return false;
> -
>        /* Otherwise pointers/references are equivalent if their pointed
>         to types are effectively the same.  We can strip qualifiers
>         on pointed-to types for further comparison, which is done in
> --- 1153,1158 ----
> Index: gcc/testsuite/gcc.c-torture/compile/pr37742.c
> ===================================================================
> *** /dev/null   1970-01-01 00:00:00.000000000 +0000
> --- gcc/testsuite/gcc.c-torture/compile/pr37742.c       2008-10-15 22:30:25.000000000 +0200
> ***************
> *** 0 ****
> --- 1,21 ----
> + void foo(int* __restrict__ p, int* q, int* p1, int *q1)
> + {
> +   int i;
> +
> +   p = p1;
> +   q = q1;
> +
> +   for (i = 0; i < 4; ++i)
> +     *++q = *++p + 1;
> + }
> +
> + void bar(int* p, int* __restrict__ q, int* p1, int *q1)
> + {
> +   int i;
> +
> +   p = p1;
> +   q = q1;
> +
> +   for (i = 0; i < 4; ++i)
> +     *++q = *++p + 1;
> + }
> Index: gcc/gimplify.c
> ===================================================================
> *** gcc/gimplify.c.orig 2008-10-15 22:30:21.000000000 +0200
> --- gcc/gimplify.c      2008-10-15 22:30:25.000000000 +0200
> ***************
> *** 565,571 ****
>  static inline tree
>  create_tmp_from_val (tree val)
>  {
> !   return create_tmp_var (TYPE_MAIN_VARIANT (TREE_TYPE (val)), get_name (val));
>  }
>
>  /* Create a temporary to hold the value of VAL.  If IS_FORMAL, try to reuse
> --- 565,571 ----
>  static inline tree
>  create_tmp_from_val (tree val)
>  {
> !   return create_tmp_var (TREE_TYPE (val), get_name (val));
>  }
>
>  /* Create a temporary to hold the value of VAL.  If IS_FORMAL, try to reuse
> Index: gcc/cp/decl.c
> ===================================================================
> *** gcc/cp/decl.c.orig  2008-10-15 22:30:22.000000000 +0200
> --- gcc/cp/decl.c       2008-10-15 22:30:25.000000000 +0200
> ***************
> *** 11459,11465 ****
>      {
>        tree resdecl;
>
> !       resdecl = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype));
>        DECL_ARTIFICIAL (resdecl) = 1;
>        DECL_IGNORED_P (resdecl) = 1;
>        DECL_RESULT (decl1) = resdecl;
> --- 11459,11465 ----
>      {
>        tree resdecl;
>
> !       resdecl = build_decl (RESULT_DECL, 0, restype);
>        DECL_ARTIFICIAL (resdecl) = 1;
>        DECL_IGNORED_P (resdecl) = 1;
>        DECL_RESULT (decl1) = resdecl;
> Index: gcc/testsuite/g++.dg/pr37742.C
> ===================================================================
> *** /dev/null   1970-01-01 00:00:00.000000000 +0000
> --- gcc/testsuite/g++.dg/pr37742.C      2008-10-15 22:30:25.000000000 +0200
> ***************
> *** 0 ****
> --- 1,10 ----
> + /* { dg-do compile } */
> +
> + typedef long unsigned int size_t;
> + void*   __valarray_get_memory(size_t __n);
> + int*__restrict__
> + __valarray_get_storage(size_t __n)
> + {
> +   return static_cast<int* __restrict__>(__valarray_get_memory(__n));
> + }
> +
> Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-7.c
> ===================================================================
> *** gcc/testsuite/gcc.dg/tree-ssa/forwprop-7.c.orig     2008-10-15 22:32:19.000000000 +0200
> --- gcc/testsuite/gcc.dg/tree-ssa/forwprop-7.c  2008-10-15 22:33:12.000000000 +0200
> ***************
> *** 8,14 ****
>    return *p + *p;
>  }
>
> ! /* We should not convert the cast to a VCE in forwprop1 as we have a volatile reference.  */
>  /* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 0 "forwprop1"} } */
> ! /* { dg-final { scan-tree-dump-times "volatile int" 2 "forwprop1"} } */
>  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
> --- 8,16 ----
>    return *p + *p;
>  }
>
> ! /* We should not convert the cast to a VCE in forwprop1 as we have a
> !    volatile reference.  */
> !
>  /* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 0 "forwprop1"} } */
> ! /* { dg-final { scan-tree-dump-times "={v}" 2 "forwprop1"} } */
>  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]