diff options
Diffstat (limited to 'contrib/gcc/c-typeck.c')
-rw-r--r-- | contrib/gcc/c-typeck.c | 547 |
1 files changed, 267 insertions, 280 deletions
diff --git a/contrib/gcc/c-typeck.c b/contrib/gcc/c-typeck.c index 17e3144..21cc510 100644 --- a/contrib/gcc/c-typeck.c +++ b/contrib/gcc/c-typeck.c @@ -51,7 +51,7 @@ static int missing_braces_mentioned; static int undeclared_variable_notice; static tree qualify_type PARAMS ((tree, tree)); -static int comp_target_types PARAMS ((tree, tree)); +static int comp_target_types PARAMS ((tree, tree, int)); static int function_types_compatible_p PARAMS ((tree, tree)); static int type_lists_compatible_p PARAMS ((tree, tree)); static tree decl_constant_value_for_broken_optimization PARAMS ((tree)); @@ -73,7 +73,7 @@ static void push_array_bounds PARAMS ((int)); static int spelling_length PARAMS ((void)); static char *print_spelling PARAMS ((char *)); static void warning_init PARAMS ((const char *)); -static tree digest_init PARAMS ((tree, tree, int, int)); +static tree digest_init PARAMS ((tree, tree, int)); static void output_init_element PARAMS ((tree, tree, tree, int)); static void output_pending_init_elements PARAMS ((int)); static int set_designator PARAMS ((int)); @@ -99,7 +99,7 @@ require_complete_type (value) if (COMPLETE_TYPE_P (type)) return value; - incomplete_type_error (value, type); + c_incomplete_type_error (value, type); return error_mark_node; } @@ -108,7 +108,7 @@ require_complete_type (value) and TYPE is the type that was invalid. */ void -incomplete_type_error (value, type) +c_incomplete_type_error (value, type) tree value; tree type; { @@ -173,6 +173,28 @@ incomplete_type_error (value, type) } } +/* Given a type, apply default promotions wrt unnamed function + arguments and return the new type. */ + +tree +c_type_promotes_to (type) + tree type; +{ + if (TYPE_MAIN_VARIANT (type) == float_type_node) + return double_type_node; + + if (c_promoting_integer_type_p (type)) + { + /* Preserve unsignedness if not really getting any wider. */ + if (TREE_UNSIGNED (type) + && (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))) + return unsigned_type_node; + return integer_type_node; + } + + return type; +} + /* Return a variant of TYPE which has all the type qualifiers of LIKE as well as those of TYPE. */ @@ -216,9 +238,9 @@ common_type (t1, t2) /* Treat an enum type as the unsigned integer type of the same width. */ if (TREE_CODE (t1) == ENUMERAL_TYPE) - t1 = type_for_size (TYPE_PRECISION (t1), 1); + t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1); if (TREE_CODE (t2) == ENUMERAL_TYPE) - t2 = type_for_size (TYPE_PRECISION (t2), 1); + t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1); code1 = TREE_CODE (t1); code2 = TREE_CODE (t2); @@ -465,9 +487,9 @@ comptypes (type1, type2) signedness. */ if (TREE_CODE (t1) == ENUMERAL_TYPE) - t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1)); + t1 = c_common_type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1)); if (TREE_CODE (t2) == ENUMERAL_TYPE) - t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2)); + t2 = c_common_type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2)); if (t1 == t2) return 1; @@ -546,7 +568,7 @@ comptypes (type1, type2) } case RECORD_TYPE: - if (maybe_objc_comptypes (t1, t2, 0) == 1) + if (flag_objc && objc_comptypes (t1, t2, 0) == 1) val = 1; break; @@ -557,16 +579,21 @@ comptypes (type1, type2) } /* Return 1 if TTL and TTR are pointers to types that are equivalent, - ignoring their qualifiers. */ + 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). +*/ static int -comp_target_types (ttl, ttr) +comp_target_types (ttl, ttr, reflexive) tree ttl, ttr; + int reflexive; { int val; - /* Give maybe_objc_comptypes a crack at letting these types through. */ - if ((val = maybe_objc_comptypes (ttl, ttr, 1)) >= 0) + /* Give objc_comptypes a crack at letting these types through. */ + if ((val = objc_comptypes (ttl, ttr, reflexive)) >= 0) return val; val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)), @@ -658,12 +685,12 @@ type_lists_compatible_p (args1, args2) So match anything that self-promotes. */ if (TREE_VALUE (args1) == 0) { - if (simple_type_promotes_to (TREE_VALUE (args2)) != NULL_TREE) + if (c_type_promotes_to (TREE_VALUE (args2)) != TREE_VALUE (args2)) return 0; } else if (TREE_VALUE (args2) == 0) { - if (simple_type_promotes_to (TREE_VALUE (args1)) != NULL_TREE) + if (c_type_promotes_to (TREE_VALUE (args1)) != TREE_VALUE (args1)) return 0; } else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)), @@ -714,71 +741,6 @@ type_lists_compatible_p (args1, args2) } } -/* Compute the value of the `sizeof' operator. */ - -tree -c_sizeof (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree size; - - if (code == FUNCTION_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("sizeof applied to a function type"); - size = size_one_node; - } - else if (code == VOID_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("sizeof applied to a void type"); - size = size_one_node; - } - else if (code == ERROR_MARK) - size = size_one_node; - else if (!COMPLETE_TYPE_P (type)) - { - error ("sizeof applied to an incomplete type"); - size = size_zero_node; - } - else - /* Convert in case a char is more than one unit. */ - size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), - size_int (TYPE_PRECISION (char_type_node) - / BITS_PER_UNIT)); - - /* SIZE will have an integer type with TYPE_IS_SIZETYPE set. - TYPE_IS_SIZETYPE means that certain things (like overflow) will - never happen. However, this node should really have type - `size_t', which is just a typedef for an ordinary integer type. */ - return fold (build1 (NOP_EXPR, size_type_node, size)); -} - -tree -c_sizeof_nowarn (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree size; - - if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK) - size = size_one_node; - else if (!COMPLETE_TYPE_P (type)) - size = size_zero_node; - else - /* Convert in case a char is more than one unit. */ - size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), - size_int (TYPE_PRECISION (char_type_node) - / BITS_PER_UNIT)); - - /* SIZE will have an integer type with TYPE_IS_SIZETYPE set. - TYPE_IS_SIZETYPE means that certain things (like overflow) will - never happen. However, this node should really have type - `size_t', which is just a typedef for an ordinary integer type. */ - return fold (build1 (NOP_EXPR, size_type_node, size)); -} - /* Compute the size to increment a pointer by. */ tree @@ -932,7 +894,7 @@ default_function_array_conversion (exp) is not the target type of the type of the ADDR_EXPR itself. Question is, can this lossage be avoided? */ adr = build1 (ADDR_EXPR, ptrtype, exp); - if (mark_addressable (exp) == 0) + if (!c_mark_addressable (exp)) return error_mark_node; TREE_CONSTANT (adr) = staticp (exp); TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */ @@ -994,12 +956,11 @@ default_conversion (exp) but convert wide enums to something wider. */ if (code == ENUMERAL_TYPE) { - type = type_for_size (MAX (TYPE_PRECISION (type), - TYPE_PRECISION (integer_type_node)), - ((flag_traditional - || (TYPE_PRECISION (type) - >= TYPE_PRECISION (integer_type_node))) - && TREE_UNSIGNED (type))); + type = c_common_type_for_size (MAX (TYPE_PRECISION (type), + TYPE_PRECISION (integer_type_node)), + ((TYPE_PRECISION (type) + >= TYPE_PRECISION (integer_type_node)) + && TREE_UNSIGNED (type))); return convert (type, exp); } @@ -1010,26 +971,18 @@ default_conversion (exp) c_promoting_integer_type_p, otherwise leave it alone. */ && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)), TYPE_PRECISION (integer_type_node))) - return convert (flag_traditional && TREE_UNSIGNED (type) - ? unsigned_type_node : integer_type_node, - exp); + return convert (integer_type_node, exp); if (c_promoting_integer_type_p (type)) { - /* Traditionally, unsignedness is preserved in default promotions. - Also preserve unsignedness if not really getting any wider. */ + /* Preserve unsignedness if not really getting any wider. */ if (TREE_UNSIGNED (type) - && (flag_traditional - || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))) + && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) return convert (unsigned_type_node, exp); return convert (integer_type_node, exp); } - if (flag_traditional && !flag_allow_single_precision - && TYPE_MAIN_VARIANT (type) == float_type_node) - return convert (double_type_node, exp); - if (code == VOID_TYPE) { error ("void value not ignored as it ought to be"); @@ -1172,7 +1125,7 @@ build_component_ref (datum, component) { if (!COMPLETE_TYPE_P (type)) { - incomplete_type_error (NULL_TREE, type); + c_incomplete_type_error (NULL_TREE, type); return error_mark_node; } @@ -1191,7 +1144,7 @@ build_component_ref (datum, component) end does it - by giving the anonymous entities each a separate name and type, and then have build_component_ref recursively call itself. We can't do that here. */ - for (; field; field = TREE_CHAIN (field)) + do { tree subdatum = TREE_VALUE (field); @@ -1208,7 +1161,10 @@ build_component_ref (datum, component) warn_deprecated_use (subdatum); datum = ref; + + field = TREE_CHAIN (field); } + while (field); return ref; } @@ -1326,7 +1282,7 @@ build_array_ref (array, index) || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array))) && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST)) { - if (mark_addressable (array) == 0) + if (!c_mark_addressable (array)) return error_mark_node; } /* An array that is indexed by a constant value which is not within @@ -1337,7 +1293,7 @@ build_array_ref (array, index) && TYPE_VALUES (TREE_TYPE (array)) && ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array)))) { - if (mark_addressable (array) == 0) + if (!c_mark_addressable (array)) return error_mark_node; } @@ -1349,7 +1305,7 @@ build_array_ref (array, index) if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)) pedwarn ("ISO C forbids subscripting `register' array"); else if (! flag_isoc99 && ! lvalue_p (foo)) - pedwarn ("ISO C89 forbids subscripting non-lvalue array"); + pedwarn ("ISO C90 forbids subscripting non-lvalue array"); } type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array))); @@ -1502,6 +1458,17 @@ build_external_ref (id, fun) ref = DECL_INITIAL (ref); TREE_CONSTANT (ref) = 1; } + else if (current_function_decl != 0 + && DECL_CONTEXT (current_function_decl) != 0 + && (TREE_CODE (ref) == VAR_DECL + || TREE_CODE (ref) == PARM_DECL + || TREE_CODE (ref) == FUNCTION_DECL)) + { + tree context = decl_function_context (ref); + + if (context != 0 && context != current_function_decl) + DECL_NONLOCAL (ref) = 1; + } return ref; } @@ -1564,10 +1531,9 @@ build_function_call (function, params) coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl); - /* Check for errors in format strings. */ + /* Check that the arguments to the function are valid. */ - if (warn_format) - check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params); + check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params); /* Recognize certain built-in functions so we can make tree-codes other than CALL_EXPR. We do this when it enables fold-const.c @@ -2011,7 +1977,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) /* 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)) + && comp_target_types (type0, type1, 1)) return pointer_diff (op0, op1); /* Handle pointer minus int. Just like pointer plus int. */ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) @@ -2035,9 +2001,9 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) warning ("division by zero"); if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) + || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) + || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) { if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)) resultcode = RDIV_EXPR; @@ -2060,6 +2026,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) case BIT_XOR_EXPR: if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) shorten = -1; + else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE) + common = 1; break; case TRUNC_MOD_EXPR: @@ -2094,8 +2062,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) but that does not mean the operands should be converted to ints! */ result_type = integer_type_node; - op0 = truthvalue_conversion (op0); - op1 = truthvalue_conversion (op1); + op0 = c_common_truthvalue_conversion (op0); + op1 = c_common_truthvalue_conversion (op1); converted = 1; } break; @@ -2121,18 +2089,14 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) } } - /* Use the type of the value to be shifted. - This is what most traditional C compilers do. */ + /* Use the type of the value to be shifted. */ result_type = type0; - /* Unless traditional, convert the shift-count to an integer, - regardless of size of value being shifted. */ - if (! flag_traditional) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } + /* Convert the shift-count to an integer, regardless of size + of value being shifted. */ + if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) + op1 = convert (integer_type_node, op1); + /* Avoid converting op1 to result_type later. */ + converted = 1; } break; @@ -2148,18 +2112,14 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) warning ("left shift count >= width of type"); } - /* Use the type of the value to be shifted. - This is what most traditional C compilers do. */ + /* Use the type of the value to be shifted. */ result_type = type0; - /* Unless traditional, convert the shift-count to an integer, - regardless of size of value being shifted. */ - if (! flag_traditional) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } + /* Convert the shift-count to an integer, regardless of size + of value being shifted. */ + if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) + op1 = convert (integer_type_node, op1); + /* Avoid converting op1 to result_type later. */ + converted = 1; } break; @@ -2175,18 +2135,14 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) warning ("shift count >= width of type"); } - /* Use the type of the value to be shifted. - This is what most traditional C compilers do. */ + /* Use the type of the value to be shifted. */ result_type = type0; - /* Unless traditional, convert the shift-count to an integer, - regardless of size of value being shifted. */ - if (! flag_traditional) - { - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } + /* Convert the shift-count to an integer, regardless of size + of value being shifted. */ + if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) + op1 = convert (integer_type_node, op1); + /* Avoid converting op1 to result_type later. */ + converted = 1; } break; @@ -2198,9 +2154,11 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) but don't convert the args to int! */ build_type = integer_type_node; if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) + || code0 == COMPLEX_TYPE + || code0 == VECTOR_TYPE) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) + || code1 == COMPLEX_TYPE + || code1 == VECTOR_TYPE)) short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { @@ -2209,7 +2167,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) /* 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)) + if (comp_target_types (type0, type1, 1)) result_type = common_type (type0, type1); else if (VOID_TYPE_P (tt0)) { @@ -2240,14 +2198,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); + pedwarn ("comparison between pointer and integer"); } else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) { result_type = type1; - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); + pedwarn ("comparison between pointer and integer"); } break; @@ -2258,7 +2214,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) shorten = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { - if (comp_target_types (type0, type1)) + if (comp_target_types (type0, type1, 1)) { result_type = common_type (type0, type1); if (pedantic @@ -2283,7 +2239,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { - if (comp_target_types (type0, type1)) + if (comp_target_types (type0, type1, 1)) { result_type = common_type (type0, type1); if (!COMPLETE_TYPE_P (TREE_TYPE (type0)) @@ -2316,14 +2272,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); + pedwarn ("comparison between pointer and integer"); } else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) { result_type = type1; - if (! flag_traditional) - pedwarn ("comparison between pointer and integer"); + pedwarn ("comparison between pointer and integer"); } break; @@ -2347,9 +2301,11 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) break; } - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) + if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE + || code0 == VECTOR_TYPE) && - (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) + (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE + || code1 == VECTOR_TYPE)) { int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE); @@ -2411,22 +2367,24 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) && unsigned0 == unsigned1 && (unsigned0 || !uns)) result_type - = signed_or_unsigned_type (unsigned0, - common_type (TREE_TYPE (arg0), TREE_TYPE (arg1))); + = c_common_signed_or_unsigned_type + (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1))); else if (TREE_CODE (arg0) == INTEGER_CST && (unsigned1 || !uns) && (TYPE_PRECISION (TREE_TYPE (arg1)) < TYPE_PRECISION (result_type)) - && (type = signed_or_unsigned_type (unsigned1, - TREE_TYPE (arg1)), + && (type + = c_common_signed_or_unsigned_type (unsigned1, + TREE_TYPE (arg1)), int_fits_type_p (arg0, type))) result_type = type; else if (TREE_CODE (arg1) == INTEGER_CST && (unsigned0 || !uns) && (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)) - && (type = signed_or_unsigned_type (unsigned0, - TREE_TYPE (arg0)), + && (type + = c_common_signed_or_unsigned_type (unsigned0, + TREE_TYPE (arg0)), int_fits_type_p (arg1, type))) result_type = type; } @@ -2452,7 +2410,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) { /* Do an unsigned shift if the operand was zero-extended. */ result_type - = signed_or_unsigned_type (unsigned_arg, TREE_TYPE (arg0)); + = c_common_signed_or_unsigned_type (unsigned_arg, + TREE_TYPE (arg0)); /* Convert value-to-be-shifted to that type. */ if (TREE_TYPE (op0) != result_type) op0 = convert (result_type, op0); @@ -2523,22 +2482,24 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) constant expression involving such literals or a conditional expression involving such literals) and it is non-negative. */ - if (tree_expr_nonnegative_p (sop)) + if (c_tree_expr_nonnegative_p (sop)) /* OK */; /* Do not warn if the comparison is an equality operation, the unsigned quantity is an integral constant, and it would fit in the result if the result were signed. */ else if (TREE_CODE (uop) == INTEGER_CST && (resultcode == EQ_EXPR || resultcode == NE_EXPR) - && int_fits_type_p (uop, signed_type (result_type))) + && int_fits_type_p + (uop, c_common_signed_type (result_type))) /* OK */; /* Do not warn if the unsigned quantity is an enumeration constant and its maximum value would fit in the result if the result were signed. */ else if (TREE_CODE (uop) == INTEGER_CST && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE - && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE(uop)), - signed_type (result_type))) + && int_fits_type_p + (TYPE_MAX_VALUE (TREE_TYPE(uop)), + c_common_signed_type (result_type))) /* OK */; else warning ("comparison between signed and unsigned"); @@ -2637,6 +2598,27 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) } } + +/* Return true if `t' is known to be non-negative. */ + +int +c_tree_expr_nonnegative_p (t) + tree t; +{ + if (TREE_CODE (t) == STMT_EXPR) + { + t=COMPOUND_BODY (STMT_EXPR_STMT (t)); + + /* Find the last statement in the chain, ignoring the final + * scope statement */ + while (TREE_CHAIN (t) != NULL_TREE + && TREE_CODE (TREE_CHAIN (t)) != SCOPE_STMT) + t=TREE_CHAIN (t); + return tree_expr_nonnegative_p (TREE_OPERAND (t, 0)); + } + return tree_expr_nonnegative_p (t); +} + /* Return a tree for the difference of pointers OP0 and OP1. The resulting tree has type int. */ @@ -2758,11 +2740,13 @@ build_unary_op (code, xarg, flag) } else if (!noconvert) arg = default_conversion (arg); + arg = non_lvalue (arg); break; case NEGATE_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE - || typecode == COMPLEX_TYPE)) + || typecode == COMPLEX_TYPE + || typecode == VECTOR_TYPE)) { error ("wrong type argument to unary minus"); return error_mark_node; @@ -2772,7 +2756,12 @@ build_unary_op (code, xarg, flag) break; case BIT_NOT_EXPR: - if (typecode == COMPLEX_TYPE) + if (typecode == INTEGER_TYPE || typecode == VECTOR_TYPE) + { + if (!noconvert) + arg = default_conversion (arg); + } + else if (typecode == COMPLEX_TYPE) { code = CONJ_EXPR; if (pedantic) @@ -2780,13 +2769,11 @@ build_unary_op (code, xarg, flag) if (!noconvert) arg = default_conversion (arg); } - else if (typecode != INTEGER_TYPE) + else { error ("wrong type argument to bit-complement"); return error_mark_node; } - else if (!noconvert) - arg = default_conversion (arg); break; case ABS_EXPR: @@ -2822,7 +2809,7 @@ build_unary_op (code, xarg, flag) error ("wrong type argument to unary exclamation mark"); return error_mark_node; } - arg = truthvalue_conversion (arg); + arg = c_common_truthvalue_conversion (arg); return invert_truthvalue (arg); case NOP_EXPR: @@ -2888,6 +2875,9 @@ build_unary_op (code, xarg, flag) tree inc; tree result_type = TREE_TYPE (arg); + arg = get_unwidened (arg, 0); + argtype = TREE_TYPE (arg); + /* Compute the increment. */ if (typecode == POINTER_TYPE) @@ -2916,9 +2906,6 @@ build_unary_op (code, xarg, flag) else inc = integer_one_node; - arg = get_unwidened (arg, 0); - argtype = TREE_TYPE (arg); - inc = convert (argtype, inc); /* Handle incrementing a cast-expression. */ @@ -3012,7 +2999,7 @@ build_unary_op (code, xarg, flag) /* For &x[y], return x+y */ if (TREE_CODE (arg) == ARRAY_REF) { - if (mark_addressable (TREE_OPERAND (arg, 0)) == 0) + if (!c_mark_addressable (TREE_OPERAND (arg, 0))) return error_mark_node; return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1), 1); @@ -3067,7 +3054,7 @@ build_unary_op (code, xarg, flag) argtype = build_pointer_type (argtype); - if (mark_addressable (arg) == 0) + if (!c_mark_addressable (arg)) return error_mark_node; { @@ -3286,13 +3273,14 @@ readonly_warning (arg, msgid) /* Mark EXP saying that we need to be able to take the address of it; it should not be allocated in a register. - Value is 1 if successful. */ + Returns true if successful. */ -int -mark_addressable (exp) +bool +c_mark_addressable (exp) tree exp; { tree x = exp; + while (1) switch (TREE_CODE (x)) { @@ -3301,7 +3289,7 @@ mark_addressable (exp) { error ("cannot take address of bit-field `%s'", IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1)))); - return 0; + return false; } /* ... fall through ... */ @@ -3316,7 +3304,7 @@ mark_addressable (exp) case COMPOUND_LITERAL_EXPR: case CONSTRUCTOR: TREE_ADDRESSABLE (x) = 1; - return 1; + return true; case VAR_DECL: case CONST_DECL: @@ -3329,7 +3317,7 @@ mark_addressable (exp) { error ("global register variable `%s' used in nested function", IDENTIFIER_POINTER (DECL_NAME (x))); - return 0; + return false; } pedwarn ("register variable `%s' used in nested function", IDENTIFIER_POINTER (DECL_NAME (x))); @@ -3340,7 +3328,7 @@ mark_addressable (exp) { error ("address of global register variable `%s' requested", IDENTIFIER_POINTER (DECL_NAME (x))); - return 0; + return false; } /* If we are making this addressable due to its having @@ -3351,13 +3339,13 @@ mark_addressable (exp) else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x))) { error ("cannot put object with volatile field into register"); - return 0; + return false; } pedwarn ("address of register variable `%s' requested", IDENTIFIER_POINTER (DECL_NAME (x))); } - put_var_into_stack (x); + put_var_into_stack (x, /*rescan=*/true); /* drops in */ case FUNCTION_DECL: @@ -3368,7 +3356,7 @@ mark_addressable (exp) #endif default: - return 1; + return true; } } @@ -3385,7 +3373,7 @@ build_conditional_expr (ifexp, op1, op2) tree result_type = NULL; tree orig_op1 = op1, orig_op2 = op2; - ifexp = truthvalue_conversion (default_conversion (ifexp)); + ifexp = c_common_truthvalue_conversion (default_conversion (ifexp)); #if 0 /* Produces wrong result if within sizeof. */ /* Don't promote the operands separately if they promote @@ -3458,8 +3446,8 @@ build_conditional_expr (ifexp, op1, op2) /* Do not warn if the signed quantity is an unsuffixed integer literal (or some static constant expression involving such literals) and it is non-negative. */ - else if ((unsigned_op2 && tree_expr_nonnegative_p (op1)) - || (unsigned_op1 && tree_expr_nonnegative_p (op2))) + else if ((unsigned_op2 && c_tree_expr_nonnegative_p (op1)) + || (unsigned_op1 && c_tree_expr_nonnegative_p (op2))) /* OK */; else warning ("signed and unsigned type in conditional expression"); @@ -3474,7 +3462,7 @@ build_conditional_expr (ifexp, op1, op2) } else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) { - if (comp_target_types (type1, type2)) + if (comp_target_types (type1, type2, 1)) result_type = common_type (type1, type2); else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node && TREE_CODE (orig_op1) != NOP_EXPR) @@ -3629,7 +3617,12 @@ build_c_cast (type, expr) if (type == error_mark_node || expr == error_mark_node) return error_mark_node; - type = TYPE_MAIN_VARIANT (type); + + /* The ObjC front-end uses TYPE_MAIN_VARIANT to tie together types differing + only in <protocol> qualifications. But when constructing cast expressions, + the protocols do matter and must be kept around. */ + if (!flag_objc || !objc_is_id (type)) + type = TYPE_MAIN_VARIANT (type); #if 0 /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ @@ -3685,8 +3678,7 @@ build_c_cast (type, expr) else name = ""; t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE, - build_tree_list (field, value)), - 0, 0); + build_tree_list (field, value)), 0); TREE_CONSTANT (t) = TREE_CONSTANT (value); return t; } @@ -3781,6 +3773,23 @@ build_c_cast (type, expr) && !TREE_CONSTANT (value)) warning ("cast to pointer from integer of different size"); + if (TREE_CODE (type) == POINTER_TYPE + && TREE_CODE (otype) == POINTER_TYPE + && TREE_CODE (expr) == ADDR_EXPR + && DECL_P (TREE_OPERAND (expr, 0)) + && flag_strict_aliasing && warn_strict_aliasing + && !VOID_TYPE_P (TREE_TYPE (type))) + { + /* Casting the address of a decl to non void pointer. Warn + if the cast breaks type based aliasing. */ + if (!COMPLETE_TYPE_P (TREE_TYPE (type))) + warning ("type-punning to incomplete type might break strict-aliasing rules"); + else if (!alias_sets_conflict_p + (get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0))), + get_alias_set (TREE_TYPE (type)))) + warning ("dereferencing type-punned pointer will break strict-aliasing rules"); + } + ovalue = value; value = convert (type, value); @@ -4037,9 +4046,11 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) { overflow_warning (rhs); - /* Check for Objective-C protocols. This will issue a warning if - there are protocol violations. No need to use the return value. */ - maybe_objc_comptypes (type, rhstype, 0); + /* Check for Objective-C protocols. This will automatically + issue a warning if there are protocol violations. No need to + use the return value. */ + if (flag_objc) + objc_comptypes (type, rhstype, 0); return rhs; } @@ -4054,7 +4065,12 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) if (codel == REFERENCE_TYPE && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1) { - if (mark_addressable (rhs) == 0) + if (!lvalue_p (rhs)) + { + error ("cannot pass rvalue to reference parameter"); + return error_mark_node; + } + if (!c_mark_addressable (rhs)) return error_mark_node; rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs); @@ -4073,7 +4089,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) else if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE || codel == BOOLEAN_TYPE) - && (coder == INTEGER_TYPE || coder == REAL_TYPE + && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE || coder == BOOLEAN_TYPE)) return convert_and_check (type, rhs); @@ -4107,7 +4123,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) 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)) + || comp_target_types (memb_type, rhstype, 0)) { /* If this type won't generate any warnings, use it. */ if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr) @@ -4173,7 +4189,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) /* Conversions among pointers */ else if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE) - && (coder == POINTER_TYPE || coder == REFERENCE_TYPE)) + && (coder == codel)) { tree ttl = TREE_TYPE (type); tree ttr = TREE_TYPE (rhstype); @@ -4182,9 +4198,9 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) 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) - || comp_target_types (type, rhstype) - || (unsigned_type (TYPE_MAIN_VARIANT (ttl)) - == unsigned_type (TYPE_MAIN_VARIANT (ttr)))) + || comp_target_types (type, rhstype, 0) + || (c_common_unsigned_type (TYPE_MAIN_VARIANT (ttl)) + == c_common_unsigned_type (TYPE_MAIN_VARIANT (ttr)))) { if (pedantic && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE) @@ -4207,7 +4223,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) /* If this is not a case of ignoring a mismatch in signedness, no warning. */ else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr) - || comp_target_types (type, rhstype)) + || comp_target_types (type, rhstype, 0)) ; /* If there is a mismatch, do warn. */ else if (pedantic) @@ -4262,7 +4278,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) { if (funname) { - tree selector = maybe_building_objc_message_expr (); + tree selector = objc_message_selector (); if (selector && parmnum > 2) error ("incompatible type for argument %d of `%s'", @@ -4307,7 +4323,8 @@ c_convert_parm_for_inlining (parm, value, fn) /* Print a warning using MSGID. It gets OPNAME as its one parameter. - If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'". + if OPNAME is null and ARGNUM is 0, it is replaced by "passing arg of `FUNCTION'". + Otherwise if OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'". FUNCTION and ARGNUM are handled specially if we are building an Objective-C selector. */ @@ -4320,7 +4337,7 @@ warn_for_assignment (msgid, opname, function, argnum) { if (opname == 0) { - tree selector = maybe_building_objc_message_expr (); + tree selector = objc_message_selector (); char * new_opname; if (selector && argnum > 2) @@ -4328,7 +4345,27 @@ warn_for_assignment (msgid, opname, function, argnum) function = selector; argnum -= 2; } - if (function) + if (argnum == 0) + { + if (function) + { + /* Function name is known; supply it. */ + const char *const argstring = _("passing arg of `%s'"); + new_opname = (char *) alloca (IDENTIFIER_LENGTH (function) + + strlen (argstring) + 1 + + 1); + sprintf (new_opname, argstring, + IDENTIFIER_POINTER (function)); + } + else + { + /* Function name unknown (call through ptr). */ + const char *const argnofun = _("passing arg of pointer to function"); + new_opname = (char *) alloca (strlen (argnofun) + 1 + 1); + sprintf (new_opname, argnofun); + } + } + else if (function) { /* Function name is known; supply it. */ const char *const argstring = _("passing arg %d of `%s'"); @@ -4395,8 +4432,7 @@ store_init_value (decl, init) /* Digest the specified initializer into an expression. */ - value = digest_init (type, init, TREE_STATIC (decl), - TREE_STATIC (decl) || (pedantic && !flag_isoc99)); + value = digest_init (type, init, TREE_STATIC (decl)); /* Store the expression if valid; else report error. */ @@ -4496,15 +4532,6 @@ static int spelling_size; /* Size of the spelling stack. */ #define SPELLING_DEPTH() (spelling - spelling_base) #define RESTORE_SPELLING_DEPTH(DEPTH) (spelling = spelling_base + (DEPTH)) -/* Save and restore the spelling stack around arbitrary C code. */ - -#define SAVE_SPELLING_DEPTH(code) \ -{ \ - int __depth = SPELLING_DEPTH (); \ - code; \ - RESTORE_SPELLING_DEPTH (__depth); \ -} - /* Push an element on the spelling stack with type KIND and assign VALUE to MEMBER. */ @@ -4657,14 +4684,13 @@ warning_init (msgid) /* Digest the parser output INIT as an initializer for type TYPE. Return a C expression of type TYPE to represent the initial value. - The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors - if non-constant initializers or elements are seen. CONSTRUCTOR_CONSTANT - applies only to elements of constructors. */ + REQUIRE_CONSTANT requests an error if non-constant initializers or + elements are seen. */ static tree -digest_init (type, init, require_constant, constructor_constant) +digest_init (type, init, require_constant) tree type, init; - int require_constant, constructor_constant; + int require_constant; { enum tree_code code = TREE_CODE (type); tree inside_init = init; @@ -4843,44 +4869,6 @@ digest_init (type, init, require_constant, constructor_constant) return error_mark_node; } - /* Traditionally, you can write struct foo x = 0; - and it initializes the first element of x to 0. */ - if (flag_traditional) - { - tree top = 0, prev = 0, otype = type; - while (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == ARRAY_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE - || TREE_CODE (type) == UNION_TYPE) - { - tree temp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); - if (prev == 0) - top = temp; - else - TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, temp); - prev = temp; - if (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - else if (TYPE_FIELDS (type)) - type = TREE_TYPE (TYPE_FIELDS (type)); - else - { - error_init ("invalid initializer"); - return error_mark_node; - } - } - - if (otype != type) - { - TREE_OPERAND (prev, 1) - = build_tree_list (NULL_TREE, - digest_init (type, init, require_constant, - constructor_constant)); - return top; - } - else - return error_mark_node; - } error_init ("invalid initializer"); return error_mark_node; } @@ -5240,7 +5228,7 @@ really_start_incremental_init (type) constructor_max_index = build_int_2 (-1, -1); /* constructor_max_index needs to be an INTEGER_CST. Attempts - to initialize VLAs will cause an proper error; avoid tree + to initialize VLAs will cause a proper error; avoid tree checking errors as well by setting a safe value. */ if (constructor_max_index && TREE_CODE (constructor_max_index) != INTEGER_CST) @@ -5260,7 +5248,7 @@ really_start_incremental_init (type) /* Vectors are like simple fixed-size arrays. */ constructor_max_index = build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0); - constructor_index = convert (bitsizetype, integer_zero_node); + constructor_index = convert (bitsizetype, bitsize_zero_node); constructor_unfilled_index = constructor_index; } else @@ -5292,6 +5280,7 @@ push_init_level (implicit) && 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 @@ -5430,7 +5419,7 @@ push_init_level (implicit) constructor_max_index = build_int_2 (-1, -1); /* constructor_max_index needs to be an INTEGER_CST. Attempts - to initialize VLAs will cause an proper error; avoid tree + to initialize VLAs will cause a proper error; avoid tree checking errors as well by setting a safe value. */ if (constructor_max_index && TREE_CODE (constructor_max_index) != INTEGER_CST) @@ -5619,7 +5608,7 @@ pop_init_level (implicit) } /* Common handling for both array range and field name designators. - ARRAY argument is non-zero for array ranges. Returns zero for success. */ + ARRAY argument is nonzero for array ranges. Returns zero for success. */ static int set_designator (array) @@ -6277,8 +6266,7 @@ output_init_element (value, type, field, pending) || TREE_CHAIN (field))))) return; - value = digest_init (type, value, require_constant_value, - require_constant_elements); + value = digest_init (type, value, require_constant_value); if (value == error_mark_node) { constructor_erroneous = 1; @@ -6889,12 +6877,9 @@ simple_asm_stmt (expr) { tree stmt; - if (TREE_CHAIN (expr)) - expr = combine_strings (expr); - /* Simple asm statements are treated as volatile. */ stmt = add_stmt (build_stmt (ASM_STMT, ridpointers[(int) RID_VOLATILE], - expr, NULL_TREE, NULL_TREE, NULL_TREE)); + expr, NULL_TREE, NULL_TREE, NULL_TREE)); ASM_INPUT_P (stmt) = 1; return stmt; } @@ -6916,8 +6901,6 @@ build_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers) { tree tail; - if (TREE_CHAIN (string)) - string = combine_strings (string); if (TREE_CODE (string) != STRING_CST) { error ("asm template is not a string constant"); @@ -6994,7 +6977,11 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) /* Record the contents of OUTPUTS before it is modified. */ for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) - o[i] = TREE_VALUE (tail); + { + o[i] = TREE_VALUE (tail); + if (o[i] == error_mark_node) + return; + } /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of OUTPUTS some trees for where the values were actually stored. */ |