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; }