This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][C++] Fix PR37742
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "Richard Guenther" <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org, "Jason Merrill" <jason at redhat dot com>, "Mark Mitchell" <mark at codesourcery dot com>
- Date: Thu, 30 Oct 2008 21:56:11 +0100
- Subject: Re: [PATCH][C++] Fix PR37742
- References: <alpine.LNX.1.10.0810152252390.3746@zhemvz.fhfr.qr>
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" } } */
>