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]

[gomp4, 15/23] Allow as-conversions in initializers in the C frontend


Consider

int x; /* Global address space is implicit for nvptx. */
int *p = &x;

where x is a variable in __global address space, and p is a generic
pointer. We won't get very far if this doesn't work, so we must change
the C frontend to allow this conversion. This works together with the
AS_CONVERT change earlier in this series. A followup patch will add
support for implicit address spaces.

	gcc/c/
	* c-typeck.c (comptypes_internal): New argument allow_as_subset.  If
	set, allow address space changes from a subset to a superset.  All
	callers changed to pass false, except one instance in this function
	where pointer target types are compared.

------------------------------------------------------------------------
Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c.orig
+++ gcc/c/c-typeck.c
@@ -110,7 +110,7 @@ static tree find_init_member (tree, stru
 static void readonly_warning (tree, enum lvalue_use);
 static int lvalue_or_else (location_t, const_tree, enum lvalue_use);
 static void record_maybe_used_decl (tree);
-static int comptypes_internal (const_tree, const_tree, bool *, bool *);
+static int comptypes_internal (const_tree, const_tree, bool, bool *, bool *);
 
 /* Return true if EXP is a null pointer constant, false otherwise.  */
 
@@ -986,7 +986,7 @@ comptypes (tree type1, tree type2)
   const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
   int val;
 
-  val = comptypes_internal (type1, type2, NULL, NULL);
+  val = comptypes_internal (type1, type2, false, NULL, NULL);
   free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
 
   return val;
@@ -1001,7 +1001,7 @@ comptypes_check_enum_int (tree type1, tr
   const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
   int val;
 
-  val = comptypes_internal (type1, type2, enum_and_int_p, NULL);
+  val = comptypes_internal (type1, type2, false, enum_and_int_p, NULL);
   free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
 
   return val;
@@ -1017,7 +1017,7 @@ comptypes_check_different_types (tree ty
   const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
   int val;
 
-  val = comptypes_internal (type1, type2, NULL, different_types_p);
+  val = comptypes_internal (type1, type2, false, NULL, different_types_p);
   free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
 
   return val;
@@ -1034,11 +1034,13 @@ comptypes_check_different_types (tree ty
    *DIFFERENT_TYPES_P to true; *DIFFERENT_TYPES_P is never set to
    false, but may or may not be set if the types are incompatible.
    This differs from comptypes, in that we don't free the seen
-   types.  */
+   types.
+   ALLOW_AS_SUBSET, if true, causes this function to allow cases where
+   the address space of TYPE2 is a superset of that of TYPE1.  */
 
 static int
-comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
-		    bool *different_types_p)
+comptypes_internal (const_tree type1, const_tree type2, bool allow_as_subset,
+		    bool *enum_and_int_p, bool *different_types_p)
 {
   const_tree t1 = type1;
   const_tree t2 = type2;
@@ -1088,7 +1090,16 @@ comptypes_internal (const_tree type1, co
   /* Qualifiers must match. C99 6.7.3p9 */
 
   if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
-    return 0;
+    {
+      if (!allow_as_subset)
+	return 0;
+      if (TYPE_QUALS_NO_ADDR_SPACE (t1) != TYPE_QUALS_NO_ADDR_SPACE (t2))
+	return 0;
+      addr_space_t as1 = TYPE_ADDR_SPACE (t1);
+      addr_space_t as2 = TYPE_ADDR_SPACE (t2);
+      if (!targetm.addr_space.subset_p (as1, as2))
+	return 0;
+    }
 
   /* Allow for two different type nodes which have essentially the same
      definition.  Note that we already checked for equality of the type
@@ -1113,7 +1124,7 @@ comptypes_internal (const_tree type1, co
 	  || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
 	break;
       val = (TREE_TYPE (t1) == TREE_TYPE (t2)
-	     ? 1 : comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
+	     ? 1 : comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), true,
 				       enum_and_int_p, different_types_p));
       break;
 
@@ -1133,7 +1144,7 @@ comptypes_internal (const_tree type1, co
 	/* Target types must match incl. qualifiers.  */
 	if (TREE_TYPE (t1) != TREE_TYPE (t2)
 	    && 0 == (val = comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
-					       enum_and_int_p,
+					       false, enum_and_int_p,
 					       different_types_p)))
 	  return 0;
 
@@ -1193,7 +1204,7 @@ comptypes_internal (const_tree type1, co
 
     case VECTOR_TYPE:
       val = (TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
-	     && comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
+	     && comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), false,
 				    enum_and_int_p, different_types_p));
       break;
 
@@ -1445,7 +1456,7 @@ tagged_types_tu_compatible_p (const_tree
 
 	    if (DECL_NAME (s1) != DECL_NAME (s2))
 	      break;
-	    result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
+	    result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), false,
 					 enum_and_int_p, different_types_p);
 
 	    if (result != 1 && !DECL_NAME (s1))
@@ -1482,7 +1493,7 @@ tagged_types_tu_compatible_p (const_tree
 		  int result;
 
 		  result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
-					       enum_and_int_p,
+					       false, enum_and_int_p,
 					       different_types_p);
 
 		  if (result != 1 && !DECL_NAME (s1))
@@ -1525,7 +1536,7 @@ tagged_types_tu_compatible_p (const_tree
 	    if (TREE_CODE (s1) != TREE_CODE (s2)
 		|| DECL_NAME (s1) != DECL_NAME (s2))
 	      break;
-	    result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
+	    result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), false,
 					 enum_and_int_p, different_types_p);
 	    if (result == 0)
 	      break;
@@ -1580,7 +1591,7 @@ function_types_compatible_p (const_tree
   if (TYPE_VOLATILE (ret2))
     ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
 				 TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE);
-  val = comptypes_internal (ret1, ret2, enum_and_int_p, different_types_p);
+  val = comptypes_internal (ret1, ret2, false, enum_and_int_p, different_types_p);
   if (val == 0)
     return 0;
 
@@ -1679,7 +1690,7 @@ type_lists_compatible_p (const_tree args
       else if (TREE_CODE (a1) == ERROR_MARK
 	       || TREE_CODE (a2) == ERROR_MARK)
 	;
-      else if (!(newval = comptypes_internal (mv1, mv2, enum_and_int_p,
+      else if (!(newval = comptypes_internal (mv1, mv2, false, enum_and_int_p,
 					      different_types_p)))
 	{
 	  if (different_types_p != NULL)
@@ -1704,7 +1715,7 @@ type_lists_compatible_p (const_tree args
 			   ? c_build_qualified_type (TYPE_MAIN_VARIANT (mv3),
 						     TYPE_QUAL_ATOMIC)
 			   : TYPE_MAIN_VARIANT (mv3));
-		  if (comptypes_internal (mv3, mv2, enum_and_int_p,
+		  if (comptypes_internal (mv3, mv2, false, enum_and_int_p,
 					  different_types_p))
 		    break;
 		}
@@ -1729,7 +1740,7 @@ type_lists_compatible_p (const_tree args
 			   ? c_build_qualified_type (TYPE_MAIN_VARIANT (mv3),
 						     TYPE_QUAL_ATOMIC)
 			   : TYPE_MAIN_VARIANT (mv3));
-		  if (comptypes_internal (mv3, mv1, enum_and_int_p,
+		  if (comptypes_internal (mv3, mv1, false, enum_and_int_p,
 					  different_types_p))
 		    break;
 		}

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