aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-typeck.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-typeck.c')
-rw-r--r--gcc/c-typeck.c94
1 files changed, 70 insertions, 24 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index f04ba73ad75..3a38d22923b 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -375,29 +375,51 @@ composite_type (tree t1, tree t2)
&& TREE_VALUE (p1) != TREE_VALUE (p2))
{
tree memb;
+ tree mv2 = TREE_VALUE (p2);
+ if (mv2 && mv2 != error_mark_node
+ && TREE_CODE (mv2) != ARRAY_TYPE)
+ mv2 = TYPE_MAIN_VARIANT (mv2);
for (memb = TYPE_FIELDS (TREE_VALUE (p1));
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2)))
- {
- TREE_VALUE (n) = TREE_VALUE (p2);
- if (pedantic)
- pedwarn ("function types not truly compatible in ISO C");
- goto parm_done;
- }
+ {
+ tree mv3 = TREE_TYPE (memb);
+ if (mv3 && mv3 != error_mark_node
+ && TREE_CODE (mv3) != ARRAY_TYPE)
+ mv3 = TYPE_MAIN_VARIANT (mv3);
+ if (comptypes (mv3, mv2))
+ {
+ TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
+ TREE_VALUE (p2));
+ if (pedantic)
+ pedwarn ("function types not truly compatible in ISO C");
+ goto parm_done;
+ }
+ }
}
if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE
&& TREE_VALUE (p2) != TREE_VALUE (p1))
{
tree memb;
+ tree mv1 = TREE_VALUE (p1);
+ if (mv1 && mv1 != error_mark_node
+ && TREE_CODE (mv1) != ARRAY_TYPE)
+ mv1 = TYPE_MAIN_VARIANT (mv1);
for (memb = TYPE_FIELDS (TREE_VALUE (p2));
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1)))
- {
- TREE_VALUE (n) = TREE_VALUE (p1);
- if (pedantic)
- pedwarn ("function types not truly compatible in ISO C");
- goto parm_done;
- }
+ {
+ tree mv3 = TREE_TYPE (memb);
+ if (mv3 && mv3 != error_mark_node
+ && TREE_CODE (mv3) != ARRAY_TYPE)
+ mv3 = TYPE_MAIN_VARIANT (mv3);
+ if (comptypes (mv3, mv1))
+ {
+ TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
+ TREE_VALUE (p1));
+ if (pedantic)
+ pedwarn ("function types not truly compatible in ISO C");
+ goto parm_done;
+ }
+ }
}
TREE_VALUE (n) = composite_type (TREE_VALUE (p1), TREE_VALUE (p2));
parm_done: ;
@@ -470,8 +492,8 @@ common_pointer_type (tree t1, tree t2)
This is the type for the result of most arithmetic operations
if the operands have the given two types. */
-tree
-common_type (tree t1, tree t2)
+static tree
+c_common_type (tree t1, tree t2)
{
enum tree_code code1;
enum tree_code code2;
@@ -522,7 +544,7 @@ common_type (tree t1, tree t2)
{
tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
- tree subtype = common_type (subtype1, subtype2);
+ tree subtype = c_common_type (subtype1, subtype2);
if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
return t1;
@@ -592,6 +614,18 @@ common_type (tree t1, tree t2)
return t2;
}
+/* Wrapper around c_common_type that is used by c-common.c. ENUMERAL_TYPEs
+ are allowed here and are converted to their compatible integer types. */
+tree
+common_type (tree t1, tree t2)
+{
+ if (TREE_CODE (t1) == ENUMERAL_TYPE)
+ t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
+ if (TREE_CODE (t2) == ENUMERAL_TYPE)
+ t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
+ return c_common_type (t1, t2);
+}
+
/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
or various other operations. Return 2 if they are compatible
but a warning may be needed if you use them together. */
@@ -1110,8 +1144,14 @@ type_lists_compatible_p (tree args1, tree args2)
tree memb;
for (memb = TYPE_FIELDS (a1);
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), a2))
- break;
+ {
+ tree mv3 = TREE_TYPE (memb);
+ if (mv3 && mv3 != error_mark_node
+ && TREE_CODE (mv3) != ARRAY_TYPE)
+ mv3 = TYPE_MAIN_VARIANT (mv3);
+ if (comptypes (mv3, mv2))
+ break;
+ }
if (memb == 0)
return 0;
}
@@ -1125,8 +1165,14 @@ type_lists_compatible_p (tree args1, tree args2)
tree memb;
for (memb = TYPE_FIELDS (a2);
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), a1))
- break;
+ {
+ tree mv3 = TREE_TYPE (memb);
+ if (mv3 && mv3 != error_mark_node
+ && TREE_CODE (mv3) != ARRAY_TYPE)
+ mv3 = TYPE_MAIN_VARIANT (mv3);
+ if (comptypes (mv3, mv1))
+ break;
+ }
if (memb == 0)
return 0;
}
@@ -2893,7 +2939,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
&& (code2 == INTEGER_TYPE || code2 == REAL_TYPE
|| code2 == COMPLEX_TYPE))
{
- result_type = common_type (type1, type2);
+ result_type = c_common_type (type1, type2);
/* If -Wsign-compare, warn here if type1 and type2 have
different signedness. We'll promote the signed to unsigned
@@ -7461,7 +7507,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
if (shorten || common || short_compare)
- result_type = common_type (type0, type1);
+ result_type = c_common_type (type0, type1);
/* For certain operations (which identify themselves by shorten != 0)
if both args were extended from the same smaller type,
@@ -7519,7 +7565,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
&& (unsigned0 || !uns))
result_type
= c_common_signed_or_unsigned_type
- (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
+ (unsigned0, c_common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
else if (TREE_CODE (arg0) == INTEGER_CST
&& (unsigned1 || !uns)
&& (TYPE_PRECISION (TREE_TYPE (arg1))