X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fc-typeck.c;h=4b9b2b30d00c88396a359173c63e9d035cea0616;hp=23880d16a4377c442792405dab0d1b8e0a3eba82;hb=e7e7c0fe7891322de1bb0a8991ce4b04856f2f28;hpb=fd6481cf2e4413bca3ef43b1e504e1c78de6025d diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 23880d16a43..4b9b2b30d00 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1,6 +1,6 @@ /* Build expressions with type checking for C compiler. Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -42,14 +42,13 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "target.h" #include "tree-iterator.h" -#include "tree-gimple.h" +#include "gimple.h" #include "tree-flow.h" /* Possible cases of implicit bad conversions. Used to select diagnostic messages in convert_for_assignment. */ enum impl_conv { ic_argpass, - ic_argpass_nonproto, ic_assign, ic_init, ic_return @@ -93,11 +92,11 @@ static int spelling_length (void); static char *print_spelling (char *); static void warning_init (int, const char *); static tree digest_init (tree, tree, bool, int); -static void output_init_element (tree, bool, tree, tree, int); +static void output_init_element (tree, bool, tree, tree, int, bool); static void output_pending_init_elements (int); static int set_designator (int); static void push_range_stack (tree); -static void add_pending_init (tree, tree); +static void add_pending_init (tree, tree, bool); static void set_nonincremental_init (void); static void set_nonincremental_init_from_string (tree); static tree find_init_member (tree); @@ -470,8 +469,8 @@ composite_type (tree t1, tree t2) { TREE_VALUE (n) = composite_type (TREE_TYPE (memb), TREE_VALUE (p2)); - if (pedantic) - pedwarn ("function types not truly compatible in ISO C"); + pedwarn (input_location, OPT_pedantic, + "function types not truly compatible in ISO C"); goto parm_done; } } @@ -495,8 +494,8 @@ composite_type (tree t1, tree t2) { TREE_VALUE (n) = composite_type (TREE_TYPE (memb), TREE_VALUE (p1)); - if (pedantic) - pedwarn ("function types not truly compatible in ISO C"); + pedwarn (input_location, OPT_pedantic, + "function types not truly compatible in ISO C"); goto parm_done; } } @@ -722,7 +721,7 @@ c_common_type (tree t1, tree t2) signed type. */ if (code1 == FIXED_POINT_TYPE && TYPE_UNSIGNED (t1)) { - unsigned char mclass = 0; + enum mode_class mclass = (enum mode_class) 0; if (GET_MODE_CLASS (m1) == MODE_UFRACT) mclass = MODE_FRACT; else if (GET_MODE_CLASS (m1) == MODE_UACCUM) @@ -733,7 +732,7 @@ c_common_type (tree t1, tree t2) } if (code2 == FIXED_POINT_TYPE && TYPE_UNSIGNED (t2)) { - unsigned char mclass = 0; + enum mode_class mclass = (enum mode_class) 0; if (GET_MODE_CLASS (m2) == MODE_UFRACT) mclass = MODE_FRACT; else if (GET_MODE_CLASS (m2) == MODE_UACCUM) @@ -1039,8 +1038,8 @@ comp_target_types (tree ttl, tree ttr) mvr = TYPE_MAIN_VARIANT (mvr); val = comptypes (mvl, mvr); - if (val == 2 && pedantic) - pedwarn ("types are not quite compatible"); + if (val == 2) + pedwarn (input_location, OPT_pedantic, "types are not quite compatible"); return val; } @@ -1363,7 +1362,7 @@ function_types_compatible_p (const_tree f1, const_tree f2) /* 'volatile' qualifiers on a function's return type used to mean the function is noreturn. */ if (TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2)) - pedwarn ("function return types not compatible due to %"); + pedwarn (input_location, 0, "function return types not compatible due to %"); if (TYPE_VOLATILE (ret1)) ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1), TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE); @@ -1618,7 +1617,7 @@ array_to_pointer_conversion (tree exp) /* This way is better for a COMPONENT_REF since it can simplify the offset for a component. */ - adr = build_unary_op (ADDR_EXPR, exp, 1); + adr = build_unary_op (EXPR_LOCATION (exp), ADDR_EXPR, exp, 1); return convert (ptrtype, adr); } @@ -1635,7 +1634,7 @@ function_to_pointer_conversion (tree exp) if (TREE_NO_WARNING (orig_exp)) TREE_NO_WARNING (exp) = 1; - return build_unary_op (ADDR_EXPR, exp, 0); + return build_unary_op (EXPR_LOCATION (exp), ADDR_EXPR, exp, 0); } /* Perform the default conversion of arrays and functions to pointers. @@ -1967,13 +1966,16 @@ build_component_ref (tree datum, tree component) /* Given an expression PTR for a pointer, return an expression for the value pointed to. - ERRORSTRING is the name of the operator to appear in error messages. */ + ERRORSTRING is the name of the operator to appear in error messages. + + LOC is the location to use for the generated tree. */ tree -build_indirect_ref (tree ptr, const char *errorstring) +build_indirect_ref (location_t loc, tree ptr, const char *errorstring) { tree pointer = default_conversion (ptr); tree type = TREE_TYPE (pointer); + tree ref; if (TREE_CODE (type) == POINTER_TYPE) { @@ -1992,21 +1994,24 @@ build_indirect_ref (tree ptr, const char *errorstring) if (TREE_CODE (pointer) == ADDR_EXPR && (TREE_TYPE (TREE_OPERAND (pointer, 0)) == TREE_TYPE (type))) - return TREE_OPERAND (pointer, 0); + { + ref = TREE_OPERAND (pointer, 0); + protected_set_expr_location (ref, loc); + return ref; + } else { tree t = TREE_TYPE (type); - tree ref; ref = build1 (INDIRECT_REF, t, pointer); if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE) { - error ("dereferencing pointer to incomplete type"); + error_at (loc, "dereferencing pointer to incomplete type"); return error_mark_node; } if (VOID_TYPE_P (t) && skip_evaluation == 0) - warning (0, "dereferencing % pointer"); + warning_at (loc, 0, "dereferencing % pointer"); /* We *must* set TREE_READONLY when dereferencing a pointer to const, so that we get the proper error message if the result is used @@ -2019,11 +2024,13 @@ build_indirect_ref (tree ptr, const char *errorstring) TREE_SIDE_EFFECTS (ref) = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer); TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t); + protected_set_expr_location (ref, loc); return ref; } } else if (TREE_CODE (pointer) != ERROR_MARK) - error ("invalid type argument of %qs (have %qT)", errorstring, type); + error_at (loc, + "invalid type argument of %qs (have %qT)", errorstring, type); return error_mark_node; } @@ -2034,11 +2041,14 @@ build_indirect_ref (tree ptr, const char *errorstring) If A is a variable or a member, we generate a primitive ARRAY_REF. This avoids forcing the array out of registers, and can work on arrays that are not lvalues (for example, members of structures returned - by functions). */ + by functions). + + LOC is the location to use for the returned expression. */ tree -build_array_ref (tree array, tree index) +build_array_ref (tree array, tree index, location_t loc) { + tree ret; bool swapped = false; if (TREE_TYPE (array) == error_mark_node || TREE_TYPE (index) == error_mark_node) @@ -2051,7 +2061,7 @@ build_array_ref (tree array, tree index) if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE) { - error ("subscripted value is neither array nor pointer"); + error_at (loc, "subscripted value is neither array nor pointer"); return error_mark_node; } temp = array; @@ -2062,13 +2072,13 @@ build_array_ref (tree array, tree index) if (!INTEGRAL_TYPE_P (TREE_TYPE (index))) { - error ("array subscript is not an integer"); + error_at (loc, "array subscript is not an integer"); return error_mark_node; } if (TREE_CODE (TREE_TYPE (TREE_TYPE (array))) == FUNCTION_TYPE) { - error ("subscripted value is pointer to function"); + error_at (loc, "subscripted value is pointer to function"); return error_mark_node; } @@ -2115,9 +2125,11 @@ build_array_ref (tree array, tree index) while (TREE_CODE (foo) == COMPONENT_REF) foo = TREE_OPERAND (foo, 0); if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo)) - pedwarn ("ISO C forbids subscripting % array"); + pedwarn (loc, OPT_pedantic, + "ISO C forbids subscripting % array"); else if (!flag_isoc99 && !lvalue_p (foo)) - pedwarn ("ISO C90 forbids subscripting non-lvalue array"); + pedwarn (loc, OPT_pedantic, + "ISO C90 forbids subscripting non-lvalue array"); } type = TREE_TYPE (TREE_TYPE (array)); @@ -2137,7 +2149,9 @@ build_array_ref (tree array, tree index) in an inline function. Hope it doesn't break something else. */ | TREE_THIS_VOLATILE (array)); - return require_complete_type (fold (rval)); + ret = require_complete_type (fold (rval)); + protected_set_expr_location (ret, loc); + return ret; } else { @@ -2149,8 +2163,9 @@ build_array_ref (tree array, tree index) gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE); gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE); - return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, index, 0), - "array indexing"); + return build_indirect_ref + (loc, build_binary_op (loc, PLUS_EXPR, ar, index, 0), + "array indexing"); } } @@ -2191,8 +2206,6 @@ build_external_ref (tree id, int fun, location_t loc) /* Recursive call does not count as usage. */ if (ref != current_function_decl) { - if (!skip_evaluation) - assemble_external (ref); TREE_USED (ref) = 1; } @@ -2233,8 +2246,8 @@ build_external_ref (tree id, int fun, location_t loc) && (TREE_CODE (ref) != VAR_DECL || TREE_STATIC (ref)) && ! TREE_PUBLIC (ref) && DECL_CONTEXT (ref) != current_function_decl) - pedwarn ("%H%qD is static but used in inline function %qD " - "which is not static", &loc, ref, current_function_decl); + pedwarn (loc, 0, "%qD is static but used in inline function %qD " + "which is not static", ref, current_function_decl); return ref; } @@ -2408,11 +2421,10 @@ build_function_call (tree function, tree params) /* This situation leads to run-time undefined behavior. We can't, therefore, simply error unless we can prove that all possible executions of the program must execute the code. */ - warning (0, "function called through a non-compatible type"); - - /* We can, however, treat "undefined" any way we please. - Call abort to encourage the user to fix the program. */ - inform ("if this code is reached, the program will abort"); + if (warning (0, "function called through a non-compatible type")) + /* We can, however, treat "undefined" any way we please. + Call abort to encourage the user to fix the program. */ + inform (input_location, "if this code is reached, the program will abort"); if (VOID_TYPE_P (return_type)) return trap; @@ -2458,7 +2470,7 @@ build_function_call (tree function, tree params) if (TREE_CONSTANT (result) && (name == NULL_TREE || strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0)) - pedwarn_init ("initializer element is not constant"); + pedwarn_init (input_location, 0, "initializer element is not constant"); } else result = fold_build_call_array (TREE_TYPE (fntype), @@ -2725,15 +2737,18 @@ convert_arguments (int nargs, tree *argarray, /* This is the entry point used by the parser to build unary operators in the input. CODE, a tree_code, specifies the unary operator, and ARG is the operand. For unary plus, the C parser currently uses - CONVERT_EXPR for code. */ + CONVERT_EXPR for code. + + LOC is the location to use for the tree generated. +*/ struct c_expr -parser_build_unary_op (enum tree_code code, struct c_expr arg) +parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc) { struct c_expr result; - result.original_code = ERROR_MARK; - result.value = build_unary_op (code, arg.value, 0); + result.value = build_unary_op (loc, code, arg.value, 0); + result.original_code = code; if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value)) overflow_warning (result.value); @@ -2745,29 +2760,35 @@ parser_build_unary_op (enum tree_code code, struct c_expr arg) in the input. CODE, a tree_code, specifies the binary operator, and ARG1 and ARG2 are the operands. In addition to constructing the expression, we check for operands that were written with other binary - operators in a way that is likely to confuse the user. */ + operators in a way that is likely to confuse the user. + + LOCATION is the location of the binary operator. */ struct c_expr -parser_build_binary_op (enum tree_code code, struct c_expr arg1, - struct c_expr arg2) +parser_build_binary_op (location_t location, enum tree_code code, + struct c_expr arg1, struct c_expr arg2) { struct c_expr result; enum tree_code code1 = arg1.original_code; enum tree_code code2 = arg2.original_code; - result.value = build_binary_op (code, arg1.value, arg2.value, 1); + result.value = build_binary_op (location, code, + arg1.value, arg2.value, 1); result.original_code = code; if (TREE_CODE (result.value) == ERROR_MARK) return result; + if (location != UNKNOWN_LOCATION) + protected_set_expr_location (result.value, location); + /* Check for cases such as x+y< used in subtraction"); - if (TREE_CODE (target_type) == FUNCTION_TYPE) - pedwarn ("pointer to a function used in subtraction"); - } + if (TREE_CODE (target_type) == VOID_TYPE) + pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + "pointer of type % used in subtraction"); + if (TREE_CODE (target_type) == FUNCTION_TYPE) + pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + "pointer to a function used in subtraction"); /* If the conversion to ptrdiff_type does anything like widening or converting a partial to an integral mode, we get a convert_expression @@ -2859,7 +2879,8 @@ pointer_diff (tree op0, tree op1) Do not do default conversions on the minus operator in case restype is a short type. */ - op0 = build_binary_op (MINUS_EXPR, convert (restype, op0), + op0 = build_binary_op (input_location, + MINUS_EXPR, convert (restype, op0), convert (restype, op1), 0); /* This generates an error if op1 is pointer to incomplete type. */ if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1)))) @@ -2879,16 +2900,20 @@ pointer_diff (tree op0, tree op1) the default promotions (such as from short to int). For ADDR_EXPR, the default promotions are not applied; FLAG nonzero allows non-lvalues; this is only used to handle conversion of non-lvalue - arrays to pointers in C99. */ + arrays to pointers in C99. + + LOCATION is the location of the operator. */ tree -build_unary_op (enum tree_code code, tree xarg, int flag) +build_unary_op (location_t location, + enum tree_code code, tree xarg, int flag) { /* No default_conversion here. It causes trouble for ADDR_EXPR. */ tree arg = xarg; tree argtype = 0; enum tree_code typecode; tree val; + tree ret = error_mark_node; int noconvert = flag; const char *invalid_op_diag; @@ -2904,7 +2929,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag) if ((invalid_op_diag = targetm.invalid_unary_op (code, TREE_TYPE (xarg)))) { - error (invalid_op_diag); + error_at (location, invalid_op_diag); return error_mark_node; } @@ -2918,7 +2943,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag) || typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE || typecode == VECTOR_TYPE)) { - error ("wrong type argument to unary plus"); + error_at (location, "wrong type argument to unary plus"); return error_mark_node; } else if (!noconvert) @@ -2931,7 +2956,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag) || typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE || typecode == VECTOR_TYPE)) { - error ("wrong type argument to unary minus"); + error_at (location, "wrong type argument to unary minus"); return error_mark_node; } else if (!noconvert) @@ -2950,14 +2975,14 @@ build_unary_op (enum tree_code code, tree xarg, int flag) else if (typecode == COMPLEX_TYPE) { code = CONJ_EXPR; - if (pedantic) - pedwarn ("ISO C does not support %<~%> for complex conjugation"); + pedwarn (location, OPT_pedantic, + "ISO C does not support %<~%> for complex conjugation"); if (!noconvert) arg = default_conversion (arg); } else { - error ("wrong type argument to bit-complement"); + error_at (location, "wrong type argument to bit-complement"); return error_mark_node; } break; @@ -2965,7 +2990,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag) case ABS_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE)) { - error ("wrong type argument to abs"); + error_at (location, "wrong type argument to abs"); return error_mark_node; } else if (!noconvert) @@ -2977,7 +3002,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag) if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE || typecode == COMPLEX_TYPE)) { - error ("wrong type argument to conjugation"); + error_at (location, "wrong type argument to conjugation"); return error_mark_node; } else if (!noconvert) @@ -2989,27 +3014,31 @@ build_unary_op (enum tree_code code, tree xarg, int flag) && typecode != REAL_TYPE && typecode != POINTER_TYPE && typecode != COMPLEX_TYPE) { - error ("wrong type argument to unary exclamation mark"); + error_at (location, + "wrong type argument to unary exclamation mark"); return error_mark_node; } - arg = c_objc_common_truthvalue_conversion (arg); - return invert_truthvalue (arg); + arg = c_objc_common_truthvalue_conversion (location, arg); + ret = invert_truthvalue (arg); + goto return_build_unary_op; case REALPART_EXPR: if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_REALPART (arg); + ret = TREE_REALPART (arg); else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - return fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); + ret = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); else - return arg; + ret = arg; + goto return_build_unary_op; case IMAGPART_EXPR: if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_IMAGPART (arg); + ret = TREE_IMAGPART (arg); else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - return fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); + ret = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg); else - return convert (TREE_TYPE (arg), integer_zero_node); + ret = omit_one_operand (TREE_TYPE (arg), integer_zero_node, arg); + goto return_build_unary_op; case PREINCREMENT_EXPR: case POSTINCREMENT_EXPR: @@ -3022,18 +3051,18 @@ build_unary_op (enum tree_code code, tree xarg, int flag) { tree real, imag; - if (pedantic) - pedwarn ("ISO C does not support %<++%> and %<--%>" - " on complex types"); + pedwarn (location, OPT_pedantic, + "ISO C does not support %<++%> and %<--%> on complex types"); arg = stabilize_reference (arg); - real = build_unary_op (REALPART_EXPR, arg, 1); - imag = build_unary_op (IMAGPART_EXPR, arg, 1); - real = build_unary_op (code, real, 1); + real = build_unary_op (EXPR_LOCATION (arg), REALPART_EXPR, arg, 1); + imag = build_unary_op (EXPR_LOCATION (arg), IMAGPART_EXPR, arg, 1); + real = build_unary_op (EXPR_LOCATION (arg), code, real, 1); if (real == error_mark_node || imag == error_mark_node) return error_mark_node; - return build2 (COMPLEX_EXPR, TREE_TYPE (arg), - real, imag); + ret = build2 (COMPLEX_EXPR, TREE_TYPE (arg), + real, imag); + goto return_build_unary_op; } /* Report invalid types. */ @@ -3042,18 +3071,16 @@ build_unary_op (enum tree_code code, tree xarg, int flag) && typecode != INTEGER_TYPE && typecode != REAL_TYPE) { if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - error ("wrong type argument to increment"); + error_at (location, "wrong type argument to increment"); else - error ("wrong type argument to decrement"); + error_at (location, "wrong type argument to decrement"); return error_mark_node; } { tree inc; - tree result_type = TREE_TYPE (arg); - arg = get_unwidened (arg, 0); argtype = TREE_TYPE (arg); /* Compute the increment. */ @@ -3062,27 +3089,30 @@ build_unary_op (enum tree_code code, tree xarg, int flag) { /* If pointer target is an undefined struct, we just cannot know how to do the arithmetic. */ - if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (result_type))) + if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (argtype))) { if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - error ("increment of pointer to unknown structure"); + error_at (location, + "increment of pointer to unknown structure"); else - error ("decrement of pointer to unknown structure"); + error_at (location, + "decrement of pointer to unknown structure"); } - else if ((pedantic || warn_pointer_arith) - && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)) + else if (TREE_CODE (TREE_TYPE (argtype)) == FUNCTION_TYPE + || TREE_CODE (TREE_TYPE (argtype)) == VOID_TYPE) { if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - pedwarn ("wrong type argument to increment"); + pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + "wrong type argument to increment"); else - pedwarn ("wrong type argument to decrement"); + pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + "wrong type argument to decrement"); } - inc = c_size_in_bytes (TREE_TYPE (result_type)); + inc = c_size_in_bytes (TREE_TYPE (argtype)); inc = fold_convert (sizetype, inc); } - else if (FRACT_MODE_P (TYPE_MODE (result_type))) + else if (FRACT_MODE_P (TYPE_MODE (argtype))) { /* For signed fract types, we invert ++ to -- or -- to ++, and change inc from 1 to -1, because @@ -3129,10 +3159,10 @@ build_unary_op (enum tree_code code, tree xarg, int flag) else val = build2 (code, TREE_TYPE (arg), arg, inc); TREE_SIDE_EFFECTS (val) = 1; - val = convert (result_type, val); if (TREE_CODE (val) != code) TREE_NO_WARNING (val) = 1; - return val; + ret = val; + goto return_build_unary_op; } case ADDR_EXPR: @@ -3144,7 +3174,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag) /* Don't let this be an lvalue. */ if (lvalue_p (TREE_OPERAND (arg, 0))) return non_lvalue (TREE_OPERAND (arg, 0)); - return TREE_OPERAND (arg, 0); + ret = TREE_OPERAND (arg, 0); + goto return_build_unary_op; } /* For &x[y], return x+y */ @@ -3153,7 +3184,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag) tree op0 = TREE_OPERAND (arg, 0); if (!c_mark_addressable (op0)) return error_mark_node; - return build_binary_op (PLUS_EXPR, + return build_binary_op (location, PLUS_EXPR, (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE ? array_to_pointer_conversion (op0) : op0), @@ -3196,12 +3227,14 @@ build_unary_op (enum tree_code code, tree xarg, int flag) tree op0 = fold_convert (sizetype, fold_offsetof (arg, val)), op1; op1 = fold_convert (argtype, TREE_OPERAND (val, 0)); - return fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0); + ret = fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0); + goto return_build_unary_op; } val = build1 (ADDR_EXPR, argtype, arg); - return val; + ret = val; + goto return_build_unary_op; default: gcc_unreachable (); @@ -3209,8 +3242,12 @@ build_unary_op (enum tree_code code, tree xarg, int flag) if (argtype == 0) argtype = TREE_TYPE (arg); - return require_constant_value ? fold_build1_initializer (code, argtype, arg) - : fold_build1 (code, argtype, arg); + ret = require_constant_value ? fold_build1_initializer (code, argtype, arg) + : fold_build1 (code, argtype, arg); + return_build_unary_op: + gcc_assert (ret != error_mark_node); + protected_set_expr_location (ret, location); + return ret; } /* Return nonzero if REF is an lvalue valid for this language. @@ -3351,7 +3388,7 @@ c_mark_addressable (tree exp) ("global register variable %qD used in nested function", x); return false; } - pedwarn ("register variable %qD used in nested function", x); + pedwarn (input_location, 0, "register variable %qD used in nested function", x); } else if (C_DECL_REGISTER (x)) { @@ -3458,8 +3495,9 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) } else if (code1 == VOID_TYPE || code2 == VOID_TYPE) { - if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE)) - pedwarn ("ISO C forbids conditional expr with only one void side"); + if (code1 != VOID_TYPE || code2 != VOID_TYPE) + pedwarn (input_location, OPT_pedantic, + "ISO C forbids conditional expr with only one void side"); result_type = void_type_node; } else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) @@ -3472,30 +3510,34 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) result_type = qualify_type (type1, type2); else if (VOID_TYPE_P (TREE_TYPE (type1))) { - if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE) - pedwarn ("ISO C forbids conditional expr between " + if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE) + pedwarn (input_location, OPT_pedantic, + "ISO C forbids conditional expr between " "% and function pointer"); result_type = build_pointer_type (qualify_type (TREE_TYPE (type1), TREE_TYPE (type2))); } else if (VOID_TYPE_P (TREE_TYPE (type2))) { - if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE) - pedwarn ("ISO C forbids conditional expr between " + if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE) + pedwarn (input_location, OPT_pedantic, + "ISO C forbids conditional expr between " "% and function pointer"); result_type = build_pointer_type (qualify_type (TREE_TYPE (type2), TREE_TYPE (type1))); } else { - pedwarn ("pointer type mismatch in conditional expression"); + pedwarn (input_location, 0, + "pointer type mismatch in conditional expression"); result_type = build_pointer_type (void_type_node); } } else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) { if (!null_pointer_constant_p (orig_op2)) - pedwarn ("pointer/integer type mismatch in conditional expression"); + pedwarn (input_location, 0, + "pointer/integer type mismatch in conditional expression"); else { op2 = null_pointer_node; @@ -3505,7 +3547,8 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE) { if (!null_pointer_constant_p (orig_op1)) - pedwarn ("pointer/integer type mismatch in conditional expression"); + pedwarn (input_location, 0, + "pointer/integer type mismatch in conditional expression"); else { op1 = null_pointer_node; @@ -3616,12 +3659,10 @@ build_c_cast (tree type, tree expr) if (type == TYPE_MAIN_VARIANT (TREE_TYPE (value))) { - if (pedantic) - { - if (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - pedwarn ("ISO C forbids casting nonscalar to the same type"); - } + if (TREE_CODE (type) == RECORD_TYPE + || TREE_CODE (type) == UNION_TYPE) + pedwarn (input_location, OPT_pedantic, + "ISO C forbids casting nonscalar to the same type"); } else if (TREE_CODE (type) == UNION_TYPE) { @@ -3637,8 +3678,8 @@ build_c_cast (tree type, tree expr) { tree t; - if (pedantic) - pedwarn ("ISO C forbids casts to union type"); + pedwarn (input_location, OPT_pedantic, + "ISO C forbids casts to union type"); t = digest_init (type, build_constructor_single (type, field, value), true, 0); @@ -3749,7 +3790,8 @@ build_c_cast (tree type, tree expr) && TREE_CODE (otype) == POINTER_TYPE && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE) - pedwarn ("ISO C forbids conversion of function pointer to object pointer type"); + pedwarn (input_location, OPT_pedantic, "ISO C forbids " + "conversion of function pointer to object pointer type"); if (pedantic && TREE_CODE (type) == POINTER_TYPE @@ -3757,7 +3799,8 @@ build_c_cast (tree type, tree expr) && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE && !null_pointer_constant_p (value)) - pedwarn ("ISO C forbids conversion of object pointer to function pointer type"); + pedwarn (input_location, OPT_pedantic, "ISO C forbids " + "conversion of object pointer to function pointer type"); ovalue = value; value = convert (type, value); @@ -3809,10 +3852,13 @@ c_cast_expr (struct c_type_name *type_name, tree expr) /* Build an assignment expression of lvalue LHS from value RHS. MODIFYCODE is the code for a binary operator that we use to combine the old value of LHS with RHS to get the new value. - Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. */ + Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. + + LOCATION is the location of the MODIFYCODE operator. */ tree -build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) +build_modify_expr (location_t location, + tree lhs, enum tree_code modifycode, tree rhs) { tree result; tree newrhs; @@ -3839,7 +3885,8 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) if (modifycode != NOP_EXPR) { lhs = stabilize_reference (lhs); - newrhs = build_binary_op (modifycode, lhs, rhs, 1); + newrhs = build_binary_op (location, + modifycode, lhs, rhs, 1); } /* Give an error for storing in something that is 'const'. */ @@ -3886,13 +3933,17 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) { result = objc_generate_write_barrier (lhs, modifycode, newrhs); if (result) - return result; + { + protected_set_expr_location (result, location); + return result; + } } /* Scan operands. */ result = build2 (MODIFY_EXPR, lhstype, lhs, newrhs); TREE_SIDE_EFFECTS (result) = 1; + protected_set_expr_location (result, location); /* If we got the LHS in a different type for storing in, convert the result back to the nominal type of LHS @@ -3901,8 +3952,11 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) if (olhstype == TREE_TYPE (result)) return result; - return convert_for_assignment (olhstype, result, ic_assign, - NULL_TREE, NULL_TREE, 0); + + result = convert_for_assignment (olhstype, result, ic_assign, + NULL_TREE, NULL_TREE, 0); + protected_set_expr_location (result, location); + return result; } /* Convert value RHS to type TYPE as preparation for an assignment @@ -3926,7 +3980,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, tree rname = NULL_TREE; bool objc_ok = false; - if (errtype == ic_argpass || errtype == ic_argpass_nonproto) + if (errtype == ic_argpass) { tree selector; /* Change pointer to function to the function itself for @@ -3948,28 +4002,29 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, /* This macro is used to emit diagnostics to ensure that all format strings are complete sentences, visible to gettext and checked at compile time. */ -#define WARN_FOR_ASSIGNMENT(AR, AS, IN, RE) \ - do { \ - switch (errtype) \ - { \ - case ic_argpass: \ - pedwarn (AR, parmnum, rname); \ - break; \ - case ic_argpass_nonproto: \ - warning (0, AR, parmnum, rname); \ - break; \ - case ic_assign: \ - pedwarn (AS); \ - break; \ - case ic_init: \ - pedwarn (IN); \ - break; \ - case ic_return: \ - pedwarn (RE); \ - break; \ - default: \ - gcc_unreachable (); \ - } \ +#define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE) \ + do { \ + switch (errtype) \ + { \ + case ic_argpass: \ + if (pedwarn (LOCATION, OPT, AR, parmnum, rname)) \ + inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \ + ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \ + "expected %qT but argument is of type %qT", \ + type, rhstype); \ + break; \ + case ic_assign: \ + pedwarn (LOCATION, OPT, AS); \ + break; \ + case ic_init: \ + pedwarn (LOCATION, OPT, IN); \ + break; \ + case ic_return: \ + pedwarn (LOCATION, OPT, RE); \ + break; \ + default: \ + gcc_unreachable (); \ + } \ } while (0) STRIP_TYPE_NOPS (rhs); @@ -4076,7 +4131,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, /* Conversion to a transparent union from its member types. This applies only to function arguments. */ if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type) - && (errtype == ic_argpass || errtype == ic_argpass_nonproto)) + && errtype == ic_argpass) { tree memb, marginal_memb = NULL_TREE; @@ -4147,7 +4202,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, function where an ordinary one is wanted, but not vice-versa. */ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) - WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE " + WARN_FOR_ASSIGNMENT (input_location, 0, + G_("passing argument %d of %qE " "makes qualified function " "pointer from unqualified"), G_("assignment makes qualified " @@ -4160,7 +4216,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, "pointer from unqualified")); } else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) - WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE discards " + WARN_FOR_ASSIGNMENT (input_location, 0, + G_("passing argument %d of %qE discards " "qualifiers from pointer target type"), G_("assignment discards qualifiers " "from pointer target type"), @@ -4172,8 +4229,9 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, memb = marginal_memb; } - if (pedantic && (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl))) - pedwarn ("ISO C prohibits argument conversion to union type"); + if (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl)) + pedwarn (input_location, OPT_pedantic, + "ISO C prohibits argument conversion to union type"); rhs = fold_convert (TREE_TYPE (memb), rhs); return build_constructor_single (type, memb, rhs); @@ -4196,10 +4254,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, if (TREE_CODE (mvr) != ARRAY_TYPE) mvr = TYPE_MAIN_VARIANT (mvr); /* Opaque pointers are treated like void pointers. */ - is_opaque_pointer = (targetm.vector_opaque_p (type) - || targetm.vector_opaque_p (rhstype)) - && TREE_CODE (ttl) == VECTOR_TYPE - && TREE_CODE (ttr) == VECTOR_TYPE; + is_opaque_pointer = vector_targets_convertible_p (ttl, ttr); /* C++ does not allow the implicit conversion void* -> T*. However, for the purpose of reducing the number of false positives, we @@ -4220,7 +4275,6 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, switch (errtype) { case ic_argpass: - case ic_argpass_nonproto: warning (OPT_Wmissing_format_attribute, "argument %d of %qE might be " "a candidate for a format attribute", @@ -4261,7 +4315,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, (VOID_TYPE_P (ttr) && !null_pointer_constant_p (rhs) && TREE_CODE (ttl) == FUNCTION_TYPE))) - WARN_FOR_ASSIGNMENT (G_("ISO C forbids passing argument %d of " + WARN_FOR_ASSIGNMENT (input_location, OPT_pedantic, + G_("ISO C forbids passing argument %d of " "%qE between function pointer " "and %"), G_("ISO C forbids assignment between " @@ -4281,7 +4336,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, 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 (G_("passing argument %d of %qE discards " + WARN_FOR_ASSIGNMENT (input_location, 0, + G_("passing argument %d of %qE discards " "qualifiers from pointer target type"), G_("assignment discards qualifiers " "from pointer target type"), @@ -4297,7 +4353,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, ; /* If there is a mismatch, do warn. */ else if (warn_pointer_sign) - WARN_FOR_ASSIGNMENT (G_("pointer targets in passing argument " + WARN_FOR_ASSIGNMENT (input_location, OPT_Wpointer_sign, + G_("pointer targets in passing argument " "%d of %qE differ in signedness"), G_("pointer targets in assignment " "differ in signedness"), @@ -4314,7 +4371,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, it is okay to use a const or volatile function where an ordinary one is wanted, but not vice-versa. */ if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) - WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes " + WARN_FOR_ASSIGNMENT (input_location, 0, + G_("passing argument %d of %qE makes " "qualified function pointer " "from unqualified"), G_("assignment makes qualified function " @@ -4328,7 +4386,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, else /* Avoid warning about the volatile ObjC EH puts on decls. */ if (!objc_ok) - WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE from " + WARN_FOR_ASSIGNMENT (input_location, 0, + G_("passing argument %d of %qE from " "incompatible pointer type"), G_("assignment from incompatible pointer type"), G_("initialization from incompatible " @@ -4350,7 +4409,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, or one that results from arithmetic, even including a cast to integer type. */ if (!null_pointer_constant_p (rhs)) - WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes " + WARN_FOR_ASSIGNMENT (input_location, 0, + G_("passing argument %d of %qE makes " "pointer from integer without a cast"), G_("assignment makes pointer from integer " "without a cast"), @@ -4363,7 +4423,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, } else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) { - WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes integer " + WARN_FOR_ASSIGNMENT (input_location, 0, + G_("passing argument %d of %qE makes integer " "from pointer without a cast"), G_("assignment makes integer from pointer " "without a cast"), @@ -4379,19 +4440,22 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, switch (errtype) { case ic_argpass: - case ic_argpass_nonproto: - /* ??? This should not be an error when inlining calls to - unprototyped functions. */ error ("incompatible type for argument %d of %qE", parmnum, rname); + inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) + ? DECL_SOURCE_LOCATION (fundecl) : input_location, + "expected %qT but argument is of type %qT", type, rhstype); break; case ic_assign: - error ("incompatible types in assignment"); + error ("incompatible types when assigning to type %qT from type %qT", + type, rhstype); break; case ic_init: - error ("incompatible types in initialization"); + error ("incompatible types when initializing type %qT using type %qT", + type, rhstype); break; case ic_return: - error ("incompatible types in return"); + error ("incompatible types when returning type %qT but %qT was expected", + rhstype, type); break; default: gcc_unreachable (); @@ -4621,19 +4685,20 @@ error_init (const char *msgid) error ("(near initialization for %qs)", ofwhat); } -/* Issue a pedantic warning for a bad initializer component. - MSGID identifies the message. - The component name is taken from the spelling stack. */ +/* Issue a pedantic warning for a bad initializer component. OPT is + the option OPT_* (from options.h) controlling this warning or 0 if + it is unconditionally given. MSGID identifies the message. The + component name is taken from the spelling stack. */ void -pedwarn_init (const char *msgid) +pedwarn_init (location_t location, int opt, const char *msgid) { char *ofwhat; - pedwarn ("%s", _(msgid)); + pedwarn (location, opt, "%s", _(msgid)); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat) - pedwarn ("(near initialization for %qs)", ofwhat); + pedwarn (location, opt, "(near initialization for %qs)", ofwhat); } /* Issue a warning for a bad initializer component. @@ -4664,7 +4729,8 @@ maybe_warn_string_init (tree type, struct c_expr expr) && TREE_CODE (type) == ARRAY_TYPE && TREE_CODE (expr.value) == STRING_CST && expr.original_code != STRING_CST) - pedwarn_init ("array initialized from parenthesized string constant"); + pedwarn_init (input_location, OPT_pedantic, + "array initialized from parenthesized string constant"); } /* Digest the parser output INIT as an initializer for type TYPE. @@ -4707,48 +4773,58 @@ digest_init (tree type, tree init, bool strict_string, int require_constant) || typ1 == signed_char_type_node || typ1 == unsigned_char_type_node); bool wchar_array = !!comptypes (typ1, wchar_type_node); - if (char_array || wchar_array) + bool char16_array = !!comptypes (typ1, char16_type_node); + bool char32_array = !!comptypes (typ1, char32_type_node); + + if (char_array || wchar_array || char16_array || char32_array) { struct c_expr expr; - bool char_string; + tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))); expr.value = inside_init; expr.original_code = (strict_string ? STRING_CST : ERROR_MARK); maybe_warn_string_init (type, expr); - char_string - = (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) - == char_type_node); - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), TYPE_MAIN_VARIANT (type))) return inside_init; - if (!wchar_array && !char_string) + if (char_array) { - error_init ("char-array initialized from wide string"); - return error_mark_node; + if (typ2 != char_type_node) + { + error_init ("char-array initialized from wide string"); + return error_mark_node; + } } - if (char_string && !char_array) + else { - error_init ("wchar_t-array initialized from non-wide string"); - return error_mark_node; + if (typ2 == char_type_node) + { + error_init ("wide character array initialized from non-wide " + "string"); + return error_mark_node; + } + else if (!comptypes(typ1, typ2)) + { + error_init ("wide character array initialized from " + "incompatible wide string"); + return error_mark_node; + } } TREE_TYPE (inside_init) = type; if (TYPE_DOMAIN (type) != 0 && TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST - /* Subtract 1 (or sizeof (wchar_t)) + /* Subtract the size of a single (possibly wide) character because it's ok to ignore the terminating null char that is counted in the length of the constant. */ && 0 > compare_tree_int (TYPE_SIZE_UNIT (type), TREE_STRING_LENGTH (inside_init) - - ((TYPE_PRECISION (typ1) - != TYPE_PRECISION (char_type_node)) - ? (TYPE_PRECISION (wchar_type_node) - / BITS_PER_UNIT) - : 1))) - pedwarn_init ("initializer-string for array of chars is too long"); + - (TYPE_PRECISION (typ1) + / BITS_PER_UNIT))) + pedwarn_init (input_location, 0, + "initializer-string for array of chars is too long"); return inside_init; } @@ -4794,6 +4870,9 @@ digest_init (tree type, tree init, bool strict_string, int require_constant) } } + if (warn_sequence_point) + verify_sequence_points (inside_init); + /* Any type can be initialized from an expression of the same type, optionally with braces. */ @@ -4863,7 +4942,8 @@ digest_init (tree type, tree init, bool strict_string, int require_constant) if (inside_init == error_mark_node) error_init ("initializer element is not constant"); else - pedwarn_init ("initializer element is not constant"); + pedwarn_init (input_location, OPT_pedantic, + "initializer element is not constant"); if (flag_pedantic_errors) inside_init = error_mark_node; } @@ -5309,12 +5389,12 @@ push_init_level (int implicit) if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) - process_init_element (pop_init_level (1)); + process_init_element (pop_init_level (1), true); 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)); + process_init_element (pop_init_level (1), true); else break; } @@ -5508,7 +5588,7 @@ pop_init_level (int implicit) /* When we come to an explicit close brace, pop any inner levels that didn't have explicit braces. */ while (constructor_stack->implicit) - process_init_element (pop_init_level (1)); + process_init_element (pop_init_level (1), true); gcc_assert (!constructor_range_stack); } @@ -5536,8 +5616,9 @@ pop_init_level (int implicit) if (constructor_depth > 2) error_init ("initialization of flexible array member in a nested context"); - else if (pedantic) - pedwarn_init ("initialization of a flexible array member"); + else + pedwarn_init (input_location, OPT_pedantic, + "initialization of a flexible array member"); /* We have already issued an error message for the existence of a flexible array member not at the end of the structure. @@ -5666,7 +5747,7 @@ set_designator (int array) /* Designator list starts at the level of closest explicit braces. */ while (constructor_stack->implicit) - process_init_element (pop_init_level (1)); + process_init_element (pop_init_level (1), true); constructor_designated = 1; return 0; } @@ -5827,10 +5908,15 @@ set_init_label (tree fieldname) /* Add a new initializer to the tree of pending initializers. PURPOSE identifies the initializer, either array index or field in a structure. - VALUE is the value of that index or field. */ + VALUE is the value of that index or field. + + IMPLICIT is true if value comes from pop_init_level (1), + the new initializer has been merged with the existing one + and thus no warnings should be emitted about overriding an + existing initializer. */ static void -add_pending_init (tree purpose, tree value) +add_pending_init (tree purpose, tree value, bool implicit) { struct init_node *p, **q, *r; @@ -5848,10 +5934,13 @@ add_pending_init (tree purpose, tree value) q = &p->right; else { - if (TREE_SIDE_EFFECTS (p->value)) - warning_init (0, "initialized field with side-effects overwritten"); - else if (warn_override_init) - warning_init (OPT_Woverride_init, "initialized field overwritten"); + if (!implicit) + { + if (TREE_SIDE_EFFECTS (p->value)) + warning_init (0, "initialized field with side-effects overwritten"); + else if (warn_override_init) + warning_init (OPT_Woverride_init, "initialized field overwritten"); + } p->value = value; return; } @@ -5871,10 +5960,13 @@ add_pending_init (tree purpose, tree value) q = &p->right; else { - if (TREE_SIDE_EFFECTS (p->value)) - warning_init (0, "initialized field with side-effects overwritten"); - else if (warn_override_init) - warning_init (OPT_Woverride_init, "initialized field overwritten"); + if (!implicit) + { + if (TREE_SIDE_EFFECTS (p->value)) + warning_init (0, "initialized field with side-effects overwritten"); + else if (warn_override_init) + warning_init (OPT_Woverride_init, "initialized field overwritten"); + } p->value = value; return; } @@ -6059,7 +6151,7 @@ set_nonincremental_init (void) return; FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value) - add_pending_init (index, value); + add_pending_init (index, value, false); constructor_elements = 0; if (TREE_CODE (constructor_type) == RECORD_TYPE) { @@ -6095,15 +6187,7 @@ set_nonincremental_init_from_string (tree str) gcc_assert (TREE_CODE (constructor_type) == ARRAY_TYPE); - if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) - == TYPE_PRECISION (char_type_node)) - wchar_bytes = 1; - else - { - gcc_assert (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) - == TYPE_PRECISION (wchar_type_node)); - wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT; - } + wchar_bytes = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) / BITS_PER_UNIT; charwidth = TYPE_PRECISION (char_type_node); type = TREE_TYPE (constructor_type); p = TREE_STRING_POINTER (str); @@ -6157,7 +6241,7 @@ set_nonincremental_init_from_string (tree str) } value = build_int_cst_wide (type, val[1], val[0]); - add_pending_init (purpose, value); + add_pending_init (purpose, value, false); } constructor_incremental = 0; @@ -6230,11 +6314,16 @@ find_init_member (tree field) PENDING if non-nil means output pending elements that belong right after this element. (PENDING is normally 1; - it is 0 while outputting pending elements, to avoid recursion.) */ + it is 0 while outputting pending elements, to avoid recursion.) + + IMPLICIT is true if value comes from pop_init_level (1), + the new initializer has been merged with the existing one + and thus no warnings should be emitted about overriding an + existing initializer. */ static void output_init_element (tree value, bool strict_string, tree type, tree field, - int pending) + int pending, bool implicit) { constructor_elt *celt; @@ -6282,7 +6371,8 @@ output_init_element (tree value, bool strict_string, tree type, tree field, value = error_mark_node; } else if (require_constant_elements) - pedwarn ("initializer element is not computable at load time"); + pedwarn (input_location, 0, + "initializer element is not computable at load time"); } /* If this field is empty (and not at the end of structure), @@ -6312,7 +6402,7 @@ output_init_element (tree value, bool strict_string, tree type, tree field, && tree_int_cst_lt (field, constructor_unfilled_index)) set_nonincremental_init (); - add_pending_init (field, value); + add_pending_init (field, value, implicit); return; } else if (TREE_CODE (constructor_type) == RECORD_TYPE @@ -6338,17 +6428,21 @@ output_init_element (tree value, bool strict_string, tree type, tree field, } } - add_pending_init (field, value); + add_pending_init (field, value, implicit); return; } else if (TREE_CODE (constructor_type) == UNION_TYPE && !VEC_empty (constructor_elt, constructor_elements)) { - if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt, - constructor_elements)->value)) - warning_init (0, "initialized field with side-effects overwritten"); - else if (warn_override_init) - warning_init (OPT_Woverride_init, "initialized field overwritten"); + if (!implicit) + { + if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt, + constructor_elements)->value)) + warning_init (0, + "initialized field with side-effects overwritten"); + else if (warn_override_init) + warning_init (OPT_Woverride_init, "initialized field overwritten"); + } /* We can have just one union field set. */ constructor_elements = 0; @@ -6419,7 +6513,7 @@ output_pending_init_elements (int all) constructor_unfilled_index)) output_init_element (elt->value, true, TREE_TYPE (constructor_type), - constructor_unfilled_index, 0); + constructor_unfilled_index, 0, false); else if (tree_int_cst_lt (constructor_unfilled_index, elt->purpose)) { @@ -6472,7 +6566,7 @@ output_pending_init_elements (int all) { constructor_unfilled_fields = elt->purpose; output_init_element (elt->value, true, TREE_TYPE (elt->purpose), - elt->purpose, 0); + elt->purpose, 0, false); } else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos)) { @@ -6535,10 +6629,15 @@ output_pending_init_elements (int all) to handle a partly-braced initializer. Once this has found the correct level for the new element, - it calls output_init_element. */ + it calls output_init_element. + + IMPLICIT is true if value comes from pop_init_level (1), + the new initializer has been merged with the existing one + and thus no warnings should be emitted about overriding an + existing initializer. */ void -process_init_element (struct c_expr value) +process_init_element (struct c_expr value, bool implicit) { tree orig_value = value.value; int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST; @@ -6579,12 +6678,12 @@ process_init_element (struct c_expr value) if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) - process_init_element (pop_init_level (1)); + process_init_element (pop_init_level (1), true); else if (TREE_CODE (constructor_type) == ARRAY_TYPE && (constructor_max_index == 0 || tree_int_cst_lt (constructor_max_index, constructor_index))) - process_init_element (pop_init_level (1)); + process_init_element (pop_init_level (1), true); else break; } @@ -6609,7 +6708,8 @@ process_init_element (struct c_expr value) if (constructor_fields == 0) { - pedwarn_init ("excess elements in struct initializer"); + pedwarn_init (input_location, 0, + "excess elements in struct initializer"); break; } @@ -6650,7 +6750,7 @@ process_init_element (struct c_expr value) { push_member_name (constructor_fields); output_init_element (value.value, strict_string, - fieldtype, constructor_fields, 1); + fieldtype, constructor_fields, 1, implicit); RESTORE_SPELLING_DEPTH (constructor_depth); } else @@ -6692,7 +6792,8 @@ process_init_element (struct c_expr value) if (constructor_fields == 0) { - pedwarn_init ("excess elements in union initializer"); + pedwarn_init (input_location, 0, + "excess elements in union initializer"); break; } @@ -6739,7 +6840,7 @@ process_init_element (struct c_expr value) { push_member_name (constructor_fields); output_init_element (value.value, strict_string, - fieldtype, constructor_fields, 1); + fieldtype, constructor_fields, 1, implicit); RESTORE_SPELLING_DEPTH (constructor_depth); } else @@ -6779,7 +6880,8 @@ process_init_element (struct c_expr value) && (tree_int_cst_lt (constructor_max_index, constructor_index) || integer_all_onesp (constructor_max_index))) { - pedwarn_init ("excess elements in array initializer"); + pedwarn_init (input_location, 0, + "excess elements in array initializer"); break; } @@ -6788,7 +6890,7 @@ process_init_element (struct c_expr value) { push_array_bounds (tree_low_cst (constructor_index, 1)); output_init_element (value.value, strict_string, - elttype, constructor_index, 1); + elttype, constructor_index, 1, implicit); RESTORE_SPELLING_DEPTH (constructor_depth); } @@ -6809,14 +6911,15 @@ process_init_element (struct c_expr value) always have a fixed size derived from their type. */ if (tree_int_cst_lt (constructor_max_index, constructor_index)) { - pedwarn_init ("excess elements in vector initializer"); + pedwarn_init (input_location, 0, + "excess elements in vector initializer"); break; } /* Now output the actual element. */ if (value.value) output_init_element (value.value, strict_string, - elttype, constructor_index, 1); + elttype, constructor_index, 1, implicit); constructor_index = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node); @@ -6833,14 +6936,15 @@ process_init_element (struct c_expr value) else if (constructor_type != error_mark_node && constructor_fields == 0) { - pedwarn_init ("excess elements in scalar initializer"); + pedwarn_init (input_location, 0, + "excess elements in scalar initializer"); break; } else { if (value.value) output_init_element (value.value, strict_string, - constructor_type, NULL_TREE, 1); + constructor_type, NULL_TREE, 1, implicit); constructor_fields = 0; } @@ -6856,14 +6960,14 @@ process_init_element (struct c_expr value) while (constructor_stack != range_stack->stack) { gcc_assert (constructor_stack->implicit); - process_init_element (pop_init_level (1)); + process_init_element (pop_init_level (1), true); } for (p = range_stack; !p->range_end || tree_int_cst_equal (p->index, p->range_end); p = p->prev) { gcc_assert (constructor_stack->implicit); - process_init_element (pop_init_level (1)); + process_init_element (pop_init_level (1), true); } p->index = size_binop (PLUS_EXPR, p->index, bitsize_one_node); @@ -7064,8 +7168,7 @@ c_finish_goto_label (tree label) tree c_finish_goto_ptr (tree expr) { - if (pedantic) - pedwarn ("ISO C forbids %"); + pedwarn (input_location, OPT_pedantic, "ISO C forbids %"); expr = convert (ptr_type_node, expr); return add_stmt (build1 (GOTO_EXPR, void_type_node, expr)); } @@ -7088,7 +7191,8 @@ c_finish_return (tree retval) if ((warn_return_type || flag_isoc99) && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE) { - pedwarn_c99 ("% with no value, in " + pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wreturn_type, + "% with no value, in " "function returning non-void"); no_warning = true; } @@ -7097,9 +7201,11 @@ c_finish_return (tree retval) { current_function_returns_null = 1; if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) - pedwarn ("% with a value, in function returning void"); - else if (pedantic) - pedwarn ("ISO C forbids % with expression, in function returning void"); + pedwarn (input_location, 0, + "% with a value, in function returning void"); + else + pedwarn (input_location, OPT_pedantic, "ISO C forbids " + "% with expression, in function returning void"); } else { @@ -7120,8 +7226,10 @@ c_finish_return (tree retval) { switch (TREE_CODE (inner)) { - CASE_CONVERT: case NON_LVALUE_EXPR: + CASE_CONVERT: + case NON_LVALUE_EXPR: case PLUS_EXPR: + case POINTER_PLUS_EXPR: inner = TREE_OPERAND (inner, 0); continue; @@ -7166,6 +7274,9 @@ c_finish_return (tree retval) } retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t); + + if (warn_sequence_point) + verify_sequence_points (retval); } ret_stmt = build_stmt (RETURN_EXPR, retval); @@ -7243,6 +7354,9 @@ c_start_case (tree exp) "converted to % in ISO C"); exp = default_conversion (exp); + + if (warn_sequence_point) + verify_sequence_points (exp); } } @@ -7378,8 +7492,6 @@ c_finish_if_stmt (location_t if_locus, tree cond, tree then_block, &if_locus); } - empty_if_body_warning (then_block, else_block); - stmt = build3 (COND_EXPR, void_type_node, cond, then_block, else_block); SET_EXPR_LOCATION (stmt, if_locus); add_stmt (stmt); @@ -7861,6 +7973,7 @@ push_cleanup (tree ARG_UNUSED (decl), tree cleanup, bool eh_only) /* Build a binary-operation expression without default conversions. CODE is the kind of expression to build. + LOCATION is the operator's location. This function differs from `build' in several ways: the data type of the result is computed and recorded in it, warnings are generated if arg data types are invalid, @@ -7875,12 +7988,13 @@ push_cleanup (tree ARG_UNUSED (decl), tree cleanup, bool eh_only) the arithmetic is to be done. */ tree -build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, - int convert_p) +build_binary_op (location_t location, enum tree_code code, + tree orig_op0, tree orig_op1, int convert_p) { tree type0, type1; enum tree_code code0, code1; tree op0, op1; + tree ret = error_mark_node; const char *invalid_op_diag; /* Expression code to give to the expression when it is built. @@ -7928,6 +8042,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, /* True means types are compatible as far as ObjC is concerned. */ bool objc_ok; + if (location == UNKNOWN_LOCATION) + location = input_location; + if (convert_p) { op0 = default_conversion (orig_op0); @@ -7960,7 +8077,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, if ((invalid_op_diag = targetm.invalid_binary_op (code, type0, type1))) { - error (invalid_op_diag); + error_at (location, invalid_op_diag); return error_mark_node; } @@ -7971,9 +8088,15 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, case PLUS_EXPR: /* Handle the pointer + int case. */ if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return pointer_int_sum (PLUS_EXPR, op0, op1); + { + ret = pointer_int_sum (PLUS_EXPR, op0, op1); + goto return_build_binary_op; + } else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE) - return pointer_int_sum (PLUS_EXPR, op1, op0); + { + ret = pointer_int_sum (PLUS_EXPR, op1, op0); + goto return_build_binary_op; + } else common = 1; break; @@ -7983,10 +8106,16 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, We must subtract them as integers, then divide by object size. */ if (code0 == POINTER_TYPE && code1 == POINTER_TYPE && comp_target_types (type0, type1)) - return pointer_diff (op0, op1); + { + ret = pointer_diff (op0, op1); + goto return_build_binary_op; + } /* Handle pointer minus int. Just like pointer plus int. */ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return pointer_int_sum (MINUS_EXPR, op0, op1); + { + ret = pointer_int_sum (MINUS_EXPR, op0, op1); + goto return_build_binary_op; + } else common = 1; break; @@ -8000,7 +8129,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, case FLOOR_DIV_EXPR: case ROUND_DIV_EXPR: case EXACT_DIV_EXPR: - warn_for_div_by_zero (op1); + warn_for_div_by_zero (location, op1); if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == FIXED_POINT_TYPE @@ -8047,7 +8176,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: - warn_for_div_by_zero (op1); + warn_for_div_by_zero (location, op1); if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { @@ -8078,8 +8207,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, but that does not mean the operands should be converted to ints! */ result_type = integer_type_node; - op0 = c_common_truthvalue_conversion (op0); - op1 = c_common_truthvalue_conversion (op1); + op0 = c_common_truthvalue_conversion (location, op0); + op1 = c_common_truthvalue_conversion (location, op1); converted = 1; } break; @@ -8144,8 +8273,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, case EQ_EXPR: case NE_EXPR: if (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)) - warning (OPT_Wfloat_equal, - "comparing floating point with == or != is unsafe"); + warning_at (location, + 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; @@ -8169,20 +8299,21 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, whose value is 0 but which isn't a valid null ptr const. */ if (pedantic && !null_pointer_constant_p (orig_op0) && TREE_CODE (tt1) == FUNCTION_TYPE) - pedwarn ("ISO C forbids comparison of %" - " with function pointer"); + pedwarn (location, OPT_pedantic, "ISO C forbids " + "comparison of % with function pointer"); } else if (VOID_TYPE_P (tt1)) { if (pedantic && !null_pointer_constant_p (orig_op1) && TREE_CODE (tt0) == FUNCTION_TYPE) - pedwarn ("ISO C forbids comparison of %" - " with function pointer"); + pedwarn (location, OPT_pedantic, "ISO C forbids " + "comparison of % with function pointer"); } else /* Avoid warning about the volatile ObjC EH puts on decls. */ if (!objc_ok) - pedwarn ("comparison of distinct pointer types lacks a cast"); + pedwarn (location, 0, + "comparison of distinct pointer types lacks a cast"); if (result_type == NULL_TREE) result_type = ptr_type_node; @@ -8191,27 +8322,29 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, { if (TREE_CODE (op0) == ADDR_EXPR && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))) - warning (OPT_Waddress, "the address of %qD will never be NULL", - TREE_OPERAND (op0, 0)); + warning_at (location, + OPT_Waddress, "the address of %qD will never be NULL", + TREE_OPERAND (op0, 0)); result_type = type0; } else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0)) { if (TREE_CODE (op1) == ADDR_EXPR && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))) - warning (OPT_Waddress, "the address of %qD will never be NULL", - TREE_OPERAND (op1, 0)); + warning_at (location, + OPT_Waddress, "the address of %qD will never be NULL", + TREE_OPERAND (op1, 0)); result_type = type1; } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; - pedwarn ("comparison between pointer and integer"); + pedwarn (location, 0, "comparison between pointer and integer"); } else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) { result_type = type1; - pedwarn ("comparison between pointer and integer"); + pedwarn (location, 0, "comparison between pointer and integer"); } break; @@ -8232,38 +8365,44 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, result_type = common_pointer_type (type0, type1); if (!COMPLETE_TYPE_P (TREE_TYPE (type0)) != !COMPLETE_TYPE_P (TREE_TYPE (type1))) - pedwarn ("comparison of complete and incomplete pointers"); - else if (pedantic - && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) - pedwarn ("ISO C forbids ordered comparisons of pointers to functions"); + pedwarn (location, 0, + "comparison of complete and incomplete pointers"); + else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) + pedwarn (location, OPT_pedantic, "ISO C forbids " + "ordered comparisons of pointers to functions"); } else { result_type = ptr_type_node; - pedwarn ("comparison of distinct pointer types lacks a cast"); + pedwarn (location, 0, + "comparison of distinct pointer types lacks a cast"); } } else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1)) { result_type = type0; - if (pedantic || extra_warnings) - pedwarn ("ordered comparison of pointer with integer zero"); + if (pedantic) + pedwarn (location, OPT_pedantic, + "ordered comparison of pointer with integer zero"); + else if (extra_warnings) + warning_at (location, OPT_Wextra, + "ordered comparison of pointer with integer zero"); } else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0)) { result_type = type1; - if (pedantic) - pedwarn ("ordered comparison of pointer with integer zero"); + pedwarn (location, OPT_pedantic, + "ordered comparison of pointer with integer zero"); } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; - pedwarn ("comparison between pointer and integer"); + pedwarn (location, 0, "comparison between pointer and integer"); } else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) { result_type = type1; - pedwarn ("comparison between pointer and integer"); + pedwarn (location, 0, "comparison between pointer and integer"); } break; @@ -8279,7 +8418,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0), TREE_TYPE (type1)))) { - binary_op_error (code, type0, type1); + binary_op_error (location, code, type0, type1); return error_mark_node; } @@ -8311,93 +8450,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, if (shorten && none_complex) { - int unsigned0, unsigned1; - tree arg0, arg1; - int uns; - tree type; - - /* Cast OP0 and OP1 to RESULT_TYPE. Doing so prevents - excessive narrowing when we call get_narrower below. For - example, suppose that OP0 is of unsigned int extended - from signed char and that RESULT_TYPE is long long int. - If we explicitly cast OP0 to RESULT_TYPE, OP0 would look - like - - (long long int) (unsigned int) signed_char - - which get_narrower would narrow down to - - (unsigned int) signed char - - If we do not cast OP0 first, get_narrower would return - signed_char, which is inconsistent with the case of the - explicit cast. */ - op0 = convert (result_type, op0); - op1 = convert (result_type, op1); - - arg0 = get_narrower (op0, &unsigned0); - arg1 = get_narrower (op1, &unsigned1); - - /* UNS is 1 if the operation to be done is an unsigned one. */ - uns = TYPE_UNSIGNED (result_type); - final_type = result_type; - - /* Handle the case that OP0 (or OP1) does not *contain* a conversion - but it *requires* conversion to FINAL_TYPE. */ - - if ((TYPE_PRECISION (TREE_TYPE (op0)) - == TYPE_PRECISION (TREE_TYPE (arg0))) - && TREE_TYPE (op0) != final_type) - unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0)); - if ((TYPE_PRECISION (TREE_TYPE (op1)) - == TYPE_PRECISION (TREE_TYPE (arg1))) - && TREE_TYPE (op1) != final_type) - unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1)); - - /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE. */ - - /* For bitwise operations, signedness of nominal type - does not matter. Consider only how operands were extended. */ - if (shorten == -1) - uns = unsigned0; - - /* Note that in all three cases below we refrain from optimizing - an unsigned operation on sign-extended args. - That would not be valid. */ - - /* Both args variable: if both extended in same way - from same width, do it in that width. - Do it unsigned if args were zero-extended. */ - if ((TYPE_PRECISION (TREE_TYPE (arg0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (arg1)) - == TYPE_PRECISION (TREE_TYPE (arg0))) - && unsigned0 == unsigned1 - && (unsigned0 || !uns)) - result_type - = 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 - = c_common_signed_or_unsigned_type (unsigned1, - TREE_TYPE (arg1))) - && !POINTER_TYPE_P (type) - && 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 - = c_common_signed_or_unsigned_type (unsigned0, - TREE_TYPE (arg0))) - && !POINTER_TYPE_P (type) - && int_fits_type_p (arg1, type)) - result_type = type; + result_type = shorten_binary_op (result_type, op0, op1, + shorten == -1); } /* Shifts can be shortened if shifting right. */ @@ -8445,130 +8500,19 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); if (val != 0) - return val; + { + ret = val; + goto return_build_binary_op; + } op0 = xop0, op1 = xop1; converted = 1; resultcode = xresultcode; - if (warn_sign_compare && skip_evaluation == 0) - { - int op0_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op0)); - int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1)); - int unsignedp0, unsignedp1; - tree primop0 = get_narrower (op0, &unsignedp0); - tree primop1 = get_narrower (op1, &unsignedp1); - - xop0 = orig_op0; - xop1 = orig_op1; - STRIP_TYPE_NOPS (xop0); - STRIP_TYPE_NOPS (xop1); - - /* Give warnings for comparisons between signed and unsigned - quantities that may fail. - - Do the checking based on the original operand trees, so that - casts will be considered, but default promotions won't be. - - Do not warn if the comparison is being done in a signed type, - since the signed type will only be chosen if it can represent - all the values of the unsigned type. */ - if (!TYPE_UNSIGNED (result_type)) - /* OK */; - /* Do not warn if both operands are the same signedness. */ - else if (op0_signed == op1_signed) - /* OK */; - else - { - tree sop, uop; - bool ovf; - - if (op0_signed) - sop = xop0, uop = xop1; - else - sop = xop1, uop = xop0; - - /* Do not warn if the signed quantity is an - unsuffixed integer literal (or some static - constant expression involving such literals or a - conditional expression involving such literals) - and it is non-negative. */ - if (tree_expr_nonnegative_warnv_p (sop, &ovf)) - /* 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, 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)), - c_common_signed_type (result_type))) - /* OK */; - else - warning (OPT_Wsign_compare, "comparison between signed and unsigned"); - } - - /* Warn if two unsigned values are being compared in a size - larger than their original size, and one (and only one) is the - result of a `~' operator. This comparison will always fail. - - Also warn if one operand is a constant, and the constant - does not have all bits set that are set in the ~ operand - when it is extended. */ - - if ((TREE_CODE (primop0) == BIT_NOT_EXPR) - != (TREE_CODE (primop1) == BIT_NOT_EXPR)) - { - if (TREE_CODE (primop0) == BIT_NOT_EXPR) - primop0 = get_narrower (TREE_OPERAND (primop0, 0), - &unsignedp0); - else - primop1 = get_narrower (TREE_OPERAND (primop1, 0), - &unsignedp1); - - if (host_integerp (primop0, 0) || host_integerp (primop1, 0)) - { - tree primop; - HOST_WIDE_INT constant, mask; - int unsignedp, bits; - - if (host_integerp (primop0, 0)) - { - primop = primop1; - unsignedp = unsignedp1; - constant = tree_low_cst (primop0, 0); - } - else - { - primop = primop0; - unsignedp = unsignedp0; - constant = tree_low_cst (primop1, 0); - } - - bits = TYPE_PRECISION (TREE_TYPE (primop)); - if (bits < TYPE_PRECISION (result_type) - && bits < HOST_BITS_PER_WIDE_INT && unsignedp) - { - mask = (~(HOST_WIDE_INT) 0) << bits; - if ((mask & constant) != mask) - warning (OPT_Wsign_compare, "comparison of promoted ~unsigned with constant"); - } - } - else if (unsignedp0 && unsignedp1 - && (TYPE_PRECISION (TREE_TYPE (primop0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (primop1)) - < TYPE_PRECISION (result_type))) - warning (OPT_Wsign_compare, "comparison of promoted ~unsigned with unsigned"); - } + if (warn_sign_compare && !skip_evaluation) + { + warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1, + result_type, resultcode); } } } @@ -8581,7 +8525,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, if (!result_type) { - binary_op_error (code, TREE_TYPE (op0), TREE_TYPE (op1)); + binary_op_error (location, code, TREE_TYPE (op0), TREE_TYPE (op1)); return error_mark_node; } @@ -8601,39 +8545,40 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, if (build_type == NULL_TREE) build_type = result_type; - { - /* Treat expressions in initializers specially as they can't trap. */ - tree result = require_constant_value ? fold_build2_initializer (resultcode, - build_type, - op0, op1) - : fold_build2 (resultcode, build_type, - op0, op1); - - if (final_type != 0) - result = convert (final_type, result); - return result; - } + /* Treat expressions in initializers specially as they can't trap. */ + ret = require_constant_value ? fold_build2_initializer (resultcode, + build_type, + op0, op1) + : fold_build2 (resultcode, build_type, + op0, op1); + if (final_type != 0) + ret = convert (final_type, ret); + + return_build_binary_op: + gcc_assert (ret != error_mark_node); + protected_set_expr_location (ret, location); + return ret; } /* Convert EXPR to be a truth-value, validating its type for this - purpose. */ + purpose. LOCATION is the source location for the expression. */ tree -c_objc_common_truthvalue_conversion (tree expr) +c_objc_common_truthvalue_conversion (location_t location, tree expr) { switch (TREE_CODE (TREE_TYPE (expr))) { case ARRAY_TYPE: - error ("used array that cannot be converted to pointer where scalar is required"); + error_at (location, "used array that cannot be converted to pointer where scalar is required"); return error_mark_node; case RECORD_TYPE: - error ("used struct type value where scalar is required"); + error_at (location, "used struct type value where scalar is required"); return error_mark_node; case UNION_TYPE: - error ("used union type value where scalar is required"); + error_at (location, "used union type value where scalar is required"); return error_mark_node; case FUNCTION_TYPE: @@ -8645,7 +8590,7 @@ c_objc_common_truthvalue_conversion (tree expr) /* ??? Should we also give an error for void and vectors rather than leaving those to give errors later? */ - return c_common_truthvalue_conversion (expr); + return c_common_truthvalue_conversion (location, expr); }