X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-common.c;h=942961d95b2565104455ee8f5f51304fbd6589ba;hb=f80e77555daaf6c32840c28b9d94f61ba47aa173;hp=20b24f0c3c288a1d227da9801b467a221f4cbc4d;hpb=e0559d69f5cf440c6b68bb33f4f9982dae4fe395;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-common.c b/gcc/c-common.c index 20b24f0c3c2..942961d95b2 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1,6 +1,6 @@ /* Subroutines shared by all languages that are variants of C. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -30,8 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "c-pragma.h" #include "rtl.h" #include "ggc.h" -#include "varray.h" -#include "expr.h" +#include "expr.h" /* For vector_mode_valid_p */ #include "c-common.h" #include "tm_p.h" #include "obstack.h" @@ -49,7 +48,6 @@ along with GCC; see the file COPYING3. If not see #include "real.h" #include "cgraph.h" #include "target-def.h" -#include "gimple.h" #include "fixed-value.h" #include "libfuncs.h" @@ -280,10 +278,14 @@ int flag_cond_mismatch; int flag_isoc94; -/* Nonzero means use the ISO C99 dialect of C. */ +/* Nonzero means use the ISO C99 (or C1X) dialect of C. */ int flag_isoc99; +/* Nonzero means use the ISO C1X dialect of C. */ + +int flag_isoc1x; + /* Nonzero means that we have builtin functions, and main is an int. */ int flag_hosted = 1; @@ -424,10 +426,6 @@ int flag_threadsafe_statics = 1; int flag_pretty_templates = 1; -/* Nonzero means warn about implicit declarations. */ - -int warn_implicit = 1; - /* Maximum template instantiation depth. This limit exists to limit the time it takes to notice infinite template instantiations; the default value of 1024 is likely to be in the next C++ standard. */ @@ -530,6 +528,7 @@ static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *); static tree handle_target_attribute (tree *, tree, tree, int, bool *); static tree handle_optimize_attribute (tree *, tree, tree, int, bool *); +static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *); static void check_function_nonnull (tree, int, tree *); static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT); @@ -564,6 +563,7 @@ const struct c_common_resword c_common_reswords[] = { "_Fract", RID_FRACT, D_CONLY | D_EXT }, { "_Accum", RID_ACCUM, D_CONLY | D_EXT }, { "_Sat", RID_SAT, D_CONLY | D_EXT }, + { "_Static_assert", RID_STATIC_ASSERT, D_CONLY }, { "__FUNCTION__", RID_FUNCTION_NAME, 0 }, { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 }, { "__alignof", RID_ALIGNOF, 0 }, @@ -657,6 +657,7 @@ const struct c_common_resword c_common_reswords[] = { "mutable", RID_MUTABLE, D_CXXONLY | D_CXXWARN }, { "namespace", RID_NAMESPACE, D_CXXONLY | D_CXXWARN }, { "new", RID_NEW, D_CXXONLY | D_CXXWARN }, + { "nullptr", RID_NULLPTR, D_CXXONLY | D_CXX0X | D_CXXWARN }, { "operator", RID_OPERATOR, D_CXXONLY | D_CXXWARN }, { "private", RID_PRIVATE, D_CXX_OBJC | D_CXXWARN }, { "protected", RID_PROTECTED, D_CXX_OBJC | D_CXXWARN }, @@ -829,6 +830,10 @@ const struct attribute_spec c_common_attribute_table[] = handle_target_attribute }, { "optimize", 1, -1, true, false, false, handle_optimize_attribute }, + /* For internal use (marking of builtins and runtime functions) only. + The name contains space to prevent its usage in source code. */ + { "fn spec", 1, 1, false, true, true, + handle_fnspec_attribute }, { NULL, 0, 0, false, false, false, NULL } }; @@ -1542,7 +1547,7 @@ decl_constant_value_for_optimization (tree exp) void constant_expression_warning (tree value) { - if (warn_overflow && pedantic + if (warn_overflow && pedantic && (TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST || TREE_CODE (value) == FIXED_CST || TREE_CODE (value) == VECTOR_CST @@ -1585,12 +1590,12 @@ overflow_warning (location_t loc, tree value) case INTEGER_CST: warning_at (loc, OPT_Woverflow, "integer overflow in expression"); break; - + case REAL_CST: warning_at (loc, OPT_Woverflow, "floating point overflow in expression"); break; - + case FIXED_CST: warning_at (loc, OPT_Woverflow, "fixed-point overflow in expression"); break; @@ -1598,7 +1603,7 @@ overflow_warning (location_t loc, tree value) case VECTOR_CST: warning_at (loc, OPT_Woverflow, "vector overflow in expression"); break; - + case COMPLEX_CST: if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST) warning_at (loc, OPT_Woverflow, @@ -1620,7 +1625,7 @@ overflow_warning (location_t loc, tree value) had CODE_LEFT and CODE_RIGHT, into an expression of type TYPE. */ void warn_logical_operator (location_t location, enum tree_code code, tree type, - enum tree_code code_left, tree op_left, + enum tree_code code_left, tree op_left, enum tree_code ARG_UNUSED (code_right), tree op_right) { int or_op = (code == TRUTH_ORIF_EXPR || code == TRUTH_OR_EXPR); @@ -1677,12 +1682,12 @@ warn_logical_operator (location_t location, enum tree_code code, tree type, if (rhs && TREE_CODE (rhs) == C_MAYBE_CONST_EXPR) rhs = C_MAYBE_CONST_EXPR_EXPR (rhs); - + /* If this is an OR operation, invert both sides; we will invert again at the end. */ if (or_op) in0_p = !in0_p, in1_p = !in1_p; - + /* If both expressions are the same, if we can merge the ranges, and we can build the range test, return it or it inverted. */ if (lhs && rhs && operand_equal_p (lhs, rhs, 0) @@ -1741,7 +1746,7 @@ strict_aliasing_warning (tree otype, tree type, tree expr) } else { - /* warn_strict_aliasing >= 3. This includes the default (3). + /* warn_strict_aliasing >= 3. This includes the default (3). Only warn if the cast is dereferenced immediately. */ alias_set_type set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0))); @@ -1806,7 +1811,7 @@ check_main_parameter_types (tree decl) { case 1: if (TYPE_MAIN_VARIANT (type) != integer_type_node) - pedwarn (input_location, OPT_Wmain, "first argument of %q+D should be %", + pedwarn (input_location, OPT_Wmain, "first argument of %q+D should be %", decl); break; @@ -1901,7 +1906,7 @@ vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note) both args are zero-extended or both are sign-extended. Otherwise, we might change the result. Eg, (short)-1 | (unsigned short)-1 is (int)-1 - but calculated in (unsigned short) it would be (unsigned short)-1. + but calculated in (unsigned short) it would be (unsigned short)-1. */ tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise) { @@ -1916,13 +1921,13 @@ tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise) 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. */ @@ -1937,7 +1942,7 @@ tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise) /* 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) != result_type) @@ -1946,18 +1951,18 @@ tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise) == TYPE_PRECISION (TREE_TYPE (arg1))) && TREE_TYPE (op1) != result_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 (bitwise) 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. */ @@ -2036,7 +2041,7 @@ conversion_warning (tree type, tree expr) /* Conversion from boolean to a signed:1 bit-field (which only can hold the values 0 and -1) doesn't lose information - but it does change the value. */ - if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type)) + if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type)) warning (OPT_Wconversion, "conversion to %qT from boolean expression", type); return; @@ -2057,7 +2062,7 @@ conversion_warning (tree type, tree expr) && TREE_CODE (type) == INTEGER_TYPE && !int_fits_type_p (expr, type)) { - if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type) + if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type) && tree_int_cst_sgn (expr) < 0) warning (OPT_Wsign_conversion, "negative integer implicitly converted to unsigned type"); @@ -2102,7 +2107,7 @@ conversion_warning (tree type, tree expr) tree op1 = TREE_OPERAND (expr, 1); tree op2 = TREE_OPERAND (expr, 2); - if ((TREE_CODE (op1) == REAL_CST || TREE_CODE (op1) == INTEGER_CST + if ((TREE_CODE (op1) == REAL_CST || TREE_CODE (op1) == INTEGER_CST || TREE_CODE (op1) == COND_EXPR) && (TREE_CODE (op2) == REAL_CST || TREE_CODE (op2) == INTEGER_CST || TREE_CODE (op2) == COND_EXPR)) @@ -2129,15 +2134,15 @@ conversion_warning (tree type, tree expr) expr_type = TREE_TYPE (expr); /* Don't warn for short y; short x = ((int)y & 0xff); */ - if (TREE_CODE (expr) == BIT_AND_EXPR - || TREE_CODE (expr) == BIT_IOR_EXPR + if (TREE_CODE (expr) == BIT_AND_EXPR + || TREE_CODE (expr) == BIT_IOR_EXPR || TREE_CODE (expr) == BIT_XOR_EXPR) { /* If both args were extended from a shortest type, use that type if that is safe. */ - expr_type = shorten_binary_op (expr_type, - TREE_OPERAND (expr, 0), - TREE_OPERAND (expr, 1), + expr_type = shorten_binary_op (expr_type, + TREE_OPERAND (expr, 0), + TREE_OPERAND (expr, 1), /* bitwise */1); if (TREE_CODE (expr) == BIT_AND_EXPR) @@ -2155,13 +2160,13 @@ conversion_warning (tree type, tree expr) && int_fits_type_p (op0, c_common_unsigned_type (type))) || (TREE_CODE (op1) == INTEGER_CST && int_fits_type_p (op1, c_common_signed_type (type)) - && int_fits_type_p (op1, + && int_fits_type_p (op1, c_common_unsigned_type (type)))) return; /* If constant is unsigned and fits in the target type, then the result will also fit. */ else if ((TREE_CODE (op0) == INTEGER_CST - && unsigned0 + && unsigned0 && int_fits_type_p (op0, type)) || (TREE_CODE (op1) == INTEGER_CST && unsigned1 @@ -2170,7 +2175,7 @@ conversion_warning (tree type, tree expr) } } /* Warn for integer types converted to smaller integer types. */ - if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type)) + if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type)) give_warning = true; /* When they are the same width but different signedness, @@ -2192,12 +2197,17 @@ conversion_warning (tree type, tree expr) else if (TREE_CODE (expr_type) == INTEGER_TYPE && TREE_CODE (type) == REAL_TYPE) { - tree type_low_bound = TYPE_MIN_VALUE (expr_type); - tree type_high_bound = TYPE_MAX_VALUE (expr_type); - REAL_VALUE_TYPE real_low_bound - = real_value_from_int_cst (0, type_low_bound); - REAL_VALUE_TYPE real_high_bound - = real_value_from_int_cst (0, type_high_bound); + tree type_low_bound, type_high_bound; + REAL_VALUE_TYPE real_low_bound, real_high_bound; + + /* Don't warn about char y = 0xff; float x = (int) y; */ + expr = get_unwidened (expr, 0); + expr_type = TREE_TYPE (expr); + + type_low_bound = TYPE_MIN_VALUE (expr_type); + type_high_bound = TYPE_MAX_VALUE (expr_type); + real_low_bound = real_value_from_int_cst (0, type_low_bound); + real_high_bound = real_value_from_int_cst (0, type_high_bound); if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound) || !exact_real_truncate (TYPE_MODE (type), &real_high_bound)) @@ -2245,7 +2255,7 @@ warnings_for_convert_and_check (tree type, tree expr, tree result) else conversion_warning (type, expr); } - else if (!int_fits_type_p (expr, c_common_unsigned_type (type))) + else if (!int_fits_type_p (expr, c_common_unsigned_type (type))) warning (OPT_Woverflow, "overflow in implicit constant conversion"); /* No warning for converting 0x80000000 to int. */ @@ -2294,7 +2304,7 @@ convert_and_check (tree type, tree expr) if (TREE_TYPE (expr) == type) return expr; - + result = convert (type, expr); if (c_inhibit_evaluation_warnings == 0 @@ -2600,7 +2610,7 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp, { call_expr_arg_iterator iter; tree arg; - tmp_before = tmp_nosp = 0; + tmp_before = tmp_nosp = 0; verify_tree (CALL_EXPR_FN (x), &tmp_before, &tmp_nosp, NULL_TREE); FOR_EACH_CALL_EXPR_ARG (arg, iter, x) { @@ -3685,7 +3695,7 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, && !(TREE_CODE (primop0) == INTEGER_CST && !TREE_OVERFLOW (convert (c_common_signed_type (type), primop0)))) - warning (OPT_Wtype_limits, + warning (OPT_Wtype_limits, "comparison of unsigned expression >= 0 is always true"); value = truthvalue_true_node; break; @@ -3695,7 +3705,7 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, && !(TREE_CODE (primop0) == INTEGER_CST && !TREE_OVERFLOW (convert (c_common_signed_type (type), primop0)))) - warning (OPT_Wtype_limits, + warning (OPT_Wtype_limits, "comparison of unsigned expression < 0 is always false"); value = truthvalue_false_node; break; @@ -3737,19 +3747,19 @@ pointer_int_sum (location_t loc, enum tree_code resultcode, if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE) { - pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, "pointer of type % used in arithmetic"); size_exp = integer_one_node; } else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE) { - pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, "pointer to a function used in arithmetic"); size_exp = integer_one_node; } else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE) { - pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, "pointer to member function used in arithmetic"); size_exp = integer_one_node; } @@ -3801,12 +3811,18 @@ pointer_int_sum (location_t loc, enum tree_code resultcode, TYPE_UNSIGNED (sizetype)), intop); /* Replace the integer argument with a suitable product by the object size. - Do this multiplication as signed, then convert to the appropriate - type for the pointer operation. */ - intop = convert (sizetype, - build_binary_op (loc, - MULT_EXPR, intop, - convert (TREE_TYPE (intop), size_exp), 1)); + Do this multiplication as signed, then convert to the appropriate type + for the pointer operation and disregard an overflow that occured only + because of the sign-extension change in the latter conversion. */ + { + tree t = build_binary_op (loc, + MULT_EXPR, intop, + convert (TREE_TYPE (intop), size_exp), 1); + intop = convert (sizetype, t); + if (TREE_OVERFLOW_P (intop) && !TREE_OVERFLOW (t)) + intop = build_int_cst_wide (TREE_TYPE (intop), TREE_INT_CST_LOW (intop), + TREE_INT_CST_HIGH (intop)); + } /* Create the sum or difference. */ if (resultcode == MINUS_EXPR) @@ -3912,7 +3928,7 @@ c_common_truthvalue_conversion (location_t location, tree expr) if (TREE_TYPE (expr) == truthvalue_type_node) return expr; expr = build2 (TREE_CODE (expr), truthvalue_type_node, - c_common_truthvalue_conversion (location, + c_common_truthvalue_conversion (location, TREE_OPERAND (expr, 0)), c_common_truthvalue_conversion (location, TREE_OPERAND (expr, 1))); @@ -4005,7 +4021,7 @@ c_common_truthvalue_conversion (location_t location, tree expr) { expr = build2 (COMPOUND_EXPR, truthvalue_type_node, TREE_OPERAND (expr, 1), - c_common_truthvalue_conversion + c_common_truthvalue_conversion (location, TREE_OPERAND (expr, 0))); goto ret; } @@ -4361,7 +4377,7 @@ c_sizeof_or_alignof_type (location_t loc, if (is_sizeof) { if (complain && (pedantic || warn_pointer_arith)) - pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, "invalid application of % to a function type"); else if (!complain) return error_mark_node; @@ -4374,7 +4390,7 @@ c_sizeof_or_alignof_type (location_t loc, { if (type_code == VOID_TYPE && complain && (pedantic || warn_pointer_arith)) - pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, + pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, "invalid application of %qs to a void type", op_name); else if (!complain) return error_mark_node; @@ -4385,7 +4401,7 @@ c_sizeof_or_alignof_type (location_t loc, if (complain) error_at (loc, "invalid application of %qs to incomplete type %qT ", op_name, type); - value = size_zero_node; + return error_mark_node; } else { @@ -4770,7 +4786,7 @@ c_common_nodes_and_builtins (void) /* Only supported decimal floating point extension if the target actually supports underlying modes. */ - if (targetm.scalar_mode_supported_p (SDmode) + if (targetm.scalar_mode_supported_p (SDmode) && targetm.scalar_mode_supported_p (DDmode) && targetm.scalar_mode_supported_p (TDmode)) { @@ -5332,7 +5348,7 @@ c_add_case_label (location_t loc, splay_tree cases, tree cond, tree orig_type, /* Case ranges are a GNU extension. */ if (high_value) - pedwarn (loc, OPT_pedantic, + pedwarn (loc, OPT_pedantic, "range expressions in switch statements are non-standard"); type = TREE_TYPE (cond); @@ -5658,7 +5674,7 @@ finish_label_address_expr (tree label, location_t loc) { TREE_USED (label) = 1; result = build1 (ADDR_EXPR, ptr_type_node, label); - /* The current function in not necessarily uninlinable. + /* The current function is not necessarily uninlinable. Computed gotos are incompatible with inlining, but the value here could be used only in a diagnostic, for example. */ protected_set_expr_location (result, loc); @@ -5798,6 +5814,20 @@ c_init_attributes (void) #undef DEF_ATTR_TREE_LIST } +/* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain + identifier as an argument, so the front end shouldn't look it up. */ + +bool +attribute_takes_identifier_p (const_tree attr_id) +{ + if (is_attribute_p ("mode", attr_id) + || is_attribute_p ("format", attr_id) + || is_attribute_p ("cleanup", attr_id)) + return true; + else + return targetm.attribute_takes_identifier_p (attr_id); +} + /* Attribute handlers common to C front ends. */ /* Handle a "packed" attribute; arguments as in @@ -6116,6 +6146,8 @@ handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args), { TREE_USED (node) = 1; DECL_PRESERVE_P (node) = 1; + if (TREE_CODE (node) == VAR_DECL) + DECL_READ_P (node) = 1; } else { @@ -6142,7 +6174,12 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args), || TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == LABEL_DECL || TREE_CODE (decl) == TYPE_DECL) - TREE_USED (decl) = 1; + { + TREE_USED (decl) = 1; + if (TREE_CODE (decl) == VAR_DECL + || TREE_CODE (decl) == PARM_DECL) + DECL_READ_P (decl) = 1; + } else { warning (OPT_Wattributes, "%qE attribute ignored", name); @@ -6247,7 +6284,7 @@ handle_transparent_union_attribute (tree *node, tree name, *node = type = build_duplicate_type (type); } - TYPE_TRANSPARENT_UNION (type) = 1; + TYPE_TRANSPARENT_AGGR (type) = 1; return NULL_TREE; } @@ -6269,7 +6306,7 @@ get_priority (tree args, bool is_destructor) if (!args) return DEFAULT_INIT_PRIORITY; - + if (!SUPPORTS_INIT_PRIORITY) { if (is_destructor) @@ -6293,12 +6330,12 @@ get_priority (tree args, bool is_destructor) if (is_destructor) warning (0, "destructor priorities from 0 to %d are reserved " - "for the implementation", + "for the implementation", MAX_RESERVED_INIT_PRIORITY); else warning (0, "constructor priorities from 0 to %d are reserved " - "for the implementation", + "for the implementation", MAX_RESERVED_INIT_PRIORITY); } return pri; @@ -6578,7 +6615,7 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args, && current_function_decl != NULL_TREE && !TREE_STATIC (decl)) { - error_at (DECL_SOURCE_LOCATION (decl), + error_at (DECL_SOURCE_LOCATION (decl), "section attribute cannot be specified for " "local variables"); *no_add_attrs = true; @@ -6660,10 +6697,12 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args, } else if (is_type) { + if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) + /* OK, modify the type in place. */; /* If we have a TYPE_DECL, then copy the type, so that we don't accidentally modify a builtin type. See pushdecl. */ - if (decl && TREE_TYPE (decl) != error_mark_node - && DECL_ORIGINAL_TYPE (decl) == NULL_TREE) + else if (decl && TREE_TYPE (decl) != error_mark_node + && DECL_ORIGINAL_TYPE (decl) == NULL_TREE) { tree tt = TREE_TYPE (decl); *type = build_variant_type_copy (*type); @@ -6672,7 +6711,7 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args, TREE_USED (*type) = TREE_USED (decl); TREE_TYPE (decl) = *type; } - else if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) + else *type = build_variant_type_copy (*type); TYPE_ALIGN (*type) = (1U << i) * BITS_PER_UNIT; @@ -6744,11 +6783,11 @@ handle_alias_attribute (tree *node, tree name, tree args, *no_add_attrs = true; } else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) - || (TREE_CODE (decl) != FUNCTION_DECL + || (TREE_CODE (decl) != FUNCTION_DECL && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) /* A static variable declaration is always a tentative definition, but the alias is a non-tentative definition which overrides. */ - || (TREE_CODE (decl) != FUNCTION_DECL + || (TREE_CODE (decl) != FUNCTION_DECL && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl))) { error ("%q+D defined both normally and as an alias", decl); @@ -7091,11 +7130,11 @@ handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args, tree position = TREE_VALUE (args); if (TREE_CODE (position) != INTEGER_CST - || TREE_INT_CST_HIGH (position) + || TREE_INT_CST_HIGH (position) || TREE_INT_CST_LOW (position) < 1 || TREE_INT_CST_LOW (position) > arg_count ) { - warning (OPT_Wattributes, + warning (OPT_Wattributes, "alloc_size parameter outside range"); *no_add_attrs = true; return NULL_TREE; @@ -7104,6 +7143,20 @@ handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args, return NULL_TREE; } +/* Handle a "fn spec" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name), + tree args, int ARG_UNUSED (flags), + bool *no_add_attrs ATTRIBUTE_UNUSED) +{ + gcc_assert (args + && TREE_CODE (TREE_VALUE (args)) == STRING_CST + && !TREE_CHAIN (args)); + return NULL_TREE; +} + /* Handle a "returns_twice" attribute; arguments as in struct attribute_spec.handler. */ @@ -7653,7 +7706,7 @@ handle_sentinel_attribute (tree *node, tree name, tree args, if (TREE_CODE (position) != INTEGER_CST) { - warning (OPT_Wattributes, + warning (OPT_Wattributes, "requested position is not an integer constant"); *no_add_attrs = true; } @@ -7679,10 +7732,10 @@ handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name), bool * ARG_UNUSED (no_add_attrs)) { tree params; - + /* Ensure we have a function type. */ gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); - + params = TYPE_ARG_TYPES (*node); while (params && ! VOID_TYPE_P (TREE_VALUE (params))) params = TREE_CHAIN (params); @@ -7975,21 +8028,24 @@ check_function_arguments_recurse (void (*callback) (*callback) (ctx, param, param_num); } -/* Checks the number of arguments NARGS against the required number - REQUIRED and issues an error if there is a mismatch. Returns true - if the number of arguments is correct, otherwise false. */ +/* Checks for a builtin function FNDECL that the number of arguments + NARGS against the required number REQUIRED and issues an error if + there is a mismatch. Returns true if the number of arguments is + correct, otherwise false. */ static bool -validate_nargs (tree fndecl, int nargs, int required) +builtin_function_validate_nargs (tree fndecl, int nargs, int required) { if (nargs < required) { - error ("not enough arguments to function %qE", fndecl); + error_at (input_location, + "not enough arguments to function %qE", fndecl); return false; } else if (nargs > required) { - error ("too many arguments to function %qE", fndecl); + error_at (input_location, + "too many arguments to function %qE", fndecl); return false; } return true; @@ -8008,14 +8064,14 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args) switch (DECL_FUNCTION_CODE (fndecl)) { case BUILT_IN_CONSTANT_P: - return validate_nargs (fndecl, nargs, 1); + return builtin_function_validate_nargs (fndecl, nargs, 1); case BUILT_IN_ISFINITE: case BUILT_IN_ISINF: case BUILT_IN_ISINF_SIGN: case BUILT_IN_ISNAN: case BUILT_IN_ISNORMAL: - if (validate_nargs (fndecl, nargs, 1)) + if (builtin_function_validate_nargs (fndecl, nargs, 1)) { if (TREE_CODE (TREE_TYPE (args[0])) != REAL_TYPE) { @@ -8033,7 +8089,7 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args) case BUILT_IN_ISLESSEQUAL: case BUILT_IN_ISLESSGREATER: case BUILT_IN_ISUNORDERED: - if (validate_nargs (fndecl, nargs, 2)) + if (builtin_function_validate_nargs (fndecl, nargs, 2)) { enum tree_code code0, code1; code0 = TREE_CODE (TREE_TYPE (args[0])); @@ -8051,10 +8107,10 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args) return false; case BUILT_IN_FPCLASSIFY: - if (validate_nargs (fndecl, nargs, 6)) + if (builtin_function_validate_nargs (fndecl, nargs, 6)) { unsigned i; - + for (i=0; i<5; i++) if (TREE_CODE (args[i]) != INTEGER_CST) { @@ -8166,7 +8222,7 @@ catenate_strings (const char *lhs, const char *rhs_start, int rhs_size) TOKEN, which had the associated VALUE. */ void -c_parse_error (const char *gmsgid, enum cpp_ttype token_type, +c_parse_error (const char *gmsgid, enum cpp_ttype token_type, tree value, unsigned char token_flags) { #define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2)) @@ -8175,8 +8231,8 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type, if (token_type == CPP_EOF) message = catenate_messages (gmsgid, " at end of input"); - else if (token_type == CPP_CHAR - || token_type == CPP_WCHAR + else if (token_type == CPP_CHAR + || token_type == CPP_WCHAR || token_type == CPP_CHAR16 || token_type == CPP_CHAR32) { @@ -8208,8 +8264,8 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type, free (message); message = NULL; } - else if (token_type == CPP_STRING - || token_type == CPP_WSTRING + else if (token_type == CPP_STRING + || token_type == CPP_WSTRING || token_type == CPP_STRING16 || token_type == CPP_STRING32 || token_type == CPP_UTF8STRING) @@ -8245,8 +8301,52 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type, #undef catenate_messages } +/* Mapping for cpp message reasons to the options that enable them. */ + +struct reason_option_codes_t +{ + const int reason; /* cpplib message reason. */ + const int option_code; /* gcc option that controls this message. */ +}; + +static const struct reason_option_codes_t option_codes[] = { + {CPP_W_DEPRECATED, OPT_Wdeprecated}, + {CPP_W_COMMENTS, OPT_Wcomments}, + {CPP_W_TRIGRAPHS, OPT_Wtrigraphs}, + {CPP_W_MULTICHAR, OPT_Wmultichar}, + {CPP_W_TRADITIONAL, OPT_Wtraditional}, + {CPP_W_LONG_LONG, OPT_Wlong_long}, + {CPP_W_ENDIF_LABELS, OPT_Wendif_labels}, + {CPP_W_VARIADIC_MACROS, OPT_Wvariadic_macros}, + {CPP_W_BUILTIN_MACRO_REDEFINED, OPT_Wbuiltin_macro_redefined}, + {CPP_W_UNDEF, OPT_Wundef}, + {CPP_W_UNUSED_MACROS, OPT_Wunused_macros}, + {CPP_W_CXX_OPERATOR_NAMES, OPT_Wc___compat}, + {CPP_W_NORMALIZE, OPT_Wnormalized_}, + {CPP_W_INVALID_PCH, OPT_Winvalid_pch}, + {CPP_W_WARNING_DIRECTIVE, OPT_Wcpp}, + {CPP_W_NONE, 0} +}; + +/* Return the gcc option code associated with the reason for a cpp + message, or 0 if none. */ + +static int +c_option_controlling_cpp_error (int reason) +{ + const struct reason_option_codes_t *entry; + + for (entry = option_codes; entry->reason != CPP_W_NONE; entry++) + { + if (entry->reason == reason) + return entry->option_code; + } + return 0; +} + /* Callback from cpp_error for PFILE to print diagnostics from the - preprocessor. The diagnostic is of type LEVEL, at location + preprocessor. The diagnostic is of type LEVEL, with REASON set + to the reason code if LEVEL is represents a warning, at location LOCATION unless this is after lexing and the compiler's location should be used instead, with column number possibly overridden by COLUMN_OVERRIDE if not zero; MSG is the translated message and AP @@ -8254,7 +8354,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type, otherwise. */ bool -c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, +c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason, location_t location, unsigned int column_override, const char *msg, va_list *ap) { @@ -8301,6 +8401,8 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, location, dlevel); if (column_override) diagnostic_override_column (&diagnostic, column_override); + diagnostic_override_option_index (&diagnostic, + c_option_controlling_cpp_error (reason)); ret = report_diagnostic (&diagnostic); if (level == CPP_DL_WARNING_SYSHDR) warn_system_headers = save_warn_system_headers; @@ -8585,7 +8687,7 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default) /* Make sure we have the canonical MAIN_TYPE. */ hashcode = iterative_hash_object (TYPE_HASH (unqual_elt), hashcode); - hashcode = iterative_hash_object (TYPE_HASH (TYPE_DOMAIN (main_type)), + hashcode = iterative_hash_object (TYPE_HASH (TYPE_DOMAIN (main_type)), hashcode); main_type = type_hash_canon (hashcode, main_type); @@ -8596,7 +8698,7 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default) else if (TYPE_CANONICAL (TREE_TYPE (main_type)) != TREE_TYPE (main_type) || (TYPE_CANONICAL (TYPE_DOMAIN (main_type)) != TYPE_DOMAIN (main_type))) - TYPE_CANONICAL (main_type) + TYPE_CANONICAL (main_type) = build_array_type (TYPE_CANONICAL (TREE_TYPE (main_type)), TYPE_CANONICAL (TYPE_DOMAIN (main_type))); else @@ -8678,7 +8780,6 @@ sync_resolve_params (tree orig_function, tree function, VEC(tree, gc) *params) { tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); tree ptype; - int number; unsigned int parmnum; /* We've declared the implementation functions to use "volatile void *" @@ -8686,7 +8787,6 @@ sync_resolve_params (tree orig_function, tree function, VEC(tree, gc) *params) call to check_function_arguments what ever type the user used. */ arg_types = TREE_CHAIN (arg_types); ptype = TREE_TYPE (TREE_TYPE (VEC_index (tree, params, 0))); - number = 2; /* For the rest of the values, we need to cast these to FTYPE, so that we don't get warnings for passing pointer types, etc. */ @@ -8711,7 +8811,6 @@ sync_resolve_params (tree orig_function, tree function, VEC(tree, gc) *params) VEC_replace (tree, params, parmnum, val); arg_types = TREE_CHAIN (arg_types); - number++; } /* The definition of these primitives is variadic, with the remaining @@ -8891,7 +8990,7 @@ warn_about_parentheses (enum tree_code code, || ((CODE) != INTEGER_CST \ && (integer_onep (ARG) || integer_zerop (ARG)))) - switch (code) + switch (code) { case LSHIFT_EXPR: if (code_left == PLUS_EXPR || code_right == PLUS_EXPR) @@ -9041,16 +9140,16 @@ warn_for_div_by_zero (location_t loc, tree divisor) The arguments of this function map directly to local variables of build_binary_op. */ -void +void warn_for_sign_compare (location_t location, - tree orig_op0, tree orig_op1, - tree op0, tree op1, + tree orig_op0, tree orig_op1, + tree op0, tree op1, tree result_type, enum tree_code resultcode) { int op0_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op0)); int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1)); int unsignedp0, unsignedp1; - + /* In C++, check for comparison of different enum types. */ if (c_dialect_cxx() && TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE @@ -9078,10 +9177,10 @@ warn_for_sign_compare (location_t location, if (op0_signed) sop = orig_op0, uop = orig_op1; - else + else sop = orig_op1, uop = orig_op0; - STRIP_TYPE_NOPS (sop); + STRIP_TYPE_NOPS (sop); STRIP_TYPE_NOPS (uop); base_type = (TREE_CODE (result_type) == COMPLEX_TYPE ? TREE_TYPE (result_type) : result_type); @@ -9107,23 +9206,23 @@ warn_for_sign_compare (location_t location, && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (uop)), c_common_signed_type (base_type))) /* OK */; - else + else warning_at (location, - OPT_Wsign_compare, + OPT_Wsign_compare, "comparison between signed and unsigned integer expressions"); } - + /* 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. */ op0 = get_narrower (op0, &unsignedp0); op1 = get_narrower (op1, &unsignedp1); - + if ((TREE_CODE (op0) == BIT_NOT_EXPR) ^ (TREE_CODE (op1) == BIT_NOT_EXPR)) { @@ -9138,7 +9237,7 @@ warn_for_sign_compare (location_t location, HOST_WIDE_INT constant, mask; int unsignedp; unsigned int bits; - + if (host_integerp (op0, 0)) { primop = op1; @@ -9151,7 +9250,7 @@ warn_for_sign_compare (location_t location, unsignedp = unsignedp0; constant = tree_low_cst (op1, 0); } - + bits = TYPE_PRECISION (TREE_TYPE (primop)); if (bits < TYPE_PRECISION (result_type) && bits < HOST_BITS_PER_LONG && unsignedp) @@ -9160,10 +9259,10 @@ warn_for_sign_compare (location_t location, if ((mask & constant) != mask) { if (constant == 0) - warning (OPT_Wsign_compare, + warning (OPT_Wsign_compare, "promoted ~unsigned is always non-zero"); else - warning_at (location, OPT_Wsign_compare, + warning_at (location, OPT_Wsign_compare, "comparison of promoted ~unsigned with constant"); } }