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]

[PATCH][C++] Fix PR37742


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?

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]