Mercurial > hg > CbC > CbC_gcc
diff gcc/c/c-typeck.c @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | bdf41c9fa0b7 84e7813d76e9 |
children | 351920fa3827 |
line wrap: on
line diff
--- a/gcc/c/c-typeck.c Thu Oct 25 08:08:40 2018 +0900 +++ b/gcc/c/c-typeck.c Thu Oct 25 10:21:07 2018 +0900 @@ -1,5 +1,5 @@ /* Build expressions with type checking for C compiler. - Copyright (C) 1987-2017 Free Software Foundation, Inc. + Copyright (C) 1987-2018 Free Software Foundation, Inc. This file is part of GCC. @@ -46,7 +46,6 @@ #include "omp-general.h" #include "c-family/c-objc.h" #include "c-family/c-ubsan.h" -#include "cilk.h" #include "gomp-constants.h" #include "spellcheck-tree.h" #include "gcc-rich-location.h" @@ -99,7 +98,7 @@ static int convert_arguments (location_t, vec<location_t>, tree, vec<tree, va_gc> *, vec<tree, va_gc> *, tree, tree); -static tree pointer_diff (location_t, tree, tree); +static tree pointer_diff (location_t, tree, tree, tree *); static tree convert_for_assignment (location_t, location_t, tree, tree, tree, enum impl_conv, bool, tree, tree, int); static tree valid_compound_expr_initializer (tree, tree); @@ -1197,9 +1196,9 @@ /* Target types must match incl. qualifiers. */ if (TREE_TYPE (t1) != TREE_TYPE (t2) - && 0 == (val = comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), - enum_and_int_p, - different_types_p))) + && (val = comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), + enum_and_int_p, + different_types_p)) == 0) return 0; if (different_types_p != NULL @@ -1257,7 +1256,7 @@ break; case VECTOR_TYPE: - val = (TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2) + val = (known_eq (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2)) && comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), enum_and_int_p, different_types_p)); break; @@ -1682,8 +1681,8 @@ compare that with the other type's arglist. If they don't match, ask for a warning (but no error). */ if (TYPE_ACTUAL_ARG_TYPES (f1) - && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1), - enum_and_int_p, different_types_p)) + && type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1), + enum_and_int_p, different_types_p) != 1) val = 2; return val; } @@ -1692,8 +1691,8 @@ if (!self_promoting_args_p (args1)) return 0; if (TYPE_ACTUAL_ARG_TYPES (f2) - && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2), - enum_and_int_p, different_types_p)) + && type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2), + enum_and_int_p, different_types_p) != 1) val = 2; return val; } @@ -1852,27 +1851,35 @@ /* Return either DECL or its known constant value (if it has one). */ tree -decl_constant_value (tree decl) -{ - if (/* Don't change a variable array bound or initial value to a constant - in a place where a variable is invalid. Note that DECL_INITIAL - isn't valid for a PARM_DECL. */ - current_function_decl != NULL_TREE - && TREE_CODE (decl) != PARM_DECL +decl_constant_value_1 (tree decl, bool in_init) +{ + if (/* Note that DECL_INITIAL isn't valid for a PARM_DECL. */ + TREE_CODE (decl) != PARM_DECL && !TREE_THIS_VOLATILE (decl) && TREE_READONLY (decl) && DECL_INITIAL (decl) != NULL_TREE - && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK + && !error_operand_p (DECL_INITIAL (decl)) /* This is invalid if initial value is not constant. If it has either a function call, a memory reference, or a variable, then re-evaluating it could give different results. */ && TREE_CONSTANT (DECL_INITIAL (decl)) /* Check for cases where this is sub-optimal, even though valid. */ - && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) + && (in_init || TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)) return DECL_INITIAL (decl); return decl; } +/* Return either DECL or its known constant value (if it has one). + Like the above, but always return decl outside of functions. */ + +tree +decl_constant_value (tree decl) +{ + /* Don't change a variable array bound or initial value to a constant + in a place where a variable is invalid. */ + return current_function_decl ? decl_constant_value_1 (decl, false) : decl; +} + /* Convert the array expression EXP to a pointer. */ static tree array_to_pointer_conversion (location_t loc, tree exp) @@ -2133,8 +2140,8 @@ && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)) /* If it's thinner than an int, promote it like a c_promoting_integer_type_p, otherwise leave it alone. */ - && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)), - TYPE_PRECISION (integer_type_node))) + && compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)), + TYPE_PRECISION (integer_type_node)) < 0) return convert (integer_type_node, exp); if (c_promoting_integer_type_p (type)) @@ -2219,9 +2226,14 @@ /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers to the field elements. Use a binary search on this array to quickly find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC - will always be set for structures which have many elements. */ - - if (TYPE_LANG_SPECIFIC (type) && TYPE_LANG_SPECIFIC (type)->s) + will always be set for structures which have many elements. + + Duplicate field checking replaces duplicates with NULL_TREE so + TYPE_LANG_SPECIFIC arrays are potentially no longer sorted. In that + case just iterate using DECL_CHAIN. */ + + if (TYPE_LANG_SPECIFIC (type) && TYPE_LANG_SPECIFIC (type)->s + && !seen_error ()) { int bot, top, half; tree *field_array = &TYPE_LANG_SPECIFIC (type)->s->elts[0]; @@ -2425,10 +2437,9 @@ gcc_rich_location rich_loc (reported_loc); if (component_loc != UNKNOWN_LOCATION) rich_loc.add_fixit_misspelled_id (component_loc, guessed_id); - error_at_rich_loc - (&rich_loc, - "%qT has no member named %qE; did you mean %qE?", - type, component, guessed_id); + error_at (&rich_loc, + "%qT has no member named %qE; did you mean %qE?", + type, component, guessed_id); } else error_at (loc, "%qT has no member named %qE", type, component); @@ -2502,9 +2513,9 @@ rich_location richloc (line_table, loc); /* "loc" should be the "." token. */ richloc.add_fixit_replace ("->"); - error_at_rich_loc (&richloc, - "%qE is a pointer; did you mean to use %<->%>?", - datum); + error_at (&richloc, + "%qE is a pointer; did you mean to use %<->%>?", + datum); return error_mark_node; } else if (code != ERROR_MARK) @@ -2537,7 +2548,7 @@ the backend. This only needs to be done at warn_strict_aliasing > 2. */ if (warn_strict_aliasing > 2) - if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (pointer, 0)), + if (strict_aliasing_warning (EXPR_LOCATION (pointer), type, TREE_OPERAND (pointer, 0))) TREE_NO_WARNING (pointer) = 1; } @@ -2613,17 +2624,6 @@ || TREE_TYPE (index) == error_mark_node) return error_mark_node; - if (flag_cilkplus && contains_array_notation_expr (index)) - { - size_t rank = 0; - if (!find_rank (loc, index, index, true, &rank)) - return error_mark_node; - if (rank > 1) - { - error_at (loc, "rank of the array's index is greater than 1"); - return error_mark_node; - } - } if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE /* Allow vector[index] but not index[vector]. */ @@ -2929,6 +2929,7 @@ if (TREE_CODE (expr.value) == PARM_DECL && C_ARRAY_PARAMETER (expr.value)) { + auto_diagnostic_group d; if (warning_at (loc, OPT_Wsizeof_array_argument, "%<sizeof%> on array function parameter %qE will " "return size of %qT", expr.value, @@ -3057,10 +3058,6 @@ often rewritten and don't match the original parameter list. */ if (name && !strncmp (IDENTIFIER_POINTER (name), "__atomic_", 9)) origtypes = NULL; - - if (flag_cilkplus - && is_cilkplus_reduce_builtin (function)) - origtypes = NULL; } if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE) function = function_to_pointer_conversion (loc, function); @@ -3134,9 +3131,7 @@ argarray = vec_safe_address (params); /* Check that arguments to builtin functions match the expectations. */ - if (fundecl - && DECL_BUILT_IN (fundecl) - && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL + if (fundecl && fndecl_built_in_p (fundecl, BUILT_IN_NORMAL) && !check_builtin_function_arguments (loc, arg_loc, fundecl, nargs, argarray)) return error_mark_node; @@ -3259,8 +3254,7 @@ precision should be removed (classification) or not (comparison). */ if (type_generic - && DECL_BUILT_IN (fundecl) - && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL) + && fndecl_built_in_p (fundecl, BUILT_IN_NORMAL)) { switch (DECL_FUNCTION_CODE (fundecl)) { @@ -3285,8 +3279,6 @@ break; } } - if (flag_cilkplus && fundecl && is_cilkplus_reduce_builtin (fundecl)) - return vec_safe_length (values); /* Scan the given expressions and types, producing individual converted arguments. */ @@ -3769,19 +3761,27 @@ "comparison with string literal results in unspecified behavior"); /* Warn for ptr == '\0', it's likely that it should've been ptr[0]. */ if (POINTER_TYPE_P (type1) - && null_pointer_constant_p (arg2.value) - && char_type_p (type2) - && warning_at (location, OPT_Wpointer_compare, - "comparison between pointer and zero character " - "constant")) - inform (arg1.get_start (), "did you mean to dereference the pointer?"); + && null_pointer_constant_p (arg2.value) + && char_type_p (type2)) + { + auto_diagnostic_group d; + if (warning_at (location, OPT_Wpointer_compare, + "comparison between pointer and zero character " + "constant")) + inform (arg1.get_start (), + "did you mean to dereference the pointer?"); + } else if (POINTER_TYPE_P (type2) && null_pointer_constant_p (arg1.value) - && char_type_p (type1) - && warning_at (location, OPT_Wpointer_compare, - "comparison between pointer and zero character " - "constant")) - inform (arg2.get_start (), "did you mean to dereference the pointer?"); + && char_type_p (type1)) + { + auto_diagnostic_group d; + if (warning_at (location, OPT_Wpointer_compare, + "comparison between pointer and zero character " + "constant")) + inform (arg2.get_start (), + "did you mean to dereference the pointer?"); + } } else if (TREE_CODE_CLASS (code) == tcc_comparison && (code1 == STRING_CST || code2 == STRING_CST)) @@ -3807,10 +3807,11 @@ } /* Return a tree for the difference of pointers OP0 and OP1. - The resulting tree has type int. */ + The resulting tree has type ptrdiff_t. If POINTER_SUBTRACT sanitization is + enabled, assign to INSTRUMENT_EXPR call to libsanitizer. */ static tree -pointer_diff (location_t loc, tree op0, tree op1) +pointer_diff (location_t loc, tree op0, tree op1, tree *instrument_expr) { tree restype = ptrdiff_type_node; tree result, inttype; @@ -3839,7 +3840,7 @@ op1 = convert (common_type, op1); } - /* Determine integer type to perform computations in. This will usually + /* Determine integer type result of the subtraction. This will usually be the same as the result type (ptrdiff_t), but may need to be a wider type if pointers for the address space are wider than ptrdiff_t. */ if (TYPE_PRECISION (restype) < TYPE_PRECISION (TREE_TYPE (op0))) @@ -3854,14 +3855,37 @@ pedwarn (loc, OPT_Wpointer_arith, "pointer to a function used in subtraction"); - /* First do the subtraction as integers; - then drop through to build the divide operator. - Do not do default conversions on the minus operator - in case restype is a short type. */ - - op0 = build_binary_op (loc, - MINUS_EXPR, convert (inttype, op0), - convert (inttype, op1), false); + if (sanitize_flags_p (SANITIZE_POINTER_SUBTRACT)) + { + gcc_assert (current_function_decl != NULL_TREE); + + op0 = save_expr (op0); + op1 = save_expr (op1); + + tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_SUBTRACT); + *instrument_expr = build_call_expr_loc (loc, tt, 2, op0, op1); + } + + /* First do the subtraction, then build the divide operator + and only convert at the very end. + Do not do default conversions in case restype is a short type. */ + + /* POINTER_DIFF_EXPR requires a signed integer type of the same size as + pointers. If some platform cannot provide that, or has a larger + ptrdiff_type to support differences larger than half the address + space, cast the pointers to some larger integer type and do the + computations in that type. */ + if (TYPE_PRECISION (inttype) > TYPE_PRECISION (TREE_TYPE (op0))) + op0 = build_binary_op (loc, MINUS_EXPR, convert (inttype, op0), + convert (inttype, op1), false); + else + { + /* Cast away qualifiers. */ + op0 = convert (c_common_type (TREE_TYPE (op0), TREE_TYPE (op0)), op0); + op1 = convert (c_common_type (TREE_TYPE (op1), TREE_TYPE (op1)), op1); + op0 = build2_loc (loc, POINTER_DIFF_EXPR, inttype, op0, op1); + } + /* This generates an error if op1 is pointer to incomplete type. */ if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1)))) error_at (loc, "arithmetic on pointer to an incomplete type"); @@ -4298,14 +4322,16 @@ e = TREE_OPERAND (e, 1); if ((TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE - || truth_value_p (TREE_CODE (e))) - && warning_at (location, OPT_Wbool_operation, - "%<~%> on a boolean expression")) - { - gcc_rich_location richloc (location); - richloc.add_fixit_insert_before (location, "!"); - inform_at_rich_loc (&richloc, "did you mean to use logical " - "not?"); + || truth_value_p (TREE_CODE (e)))) + { + auto_diagnostic_group d; + if (warning_at (location, OPT_Wbool_operation, + "%<~%> on a boolean expression")) + { + gcc_rich_location richloc (location); + richloc.add_fixit_insert_before (location, "!"); + inform (&richloc, "did you mean to use logical not?"); + } } if (!noconvert) arg = default_conversion (arg); @@ -4335,6 +4361,16 @@ arg = default_conversion (arg); break; + case ABSU_EXPR: + if (!(typecode == INTEGER_TYPE)) + { + error_at (location, "wrong type argument to absu"); + return error_mark_node; + } + else if (!noconvert) + arg = default_conversion (arg); + break; + case CONJ_EXPR: /* Conjugating a real value is a no-op, but allow it anyway. */ if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE @@ -4428,7 +4464,7 @@ } /* Ensure the argument is fully folded inside any SAVE_EXPR. */ - arg = c_fully_fold (arg, false, NULL); + arg = c_fully_fold (arg, false, NULL, true); bool atomic_op; atomic_op = really_atomic_lvalue (arg); @@ -4697,7 +4733,7 @@ if (val && INDIRECT_REF_P (val) && TREE_CONSTANT (TREE_OPERAND (val, 0))) { - ret = fold_convert_loc (location, argtype, fold_offsetof_1 (arg)); + ret = fold_offsetof (arg, argtype); goto return_build_unary_op; } @@ -4756,7 +4792,6 @@ case INDIRECT_REF: case ARRAY_REF: - case ARRAY_NOTATION_REF: case VAR_DECL: case PARM_DECL: case RESULT_DECL: @@ -4843,6 +4878,10 @@ break; case COMPOUND_LITERAL_EXPR: + TREE_ADDRESSABLE (x) = 1; + TREE_ADDRESSABLE (COMPOUND_LITERAL_EXPR_DECL (x)) = 1; + return true; + case CONSTRUCTOR: TREE_ADDRESSABLE (x) = 1; return true; @@ -5324,14 +5363,6 @@ tree eptype = NULL_TREE; tree ret; - if (flag_cilkplus - && (TREE_CODE (expr1) == CILK_SPAWN_STMT - || TREE_CODE (expr2) == CILK_SPAWN_STMT)) - { - error_at (loc, - "spawned function call cannot be part of a comma expression"); - return error_mark_node; - } expr1_int_operands = EXPR_INT_CONST_OPERANDS (expr1); if (expr1_int_operands) expr1 = remove_c_maybe_const_expr (expr1); @@ -5502,6 +5533,59 @@ while (TREE_CODE (in_type) == POINTER_TYPE); } +/* Heuristic check if two parameter types can be considered ABI-equivalent. */ + +static bool +c_safe_arg_type_equiv_p (tree t1, tree t2) +{ + t1 = TYPE_MAIN_VARIANT (t1); + t2 = TYPE_MAIN_VARIANT (t2); + + if (TREE_CODE (t1) == POINTER_TYPE + && TREE_CODE (t2) == POINTER_TYPE) + return true; + + /* The signedness of the parameter matters only when an integral + type smaller than int is promoted to int, otherwise only the + precision of the parameter matters. + This check should make sure that the callee does not see + undefined values in argument registers. */ + if (INTEGRAL_TYPE_P (t1) + && INTEGRAL_TYPE_P (t2) + && TYPE_PRECISION (t1) == TYPE_PRECISION (t2) + && (TYPE_UNSIGNED (t1) == TYPE_UNSIGNED (t2) + || !targetm.calls.promote_prototypes (NULL_TREE) + || TYPE_PRECISION (t1) >= TYPE_PRECISION (integer_type_node))) + return true; + + return comptypes (t1, t2); +} + +/* Check if a type cast between two function types can be considered safe. */ + +static bool +c_safe_function_type_cast_p (tree t1, tree t2) +{ + if (TREE_TYPE (t1) == void_type_node && + TYPE_ARG_TYPES (t1) == void_list_node) + return true; + + if (TREE_TYPE (t2) == void_type_node && + TYPE_ARG_TYPES (t2) == void_list_node) + return true; + + if (!c_safe_arg_type_equiv_p (TREE_TYPE (t1), TREE_TYPE (t2))) + return false; + + for (t1 = TYPE_ARG_TYPES (t1), t2 = TYPE_ARG_TYPES (t2); + t1 && t2; + t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2)) + if (!c_safe_arg_type_equiv_p (TREE_VALUE (t1), TREE_VALUE (t2))) + return false; + + return true; +} + /* Build an expression representing a cast to type TYPE of expression EXPR. LOC is the location of the cast-- typically the open paren of the cast. */ @@ -5673,7 +5757,7 @@ "of different size"); if (warn_strict_aliasing <= 2) - strict_aliasing_warning (otype, type, expr); + strict_aliasing_warning (EXPR_LOCATION (value), type, expr); /* If pedantic, warn for conversions between function and object pointer types, except for converting a null pointer constant @@ -5695,6 +5779,16 @@ pedwarn (loc, OPT_Wpedantic, "ISO C forbids " "conversion of object pointer to function pointer type"); + if (TREE_CODE (type) == POINTER_TYPE + && TREE_CODE (otype) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE + && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE + && !c_safe_function_type_cast_p (TREE_TYPE (type), + TREE_TYPE (otype))) + warning_at (loc, OPT_Wcast_function_type, + "cast between incompatible function types" + " from %qT to %qT", otype, type); + ovalue = value; value = convert (type, value); @@ -5852,7 +5946,7 @@ if (modifycode != NOP_EXPR) { - lhs = c_fully_fold (lhs, false, NULL); + lhs = c_fully_fold (lhs, false, NULL, true); lhs = stabilize_reference (lhs); /* Construct the RHS for any non-atomic compound assignemnt. */ @@ -6140,6 +6234,8 @@ { char *ofwhat; + auto_diagnostic_group d; + /* The gmsgid may be a format string with %< and %>. */ error_at (loc, gmsgid); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); @@ -6159,7 +6255,7 @@ it was defined to make sure macros defined in system headers but used incorrectly elsewhere are diagnosed. */ source_location exploc = expansion_point_location_if_in_system_header (loc); - + auto_diagnostic_group d; va_list ap; va_start (ap, gmsgid); bool warned = emit_diagnostic_valist (DK_PEDWARN, exploc, opt, gmsgid, &ap); @@ -6181,6 +6277,8 @@ char *ofwhat; bool warned; + auto_diagnostic_group d; + /* Use the location where a macro was expanded rather than where it was defined to make sure macros defined in system headers but used incorrectly elsewhere are diagnosed. */ @@ -6322,8 +6420,11 @@ switch (errtype) \ { \ case ic_argpass: \ - if (pedwarn (PLOC, OPT, AR, parmnum, rname)) \ - inform_for_arg (fundecl, (PLOC), parmnum, type, rhstype); \ + { \ + auto_diagnostic_group d; \ + if (pedwarn (PLOC, OPT, AR, parmnum, rname)) \ + inform_for_arg (fundecl, (PLOC), parmnum, type, rhstype); \ + } \ break; \ case ic_assign: \ pedwarn (LOCATION, OPT, AS); \ @@ -6348,8 +6449,11 @@ switch (errtype) \ { \ case ic_argpass: \ - if (pedwarn (PLOC, OPT, AR, parmnum, rname, QUALS)) \ - inform_for_arg (fundecl, (PLOC), parmnum, type, rhstype); \ + { \ + auto_diagnostic_group d; \ + if (pedwarn (PLOC, OPT, AR, parmnum, rname, QUALS)) \ + inform_for_arg (fundecl, (PLOC), parmnum, type, rhstype); \ + } \ break; \ case ic_assign: \ pedwarn (LOCATION, OPT, AS, QUALS); \ @@ -6374,8 +6478,11 @@ switch (errtype) \ { \ case ic_argpass: \ - if (warning_at (PLOC, OPT, AR, parmnum, rname, QUALS)) \ - inform_for_arg (fundecl, (PLOC), parmnum, type, rhstype); \ + { \ + auto_diagnostic_group d; \ + if (warning_at (PLOC, OPT, AR, parmnum, rname, QUALS)) \ + inform_for_arg (fundecl, (PLOC), parmnum, type, rhstype); \ + } \ break; \ case ic_assign: \ warning_at (LOCATION, OPT, AS, QUALS); \ @@ -6867,13 +6974,16 @@ switch (errtype) { case ic_argpass: - if (pedwarn (expr_loc, OPT_Wpointer_sign, - "pointer targets in passing argument %d of " - "%qE differ in signedness", parmnum, rname)) - inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) - ? DECL_SOURCE_LOCATION (fundecl) : expr_loc, - "expected %qT but argument is of type %qT", - type, rhstype); + { + auto_diagnostic_group d; + range_label_for_type_mismatch rhs_label (rhstype, type); + gcc_rich_location richloc (expr_loc, &rhs_label); + if (pedwarn (&richloc, OPT_Wpointer_sign, + "pointer targets in passing argument %d of " + "%qE differ in signedness", parmnum, rname)) + inform_for_arg (fundecl, expr_loc, parmnum, type, + rhstype); + } break; case ic_assign: pedwarn (location, OPT_Wpointer_sign, @@ -6924,10 +7034,15 @@ switch (errtype) { case ic_argpass: - if (pedwarn (expr_loc, OPT_Wincompatible_pointer_types, - "passing argument %d of %qE from incompatible " - "pointer type", parmnum, rname)) - inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + { + auto_diagnostic_group d; + range_label_for_type_mismatch rhs_label (rhstype, type); + gcc_rich_location richloc (expr_loc, &rhs_label); + if (pedwarn (&richloc, OPT_Wincompatible_pointer_types, + "passing argument %d of %qE from incompatible " + "pointer type", parmnum, rname)) + inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + } break; case ic_assign: pedwarn (location, OPT_Wincompatible_pointer_types, @@ -6967,10 +7082,15 @@ switch (errtype) { case ic_argpass: - if (pedwarn (expr_loc, OPT_Wint_conversion, - "passing argument %d of %qE makes pointer from " - "integer without a cast", parmnum, rname)) - inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + { + auto_diagnostic_group d; + range_label_for_type_mismatch rhs_label (rhstype, type); + gcc_rich_location richloc (expr_loc, &rhs_label); + if (pedwarn (&richloc, OPT_Wint_conversion, + "passing argument %d of %qE makes pointer from " + "integer without a cast", parmnum, rname)) + inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + } break; case ic_assign: pedwarn (location, OPT_Wint_conversion, @@ -6998,10 +7118,15 @@ switch (errtype) { case ic_argpass: - if (pedwarn (expr_loc, OPT_Wint_conversion, - "passing argument %d of %qE makes integer from " - "pointer without a cast", parmnum, rname)) - inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + { + auto_diagnostic_group d; + range_label_for_type_mismatch rhs_label (rhstype, type); + gcc_rich_location richloc (expr_loc, &rhs_label); + if (pedwarn (&richloc, OPT_Wint_conversion, + "passing argument %d of %qE makes integer from " + "pointer without a cast", parmnum, rname)) + inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + } break; case ic_assign: pedwarn (location, OPT_Wint_conversion, @@ -7037,9 +7162,14 @@ switch (errtype) { case ic_argpass: - error_at (expr_loc, "incompatible type for argument %d of %qE", parmnum, - rname); - inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + { + auto_diagnostic_group d; + range_label_for_type_mismatch rhs_label (rhstype, type); + gcc_rich_location richloc (expr_loc, &rhs_label); + error_at (&richloc, "incompatible type for argument %d of %qE", parmnum, + rname); + inform_for_arg (fundecl, expr_loc, parmnum, type, rhstype); + } break; case ic_assign: error_at (location, "incompatible types when assigning to type %qT from " @@ -7319,7 +7449,6 @@ inside_init = TREE_OPERAND (inside_init, 0); } inside_init = c_fully_fold (inside_init, require_constant, &maybe_const); - inside_init = decl_constant_value_for_optimization (inside_init); /* Initialization of an array of chars from a string constant optionally enclosed in braces. */ @@ -7384,30 +7513,36 @@ } } - TREE_TYPE (inside_init) = type; if (TYPE_DOMAIN (type) != NULL_TREE && TYPE_SIZE (type) != NULL_TREE && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) { unsigned HOST_WIDE_INT len = TREE_STRING_LENGTH (inside_init); + unsigned unit = TYPE_PRECISION (typ1) / BITS_PER_UNIT; /* 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. */ - if (0 > compare_tree_int (TYPE_SIZE_UNIT (type), - (len - - (TYPE_PRECISION (typ1) - / BITS_PER_UNIT)))) + if (compare_tree_int (TYPE_SIZE_UNIT (type), len - unit) < 0) pedwarn_init (init_loc, 0, ("initializer-string for array of chars " "is too long")); else if (warn_cxx_compat - && 0 > compare_tree_int (TYPE_SIZE_UNIT (type), len)) + && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0) warning_at (init_loc, OPT_Wc___compat, ("initializer-string for array chars " "is too long for C++")); - } - + if (compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0) + { + unsigned HOST_WIDE_INT size + = tree_to_uhwi (TYPE_SIZE_UNIT (type)); + const char *p = TREE_STRING_POINTER (inside_init); + + inside_init = build_string (size, p); + } + } + + TREE_TYPE (inside_init) = type; return inside_init; } else if (INTEGRAL_TYPE_P (typ1)) @@ -7924,8 +8059,7 @@ constructor_fields = TYPE_FIELDS (constructor_type); /* Skip any nameless bit fields at the beginning. */ while (constructor_fields != NULL_TREE - && DECL_C_BIT_FIELD (constructor_fields) - && DECL_NAME (constructor_fields) == NULL_TREE) + && DECL_UNNAMED_BIT_FIELD (constructor_fields)) constructor_fields = DECL_CHAIN (constructor_fields); constructor_unfilled_fields = constructor_fields; @@ -8130,8 +8264,7 @@ constructor_fields = TYPE_FIELDS (constructor_type); /* Skip any nameless bit fields at the beginning. */ while (constructor_fields != NULL_TREE - && DECL_C_BIT_FIELD (constructor_fields) - && DECL_NAME (constructor_fields) == NULL_TREE) + && DECL_UNNAMED_BIT_FIELD (constructor_fields)) constructor_fields = DECL_CHAIN (constructor_fields); constructor_unfilled_fields = constructor_fields; @@ -8284,9 +8417,9 @@ && !constructor_zeroinit) { gcc_assert (initializer_stack->missing_brace_richloc); - warning_at_rich_loc (initializer_stack->missing_brace_richloc, - OPT_Wmissing_braces, - "missing braces around initializer"); + warning_at (initializer_stack->missing_brace_richloc, + OPT_Wmissing_braces, + "missing braces around initializer"); } /* Warn when some struct elements are implicitly initialized to zero. */ @@ -8608,10 +8741,9 @@ { gcc_rich_location rich_loc (fieldname_loc); rich_loc.add_fixit_misspelled_id (fieldname_loc, guessed_id); - error_at_rich_loc - (&rich_loc, - "%qT has no member named %qE; did you mean %qE?", - constructor_type, fieldname, guessed_id); + error_at (&rich_loc, + "%qT has no member named %qE; did you mean %qE?", + constructor_type, fieldname, guessed_id); } else error_at (fieldname_loc, "%qT has no member named %qE", @@ -8900,8 +9032,7 @@ constructor_unfilled_fields = TYPE_FIELDS (constructor_type); /* Skip any nameless bit fields at the beginning. */ while (constructor_unfilled_fields != NULL_TREE - && DECL_C_BIT_FIELD (constructor_unfilled_fields) - && DECL_NAME (constructor_unfilled_fields) == NULL_TREE) + && DECL_UNNAMED_BIT_FIELD (constructor_unfilled_fields)) constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields); } @@ -9181,12 +9312,14 @@ "enum conversion in initialization is invalid in C++"); } - /* If this field is empty (and not at the end of structure), - don't do anything other than checking the initializer. */ + /* If this field is empty and does not have side effects (and is not at + the end of structure), don't do anything other than checking the + initializer. */ if (field && (TREE_TYPE (field) == error_mark_node || (COMPLETE_TYPE_P (TREE_TYPE (field)) && integer_zerop (TYPE_SIZE (TREE_TYPE (field))) + && !TREE_SIDE_EFFECTS (new_value) && (TREE_CODE (constructor_type) == ARRAY_TYPE || DECL_CHAIN (field))))) return; @@ -9270,8 +9403,7 @@ /* Skip any nameless bit fields. */ while (constructor_unfilled_fields != NULL_TREE - && DECL_C_BIT_FIELD (constructor_unfilled_fields) - && DECL_NAME (constructor_unfilled_fields) == NULL_TREE) + && DECL_UNNAMED_BIT_FIELD (constructor_unfilled_fields)) constructor_unfilled_fields = DECL_CHAIN (constructor_unfilled_fields); } @@ -9283,6 +9415,65 @@ output_pending_init_elements (0, braced_init_obstack); } +/* For two FIELD_DECLs in the same chain, return -1 if field1 + comes before field2, 1 if field1 comes after field2 and + 0 if field1 == field2. */ + +static int +init_field_decl_cmp (tree field1, tree field2) +{ + if (field1 == field2) + return 0; + + tree bitpos1 = bit_position (field1); + tree bitpos2 = bit_position (field2); + if (tree_int_cst_equal (bitpos1, bitpos2)) + { + /* If one of the fields has non-zero bitsize, then that + field must be the last one in a sequence of zero + sized fields, fields after it will have bigger + bit_position. */ + if (TREE_TYPE (field1) != error_mark_node + && COMPLETE_TYPE_P (TREE_TYPE (field1)) + && integer_nonzerop (TREE_TYPE (field1))) + return 1; + if (TREE_TYPE (field2) != error_mark_node + && COMPLETE_TYPE_P (TREE_TYPE (field2)) + && integer_nonzerop (TREE_TYPE (field2))) + return -1; + /* Otherwise, fallback to DECL_CHAIN walk to find out + which field comes earlier. Walk chains of both + fields, so that if field1 and field2 are close to each + other in either order, it is found soon even for large + sequences of zero sized fields. */ + tree f1 = field1, f2 = field2; + while (1) + { + f1 = DECL_CHAIN (f1); + f2 = DECL_CHAIN (f2); + if (f1 == NULL_TREE) + { + gcc_assert (f2); + return 1; + } + if (f2 == NULL_TREE) + return -1; + if (f1 == field2) + return -1; + if (f2 == field1) + return 1; + if (!tree_int_cst_equal (bit_position (f1), bitpos1)) + return 1; + if (!tree_int_cst_equal (bit_position (f2), bitpos1)) + return -1; + } + } + else if (tree_int_cst_lt (bitpos1, bitpos2)) + return -1; + else + return 1; +} + /* Output any pending elements which have become next. As we output elements, constructor_unfilled_{fields,index} advances, which may cause other elements to become next; @@ -9354,25 +9545,18 @@ } else if (RECORD_OR_UNION_TYPE_P (constructor_type)) { - tree ctor_unfilled_bitpos, elt_bitpos; - /* If the current record is complete we are done. */ if (constructor_unfilled_fields == NULL_TREE) break; - ctor_unfilled_bitpos = bit_position (constructor_unfilled_fields); - elt_bitpos = bit_position (elt->purpose); - /* We can't compare fields here because there might be empty - fields in between. */ - if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos)) - { - constructor_unfilled_fields = elt->purpose; - output_init_element (input_location, elt->value, elt->origtype, - true, TREE_TYPE (elt->purpose), - elt->purpose, false, false, - braced_init_obstack); - } - else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos)) + int cmp = init_field_decl_cmp (constructor_unfilled_fields, + elt->purpose); + if (cmp == 0) + output_init_element (input_location, elt->value, elt->origtype, + true, TREE_TYPE (elt->purpose), + elt->purpose, false, false, + braced_init_obstack); + else if (cmp < 0) { /* Advance to the next smaller node. */ if (elt->left) @@ -9398,8 +9582,8 @@ elt = elt->parent; elt = elt->parent; if (elt - && (tree_int_cst_lt (ctor_unfilled_bitpos, - bit_position (elt->purpose)))) + && init_field_decl_cmp (constructor_unfilled_fields, + elt->purpose) < 0) { next = elt->purpose; break; @@ -9635,8 +9819,8 @@ constructor_unfilled_fields = DECL_CHAIN (constructor_fields); /* Skip any nameless bit fields. */ while (constructor_unfilled_fields != 0 - && DECL_C_BIT_FIELD (constructor_unfilled_fields) - && DECL_NAME (constructor_unfilled_fields) == 0) + && (DECL_UNNAMED_BIT_FIELD + (constructor_unfilled_fields))) constructor_unfilled_fields = DECL_CHAIN (constructor_unfilled_fields); } @@ -9645,8 +9829,7 @@ constructor_fields = DECL_CHAIN (constructor_fields); /* Skip any nameless bit fields at the beginning. */ while (constructor_fields != NULL_TREE - && DECL_C_BIT_FIELD (constructor_fields) - && DECL_NAME (constructor_fields) == NULL_TREE) + && DECL_UNNAMED_BIT_FIELD (constructor_fields)) constructor_fields = DECL_CHAIN (constructor_fields); } else if (TREE_CODE (constructor_type) == UNION_TYPE) @@ -9930,7 +10113,7 @@ { tree output = TREE_VALUE (tail); - output = c_fully_fold (output, false, NULL); + output = c_fully_fold (output, false, NULL, true); /* ??? Really, this should not be here. Users should be using a proper lvalue, dammit. But there's a long history of using casts @@ -9988,7 +10171,7 @@ mark it addressable. */ if (!allows_reg && allows_mem) { - input = c_fully_fold (input, false, NULL); + input = c_fully_fold (input, false, NULL, true); /* Strip the nops as we allow this case. FIXME, this really should be rejected or made deprecated. */ @@ -10076,7 +10259,6 @@ tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)), ret_stmt; bool no_warning = false; bool npc = false; - size_t rank = 0; /* Use the expansion point to handle cases such as returning NULL in a function returning void. */ @@ -10086,25 +10268,6 @@ warning_at (xloc, 0, "function declared %<noreturn%> has a %<return%> statement"); - if (flag_cilkplus && contains_array_notation_expr (retval)) - { - /* Array notations are allowed in a return statement if it is inside a - built-in array notation reduction function. */ - if (!find_rank (loc, retval, retval, false, &rank)) - return error_mark_node; - if (rank >= 1) - { - error_at (loc, "array notation expression cannot be used as a " - "return value"); - return error_mark_node; - } - } - if (flag_cilkplus && retval && contains_cilk_spawn_stmt (retval)) - { - error_at (loc, "use of %<_Cilk_spawn%> in a return statement is not " - "allowed"); - return error_mark_node; - } if (retval) { tree semantic_type = NULL_TREE; @@ -10122,13 +10285,13 @@ if (!retval) { current_function_returns_null = 1; - if ((warn_return_type || flag_isoc99) + if ((warn_return_type >= 0 || flag_isoc99) && valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE) { bool warned_here; if (flag_isoc99) warned_here = pedwarn - (loc, 0, + (loc, warn_return_type >= 0 ? OPT_Wreturn_type : 0, "%<return%> with no value, in function returning non-void"); else warned_here = warning_at @@ -10146,7 +10309,7 @@ bool warned_here; if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) warned_here = pedwarn - (xloc, 0, + (xloc, warn_return_type >= 0 ? OPT_Wreturn_type : 0, "%<return%> with a value, in function returning void"); else warned_here = pedwarn @@ -10355,7 +10518,7 @@ /* Add this new SWITCH_EXPR to the stack. */ cs = XNEW (struct c_switch); - cs->switch_expr = build3 (SWITCH_EXPR, orig_type, exp, NULL_TREE, NULL_TREE); + cs->switch_expr = build2 (SWITCH_EXPR, orig_type, exp, NULL_TREE); SET_EXPR_LOCATION (cs->switch_expr, switch_loc); cs->orig_type = orig_type; cs->cases = splay_tree_new (case_compare, NULL, NULL); @@ -10432,6 +10595,8 @@ type ? type : TREE_TYPE (cs->switch_expr), SWITCH_COND (cs->switch_expr), cs->bool_cond_p, cs->outside_range_p); + if (c_switch_covers_all_cases_p (cs->cases, TREE_TYPE (cs->switch_expr))) + SWITCH_ALL_CASES_P (cs->switch_expr) = 1; /* Pop the stack. */ c_switch_stack = cs->next; @@ -10450,35 +10615,6 @@ { tree stmt; - /* If the condition has array notations, then the rank of the then_block and - else_block must be either 0 or be equal to the rank of the condition. If - the condition does not have array notations then break them up as it is - broken up in a normal expression. */ - if (flag_cilkplus && contains_array_notation_expr (cond)) - { - size_t then_rank = 0, cond_rank = 0, else_rank = 0; - if (!find_rank (if_locus, cond, cond, true, &cond_rank)) - return; - if (then_block - && !find_rank (if_locus, then_block, then_block, true, &then_rank)) - return; - if (else_block - && !find_rank (if_locus, else_block, else_block, true, &else_rank)) - return; - if (cond_rank != then_rank && then_rank != 0) - { - error_at (if_locus, "rank-mismatch between if-statement%'s condition" - " and the then-block"); - return; - } - else if (cond_rank != else_rank && else_rank != 0) - { - error_at (if_locus, "rank-mismatch between if-statement%'s condition" - " and the else-block"); - return; - } - } - stmt = build3 (COND_EXPR, void_type_node, cond, then_block, else_block); SET_EXPR_LOCATION (stmt, if_locus); add_stmt (stmt); @@ -10496,9 +10632,6 @@ { tree entry = NULL, exit = NULL, t; - /* In theory could forbid cilk spawn for loop increment expression, - but it should work just fine. */ - /* If the condition is zero don't generate a loop construct. */ if (cond && integer_zerop (cond)) { @@ -10771,17 +10904,21 @@ continue_searching: if (TREE_CODE (last) == STATEMENT_LIST) { - tree_stmt_iterator i; + tree_stmt_iterator l = tsi_last (last); + + while (!tsi_end_p (l) && TREE_CODE (tsi_stmt (l)) == DEBUG_BEGIN_STMT) + tsi_prev (&l); /* This can happen with degenerate cases like ({ }). No value. */ - if (!TREE_SIDE_EFFECTS (last)) + if (tsi_end_p (l)) return body; /* If we're supposed to generate side effects warnings, process all of the statements except the last. */ if (warn_unused_value) { - for (i = tsi_start (last); !tsi_one_before_end_p (i); tsi_next (&i)) + for (tree_stmt_iterator i = tsi_start (last); + tsi_stmt (i) != tsi_stmt (l); tsi_next (&i)) { location_t tloc; tree t = tsi_stmt (i); @@ -10790,9 +10927,7 @@ emit_side_effect_warnings (tloc, t); } } - else - i = tsi_last (last); - last_p = tsi_stmt_ptr (i); + last_p = tsi_stmt_ptr (l); last = *last_p; } @@ -10811,7 +10946,9 @@ /* In the case that the BIND_EXPR is not necessary, return the expression out from inside it. */ - if (last == BIND_EXPR_BODY (body) + if ((last == BIND_EXPR_BODY (body) + /* Skip nested debug stmts. */ + || last == expr_first (BIND_EXPR_BODY (body))) && BIND_EXPR_VARS (body) == NULL) { /* Even if this looks constant, do not allow it in a constant @@ -10935,6 +11072,38 @@ return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec); } +/* Subclass of range_label for labelling the type of EXPR when reporting + a type mismatch between EXPR and OTHER_EXPR. + Either or both of EXPR and OTHER_EXPR could be NULL. */ + +class maybe_range_label_for_tree_type_mismatch : public range_label +{ + public: + maybe_range_label_for_tree_type_mismatch (tree expr, tree other_expr) + : m_expr (expr), m_other_expr (other_expr) + { + } + + label_text get_text (unsigned range_idx) const FINAL OVERRIDE + { + if (m_expr == NULL_TREE + || !EXPR_P (m_expr)) + return label_text (NULL, false); + tree expr_type = TREE_TYPE (m_expr); + + tree other_type = NULL_TREE; + if (m_other_expr && EXPR_P (m_other_expr)) + other_type = TREE_TYPE (m_other_expr); + + range_label_for_type_mismatch inner (expr_type, other_type); + return inner.get_text (range_idx); + } + + private: + tree m_expr; + tree m_other_expr; +}; + /* Build a binary-operation expression without default conversions. CODE is the kind of expression to build. LOCATION is the operator's location. @@ -11062,18 +11231,9 @@ op1 = default_conversion (op1); } - /* When Cilk Plus is enabled and there are array notations inside op0, then - we check to see if there are builtin array notation functions. If - so, then we take on the type of the array notation inside it. */ - if (flag_cilkplus && contains_array_notation_expr (op0)) - orig_type0 = type0 = find_correct_array_notation_type (op0); - else - orig_type0 = type0 = TREE_TYPE (op0); - - if (flag_cilkplus && contains_array_notation_expr (op1)) - orig_type1 = type1 = find_correct_array_notation_type (op1); - else - orig_type1 = type1 = TREE_TYPE (op1); + orig_type0 = type0 = TREE_TYPE (op0); + + orig_type1 = type1 = TREE_TYPE (op1); /* The expression codes of the data types of the arguments tell us whether the arguments are integers, floating, pointers, etc. */ @@ -11117,6 +11277,20 @@ case EXACT_DIV_EXPR: may_need_excess_precision = true; break; + + case EQ_EXPR: + case NE_EXPR: + case LE_EXPR: + case GE_EXPR: + case LT_EXPR: + case GT_EXPR: + /* Excess precision for implicit conversions of integers to + floating point in C11 and later. */ + may_need_excess_precision = (flag_isoc11 + && (ANY_INTEGRAL_TYPE_P (type0) + || ANY_INTEGRAL_TYPE_P (type1))); + break; + default: may_need_excess_precision = false; break; @@ -11216,7 +11390,7 @@ if (code0 == POINTER_TYPE && code1 == POINTER_TYPE && comp_target_types (location, type0, type1)) { - ret = pointer_diff (location, op0, op1); + ret = pointer_diff (location, op0, op1, &instrument_expr); goto return_build_binary_op; } /* Handle pointer minus int. Just like pointer plus int. */ @@ -11371,13 +11545,15 @@ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE - && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) + && known_eq (TYPE_VECTOR_SUBPARTS (type0), + TYPE_VECTOR_SUBPARTS (type1))) { result_type = type0; converted = 1; } else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE - || code0 == VECTOR_TYPE) + || (code0 == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)) && code1 == INTEGER_TYPE) { doing_shift = true; @@ -11428,13 +11604,15 @@ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE - && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) + && known_eq (TYPE_VECTOR_SUBPARTS (type0), + TYPE_VECTOR_SUBPARTS (type1))) { result_type = type0; converted = 1; } else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE - || code0 == VECTOR_TYPE) + || (code0 == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)) && code1 == INTEGER_TYPE) { doing_shift = true; @@ -11502,7 +11680,8 @@ return error_mark_node; } - if (TYPE_VECTOR_SUBPARTS (type0) != TYPE_VECTOR_SUBPARTS (type1)) + if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0), + TYPE_VECTOR_SUBPARTS (type1))) { error_at (location, "comparing vectors with different " "number of elements"); @@ -11527,6 +11706,13 @@ intt = c_common_type_for_size (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))), 0); + if (!intt) + { + error_at (location, "could not find an integer type " + "of the same size as %qT", + TREE_TYPE (type0)); + return error_mark_node; + } result_type = build_opaque_vector_type (intt, TYPE_VECTOR_SUBPARTS (type0)); converted = 1; @@ -11662,7 +11848,8 @@ return error_mark_node; } - if (TYPE_VECTOR_SUBPARTS (type0) != TYPE_VECTOR_SUBPARTS (type1)) + if (maybe_ne (TYPE_VECTOR_SUBPARTS (type0), + TYPE_VECTOR_SUBPARTS (type1))) { error_at (location, "comparing vectors with different " "number of elements"); @@ -11687,6 +11874,13 @@ intt = c_common_type_for_size (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))), 0); + if (!intt) + { + error_at (location, "could not find an integer type " + "of the same size as %qT", + TREE_TYPE (type0)); + return error_mark_node; + } result_type = build_opaque_vector_type (intt, TYPE_VECTOR_SUBPARTS (type0)); converted = 1; @@ -11766,6 +11960,17 @@ result_type = type1; pedwarn (location, 0, "comparison between pointer and integer"); } + + if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE) + && sanitize_flags_p (SANITIZE_POINTER_COMPARE)) + { + op0 = save_expr (op0); + op1 = save_expr (op1); + + tree tt = builtin_decl_explicit (BUILT_IN_ASAN_POINTER_COMPARE); + instrument_expr = build_call_expr_loc (location, tt, 2, op0, op1); + } + if ((TREE_CODE (TREE_TYPE (orig_op0)) == BOOLEAN_TYPE || truth_value_p (TREE_CODE (orig_op0))) ^ (TREE_CODE (TREE_TYPE (orig_op1)) == BOOLEAN_TYPE @@ -11785,8 +11990,11 @@ || !vector_types_compatible_elements_p (type0, type1))) { gcc_rich_location richloc (location); - richloc.maybe_add_expr (orig_op0); - richloc.maybe_add_expr (orig_op1); + maybe_range_label_for_tree_type_mismatch + label_for_op0 (orig_op0, orig_op1), + label_for_op1 (orig_op1, orig_op0); + richloc.maybe_add_expr (orig_op0, &label_for_op0); + richloc.maybe_add_expr (orig_op1, &label_for_op1); binary_op_error (&richloc, code, type0, type1); return error_mark_node; } @@ -12027,8 +12235,11 @@ if (!result_type) { gcc_rich_location richloc (location); - richloc.maybe_add_expr (orig_op0); - richloc.maybe_add_expr (orig_op1); + maybe_range_label_for_tree_type_mismatch + label_for_op0 (orig_op0, orig_op1), + label_for_op1 (orig_op1, orig_op0); + richloc.maybe_add_expr (orig_op0, &label_for_op0); + richloc.maybe_add_expr (orig_op1, &label_for_op1); binary_op_error (&richloc, code, TREE_TYPE (op0), TREE_TYPE (op1)); return error_mark_node; } @@ -12754,7 +12965,7 @@ } if (tem) first = build2 (COMPOUND_EXPR, TREE_TYPE (first), tem, first); - first = c_fully_fold (first, false, NULL); + first = c_fully_fold (first, false, NULL, true); OMP_CLAUSE_DECL (c) = first; } else @@ -13317,38 +13528,21 @@ "clause on %<simd%> or %<for%> constructs"); OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT; } - if (ort & C_ORT_CILK) - { - if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) - && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (t)) - && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE) - { - error_at (OMP_CLAUSE_LOCATION (c), - "linear clause applied to non-integral, " - "non-floating, non-pointer variable with type %qT", - TREE_TYPE (t)); - remove = true; - break; - } - } - else - { - if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) - && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE) - { - error_at (OMP_CLAUSE_LOCATION (c), - "linear clause applied to non-integral non-pointer " - "variable with type %qT", TREE_TYPE (t)); - remove = true; - break; - } - if (TYPE_ATOMIC (TREE_TYPE (t))) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%<_Atomic%> %qD in %<linear%> clause", t); - remove = true; - break; - } + if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) + && TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE) + { + error_at (OMP_CLAUSE_LOCATION (c), + "linear clause applied to non-integral non-pointer " + "variable with type %qT", TREE_TYPE (t)); + remove = true; + break; + } + if (TYPE_ATOMIC (TREE_TYPE (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<_Atomic%> %qD in %<linear%> clause", t); + remove = true; + break; } if (ort == C_ORT_OMP_DECLARE_SIMD) { @@ -13880,7 +14074,6 @@ case OMP_CLAUSE_SIMD: case OMP_CLAUSE_HINT: case OMP_CLAUSE_DEFAULTMAP: - case OMP_CLAUSE__CILK_FOR_COUNT_: case OMP_CLAUSE_NUM_GANGS: case OMP_CLAUSE_NUM_WORKERS: case OMP_CLAUSE_VECTOR_LENGTH: @@ -13893,6 +14086,8 @@ case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: case OMP_CLAUSE_TILE: + case OMP_CLAUSE_IF_PRESENT: + case OMP_CLAUSE_FINALIZE: pc = &OMP_CLAUSE_CHAIN (c); continue; @@ -14432,28 +14627,6 @@ return false; } -/* Inserts "cleanup" functions after the function-body of FNDECL. FNDECL is a - spawn-helper and BODY is the newly created body for FNDECL. */ - -void -cilk_install_body_with_frame_cleanup (tree fndecl, tree body, void *w) -{ - tree list = alloc_stmt_list (); - tree frame = make_cilk_frame (fndecl); - tree dtor = create_cilk_function_exit (frame, false, true); - add_local_decl (cfun, frame); - - DECL_SAVED_TREE (fndecl) = list; - - tree body_list = alloc_stmt_list (); - cilk_outline (fndecl, &body, (struct wrapper_data *) w); - body = fold_build_cleanup_point_expr (void_type_node, body); - - append_to_statement_list (body, &body_list); - append_to_statement_list (build_stmt (EXPR_LOCATION (body), TRY_FINALLY_EXPR, - body_list, dtor), &list); -} - /* Returns true when the function declaration FNDECL is implicit, introduced as a result of a call to an otherwise undeclared function, and false otherwise. */