X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-typeck.c;h=9d41433b3975bb3e68368d8664743bbd66e72a51;hb=411bd122ff01bc10db2a1463dd8c90b264d51259;hp=b96328d89b90f4174b2c414a0541b33dd0f305c0;hpb=4eb4ffd7085e84444df44b13615b9a38f3490ac9;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index b96328d89b9..9d41433b397 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -76,7 +76,7 @@ static int require_constant_elements; static tree qualify_type (tree, tree); static int tagged_types_tu_compatible_p (tree, tree); -static int comp_target_types (tree, tree, int); +static int comp_target_types (tree, tree); static int function_types_compatible_p (tree, tree); static int type_lists_compatible_p (tree, tree); static tree decl_constant_value_for_broken_optimization (tree); @@ -618,7 +618,9 @@ c_common_type (tree t1, tree 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. */ + are allowed here and are converted to their compatible integer types. + BOOLEAN_TYPEs are allowed here and return either boolean_type_node or + preferably a non-Boolean type as the common type. */ tree common_type (tree t1, tree t2) { @@ -626,6 +628,18 @@ common_type (tree t1, tree t2) 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); + + /* If both types are BOOLEAN_TYPE, then return boolean_type_node. */ + if (TREE_CODE (t1) == BOOLEAN_TYPE + && TREE_CODE (t2) == BOOLEAN_TYPE) + return boolean_type_node; + + /* If either type is BOOLEAN_TYPE, then return the other. */ + if (TREE_CODE (t1) == BOOLEAN_TYPE) + return t2; + if (TREE_CODE (t2) == BOOLEAN_TYPE) + return t1; + return c_common_type (t1, t2); } @@ -697,10 +711,6 @@ comptypes (tree type1, tree type2) switch (TREE_CODE (t1)) { case POINTER_TYPE: - /* We must give ObjC the first crack at comparing pointers, since - protocol qualifiers may be involved. */ - if (c_dialect_objc () && (val = objc_comptypes (t1, t2, 0)) >= 0) - break; /* Do not remove mode or aliasing information. */ if (TYPE_MODE (t1) != TYPE_MODE (t2) || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2)) @@ -752,13 +762,8 @@ comptypes (tree type1, tree type2) break; } - case RECORD_TYPE: - /* We are dealing with two distinct structs. In assorted Objective-C - corner cases, however, these can still be deemed equivalent. */ - if (c_dialect_objc () && objc_comptypes (t1, t2, 0) == 1) - val = 1; - case ENUMERAL_TYPE: + case RECORD_TYPE: case UNION_TYPE: if (val != 1 && !same_translation_unit_p (t1, t2)) val = tagged_types_tu_compatible_p (t1, t2); @@ -776,22 +781,14 @@ comptypes (tree type1, tree type2) } /* Return 1 if TTL and TTR are pointers to types that are equivalent, - ignoring their qualifiers. REFLEXIVE is only used by ObjC - set it - to 1 or 0 depending if the check of the pointer types is meant to - be reflexive or not (typically, assignments are not reflexive, - while comparisons are reflexive). -*/ + ignoring their qualifiers. */ static int -comp_target_types (tree ttl, tree ttr, int reflexive) +comp_target_types (tree ttl, tree ttr) { int val; tree mvl, mvr; - /* Give objc_comptypes a crack at letting these types through. */ - if ((val = objc_comptypes (ttl, ttr, reflexive)) >= 0) - return val; - /* Do not lose qualifiers on element types of array types that are pointer targets by taking their TYPE_MAIN_VARIANT. */ mvl = TREE_TYPE (ttl); @@ -1641,12 +1638,9 @@ build_indirect_ref (tree ptr, const char *errorstring) else { tree t = TREE_TYPE (type); - tree mvt = t; tree ref; - if (TREE_CODE (mvt) != ARRAY_TYPE) - mvt = TYPE_MAIN_VARIANT (mvt); - ref = build1 (INDIRECT_REF, mvt, pointer); + ref = build1 (INDIRECT_REF, t, pointer); if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE) { @@ -2009,6 +2003,10 @@ build_function_call (tree function, tree params) else function = default_conversion (function); + /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF + expressions, like those used for ObjC messenger dispatches. */ + function = objc_rewrite_function_call (function, params); + fntype = TREE_TYPE (function); if (TREE_CODE (fntype) == ERROR_MARK) @@ -2031,13 +2029,8 @@ build_function_call (tree function, tree params) If it is not, replace the call by a trap, wrapped up in a compound expression if necessary. This has the nice side-effect to prevent the tree-inliner from generating invalid assignment trees which may - blow up in the RTL expander later. - - ??? This doesn't work for Objective-C because objc_comptypes - refuses to compare function prototypes, yet the compiler appears - to build calls that are flagged as invalid by C's comptypes. */ - if (!c_dialect_objc () - && TREE_CODE (function) == NOP_EXPR + blow up in the RTL expander later. */ + if (TREE_CODE (function) == NOP_EXPR && TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR && TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL && !comptypes (fntype, TREE_TYPE (tem))) @@ -3040,7 +3033,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) } else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) { - if (comp_target_types (type1, type2, 1)) + if (comp_target_types (type1, type2)) result_type = common_pointer_type (type1, type2); else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node && TREE_CODE (orig_op1) != NOP_EXPR) @@ -3471,6 +3464,14 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) if (TREE_CODE (newrhs) == ERROR_MARK) return error_mark_node; + /* Emit ObjC write barrier, if necessary. */ + if (c_dialect_objc () && flag_objc_gc) + { + result = objc_generate_write_barrier (lhs, modifycode, newrhs); + if (result) + return result; + } + /* Scan operands. */ result = build2 (MODIFY_EXPR, lhstype, lhs, newrhs); @@ -3506,6 +3507,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, tree rhstype; enum tree_code coder; tree rname = NULL_TREE; + bool objc_ok = false; if (errtype == ic_argpass || errtype == ic_argpass_nonproto) { @@ -3567,14 +3569,35 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, if (coder == ERROR_MARK) return error_mark_node; + if (c_dialect_objc ()) + { + int parmno; + + switch (errtype) + { + case ic_return: + parmno = 0; + break; + + case ic_assign: + parmno = -1; + break; + + case ic_init: + parmno = -2; + break; + + default: + parmno = parmnum; + break; + } + + objc_ok = objc_compare_types (type, rhstype, parmno, rname); + } + if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) { overflow_warning (rhs); - /* Check for Objective-C protocols. This will automatically - issue a warning if there are protocol violations. No need to - use the return value. */ - if (c_dialect_objc ()) - objc_comptypes (type, rhstype, 0); return rhs; } @@ -3657,7 +3680,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, Meanwhile, the lhs target must have all the qualifiers of the rhs. */ if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr) - || comp_target_types (memb_type, rhstype, 0)) + || comp_target_types (memb_type, rhstype)) { /* If this type won't generate any warnings, use it. */ if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr) @@ -3760,7 +3783,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, and vice versa; otherwise, targets must be the same. Meanwhile, the lhs target must have all the qualifiers of the rhs. */ if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr) - || (target_cmp = comp_target_types (type, rhstype, 0)) + || (target_cmp = comp_target_types (type, rhstype)) || is_opaque_pointer || (c_common_unsigned_type (mvl) == c_common_unsigned_type (mvr))) @@ -3788,14 +3811,20 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, && TREE_CODE (ttl) != FUNCTION_TYPE) { if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) - WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE discards " - "qualifiers from pointer target type"), - N_("assignment discards qualifiers " - "from pointer target type"), - N_("initialization discards qualifiers " - "from pointer target type"), - N_("return discards qualifiers from " - "pointer target type")); + { + /* Types differing only by the presence of the 'volatile' + qualifier are acceptable if the 'volatile' has been added + in by the Objective-C EH machinery. */ + if (!objc_type_quals_match (ttl, ttr)) + WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE discards " + "qualifiers from pointer target type"), + N_("assignment discards qualifiers " + "from pointer target type"), + N_("initialization discards qualifiers " + "from pointer target type"), + N_("return discards qualifiers from " + "pointer target type")); + } /* If this is not a case of ignoring a mismatch in signedness, no warning. */ else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr) @@ -3832,12 +3861,15 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, } } else - WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE from " - "incompatible pointer type"), - N_("assignment from incompatible pointer type"), - N_("initialization from incompatible " - "pointer type"), - N_("return from incompatible pointer type")); + /* Avoid warning about the volatile ObjC EH puts on decls. */ + if (!objc_ok) + WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE from " + "incompatible pointer type"), + N_("assignment from incompatible pointer type"), + N_("initialization from incompatible " + "pointer type"), + N_("return from incompatible pointer type")); + return convert (type, rhs); } else if (codel == POINTER_TYPE && coder == ARRAY_TYPE) @@ -4812,19 +4844,27 @@ push_init_level (int implicit) tree value = NULL_TREE; /* If we've exhausted any levels that didn't have braces, - pop them now. */ - while (constructor_stack->implicit) + pop them now. If implicit == 1, this will have been done in + process_init_element; do not repeat it here because in the case + of excess initializers for an empty aggregate this leads to an + infinite cycle of popping a level and immediately recreating + it. */ + if (implicit != 1) { - if ((TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - && constructor_fields == 0) - process_init_element (pop_init_level (1)); - else if (TREE_CODE (constructor_type) == ARRAY_TYPE - && constructor_max_index - && tree_int_cst_lt (constructor_max_index, constructor_index)) - process_init_element (pop_init_level (1)); - else - break; + while (constructor_stack->implicit) + { + if ((TREE_CODE (constructor_type) == RECORD_TYPE + || TREE_CODE (constructor_type) == UNION_TYPE) + && constructor_fields == 0) + process_init_element (pop_init_level (1)); + else if (TREE_CODE (constructor_type) == ARRAY_TYPE + && constructor_max_index + && tree_int_cst_lt (constructor_max_index, + constructor_index)) + process_init_element (pop_init_level (1)); + else + break; + } } /* Unless this is an explicit brace, we need to preserve previous @@ -7418,6 +7458,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, /* Nonzero means set RESULT_TYPE to the common type of the args. */ int common = 0; + /* True means types are compatible as far as ObjC is concerned. */ + bool objc_ok; + if (convert_p) { op0 = default_conversion (orig_op0); @@ -7447,6 +7490,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, if (code0 == ERROR_MARK || code1 == ERROR_MARK) return error_mark_node; + objc_ok = objc_compare_types (type0, type1, -3, NULL_TREE); + switch (code) { case PLUS_EXPR: @@ -7463,7 +7508,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, /* Subtraction of two similar pointers. We must subtract them as integers, then divide by object size. */ if (code0 == POINTER_TYPE && code1 == POINTER_TYPE - && comp_target_types (type0, type1, 1)) + && comp_target_types (type0, type1)) return pointer_diff (op0, op1); /* Handle pointer minus int. Just like pointer plus int. */ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) @@ -7483,8 +7528,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, case EXACT_DIV_EXPR: /* Floating point division by zero is a legitimate way to obtain infinities and NaNs. */ - if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1)) - warning (0, "division by zero"); + if (skip_evaluation == 0 && integer_zerop (op1)) + warning (OPT_Wdiv_by_zero, "division by zero"); if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE) @@ -7522,8 +7567,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: - if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1)) - warning (0, "division by zero"); + if (skip_evaluation == 0 && integer_zerop (op1)) + warning (OPT_Wdiv_by_zero, "division by zero"); if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { @@ -7615,8 +7660,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, case EQ_EXPR: case NE_EXPR: - if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE)) - warning (0, "comparing floating point with == or != is unsafe"); + if (code0 == REAL_TYPE || code1 == REAL_TYPE) + warning (OPT_Wfloat_equal, + "comparing floating point with == or != is unsafe"); /* Result of comparison is always int, but don't convert the args to int! */ build_type = integer_type_node; @@ -7632,7 +7678,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, /* Anything compares with void *. void * compares with anything. Otherwise, the targets must be compatible and both must be object or both incomplete. */ - if (comp_target_types (type0, type1, 1)) + if (comp_target_types (type0, type1)) result_type = common_pointer_type (type0, type1); else if (VOID_TYPE_P (tt0)) { @@ -7651,7 +7697,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, " with function pointer"); } else - pedwarn ("comparison of distinct pointer types lacks a cast"); + /* Avoid warning about the volatile ObjC EH puts on decls. */ + if (!objc_ok) + pedwarn ("comparison of distinct pointer types lacks a cast"); if (result_type == NULL_TREE) result_type = ptr_type_node; @@ -7684,7 +7732,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { - if (comp_target_types (type0, type1, 1)) + if (comp_target_types (type0, type1)) { result_type = common_pointer_type (type0, type1); if (!COMPLETE_TYPE_P (TREE_TYPE (type0))