This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp4, 15/23] Allow as-conversions in initializers in the C frontend
- From: Bernd Schmidt <bernds at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 9 Dec 2013 16:09:29 +0100
- Subject: [gomp4, 15/23] Allow as-conversions in initializers in the C frontend
- Authentication-results: sourceware.org; auth=none
- References: <52A5D8D4 dot 2030803 at codesourcery dot com>
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;
}