X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-common.c;h=4ba17e0cbd93e3616f05ef665667cf5640e592b0;hb=648298e892dac93092649dbe92a8865adbe51748;hp=e6d4197d42ca42a1964048a898a5e0d6f8e9dd10;hpb=3514c10edaf2fb1bd6b8b68d5111243fe5b8069d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-common.c b/gcc/c-common.c index e6d4197d42c..4ba17e0cbd9 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -346,7 +346,25 @@ int warn_format_nonliteral; int warn_format_security; - +/* Zero means that faster, ...NonNil variants of objc_msgSend... + calls will be used in ObjC; passing nil receivers to such calls + will most likely result in crashes. */ +int flag_nil_receivers = 1; + +/* Nonzero means that we will allow new ObjC exception syntax (@throw, + @try, etc.) in source code. */ +int flag_objc_exceptions = 0; + +/* Nonzero means that code generation will be altered to support + "zero-link" execution. This currently affects ObjC only, but may + affect other languages in the future. */ +int flag_zero_link = 0; + +/* Nonzero means emit an '__OBJC, __image_info' for the current translation + unit. It will inform the ObjC runtime that class definition(s) herein + contained are to replace one(s) previously loaded. */ +int flag_replace_objc_classes = 0; + /* C/ObjC language option variables. */ @@ -1140,8 +1158,7 @@ fname_decl (unsigned int rid, tree id) input_line = saved_lineno; } if (!ix && !current_function_decl) - pedwarn ("%H'%D' is not defined outside of function scope", - &DECL_SOURCE_LOCATION (decl), decl); + pedwarn ("%J'%D' is not defined outside of function scope", decl, decl); return decl; } @@ -1811,6 +1828,10 @@ c_common_type_for_size (unsigned int bits, int unsignedp) return 0; } +/* Used for communication between c_common_type_for_mode and + c_register_builtin_type. */ +static GTY(()) tree registered_builtin_types; + /* Return a data type that has machine mode MODE. If the mode is an integer, then UNSIGNEDP selects between signed and unsigned types. */ @@ -1818,6 +1839,8 @@ c_common_type_for_size (unsigned int bits, int unsignedp) tree c_common_type_for_mode (enum machine_mode mode, int unsignedp) { + tree t; + if (mode == TYPE_MODE (integer_type_node)) return unsignedp ? unsigned_type_node : integer_type_node; @@ -1863,6 +1886,9 @@ c_common_type_for_mode (enum machine_mode mode, int unsignedp) if (mode == TYPE_MODE (long_double_type_node)) return long_double_type_node; + if (mode == TYPE_MODE (void_type_node)) + return void_type_node; + if (mode == TYPE_MODE (build_pointer_type (char_type_node))) return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode); @@ -1903,6 +1929,10 @@ c_common_type_for_mode (enum machine_mode mode, int unsignedp) break; } + for (t = registered_builtin_types; t; t = TREE_CHAIN (t)) + if (TYPE_MODE (TREE_VALUE (t)) == mode) + return TREE_VALUE (t); + return 0; } @@ -1983,32 +2013,37 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type) || TREE_UNSIGNED (type) == unsignedp) return type; - if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)) + /* Must check the mode of the types, not the precision. Enumeral types + in C++ have precision set to match their range, but may use a wider + mode to match an ABI. If we change modes, we may wind up with bad + conversions. */ + + if (TYPE_MODE (type) == TYPE_MODE (signed_char_type_node)) return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (integer_type_node)) return unsignedp ? unsigned_type_node : integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (short_integer_type_node)) return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (long_integer_type_node)) return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (long_long_integer_type_node)) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); - if (TYPE_PRECISION (type) == TYPE_PRECISION (widest_integer_literal_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (widest_integer_literal_type_node)) return (unsignedp ? widest_unsigned_literal_type_node : widest_integer_literal_type_node); #if HOST_BITS_PER_WIDE_INT >= 64 - if (TYPE_PRECISION (type) == TYPE_PRECISION (intTI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intTI_type_node)) return unsignedp ? unsigned_intTI_type_node : intTI_type_node; #endif - if (TYPE_PRECISION (type) == TYPE_PRECISION (intDI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intDI_type_node)) return unsignedp ? unsigned_intDI_type_node : intDI_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (intSI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intSI_type_node)) return unsignedp ? unsigned_intSI_type_node : intSI_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (intHI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intHI_type_node)) return unsignedp ? unsigned_intHI_type_node : intHI_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (intQI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intQI_type_node)) return unsignedp ? unsigned_intQI_type_node : intQI_type_node; return type; @@ -2026,6 +2061,8 @@ c_register_builtin_type (tree type, const char* name) if (!TYPE_NAME (type)) TYPE_NAME (type) = decl; pushdecl (decl); + + registered_builtin_types = tree_cons (0, type, registered_builtin_types); } @@ -2577,6 +2614,9 @@ c_common_truthvalue_conversion (tree expr) if (TREE_CODE (expr) == ERROR_MARK) return expr; + if (TREE_CODE (expr) == FUNCTION_DECL) + expr = build_unary_op (ADDR_EXPR, expr, 0); + #if 0 /* This appears to be wrong for C++. */ /* These really should return error_mark_node after 2.4 is stable. But not all callers handle ERROR_MARK properly. */ @@ -2622,17 +2662,29 @@ c_common_truthvalue_conversion (tree expr) return real_zerop (expr) ? truthvalue_false_node : truthvalue_true_node; case ADDR_EXPR: - /* If we are taking the address of an external decl, it might be zero - if it is weak, so we cannot optimize. */ - if (DECL_P (TREE_OPERAND (expr, 0)) - && DECL_EXTERNAL (TREE_OPERAND (expr, 0))) - break; + { + if (TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL + && ! DECL_WEAK (TREE_OPERAND (expr, 0))) + { + /* Common Ada/Pascal programmer's mistake. We always warn + about this since it is so bad. */ + warning ("the address of `%D', will always evaluate as `true'", + TREE_OPERAND (expr, 0)); + return truthvalue_true_node; + } - if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0))) - return build (COMPOUND_EXPR, truthvalue_type_node, - TREE_OPERAND (expr, 0), truthvalue_true_node); - else - return truthvalue_true_node; + /* If we are taking the address of an external decl, it might be + zero if it is weak, so we cannot optimize. */ + if (DECL_P (TREE_OPERAND (expr, 0)) + && DECL_EXTERNAL (TREE_OPERAND (expr, 0))) + break; + + if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0))) + return build (COMPOUND_EXPR, truthvalue_type_node, + TREE_OPERAND (expr, 0), truthvalue_true_node); + else + return truthvalue_true_node; + } case COMPLEX_EXPR: return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)) @@ -2741,13 +2793,14 @@ static tree builtin_function_2 (const char *, const char *, tree, tree, tree c_build_qualified_type (tree type, int type_quals) { + if (TREE_CODE (type) == ARRAY_TYPE) + return build_array_type (c_build_qualified_type (TREE_TYPE (type), + type_quals), + TYPE_DOMAIN (type)); + /* A restrict-qualified pointer type must be a pointer to object or incomplete type. Note that the use of POINTER_TYPE_P also allows - REFERENCE_TYPEs, which is appropriate for C++. Unfortunately, - the C++ front-end also use POINTER_TYPE for pointer-to-member - values, so even though it should be illegal to use `restrict' - with such an entity we don't flag that here. Thus, special case - code for that case is required in the C++ front-end. */ + REFERENCE_TYPEs, which is appropriate for C++. */ if ((type_quals & TYPE_QUAL_RESTRICT) && (!POINTER_TYPE_P (type) || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))) @@ -2756,10 +2809,6 @@ c_build_qualified_type (tree type, int type_quals) type_quals &= ~TYPE_QUAL_RESTRICT; } - if (TREE_CODE (type) == ARRAY_TYPE) - return build_array_type (c_build_qualified_type (TREE_TYPE (type), - type_quals), - TYPE_DOMAIN (type)); return build_qualified_type (type, type_quals); } @@ -2768,9 +2817,16 @@ c_build_qualified_type (tree type, int type_quals) void c_apply_type_quals_to_decl (int type_quals, tree decl) { - if ((type_quals & TYPE_QUAL_CONST) - || (TREE_TYPE (decl) - && TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)) + tree type = TREE_TYPE (decl); + + if (((type_quals & TYPE_QUAL_CONST) + || (type && TREE_CODE (type) == REFERENCE_TYPE)) + /* An object declared 'const' is only readonly after it is + initialized. We don't have any way of expressing this currently, + so we need to be conservative and unset TREE_READONLY for types + with constructors. Otherwise aliasing code will ignore stores in + an inline constructor. */ + && !(type && TYPE_NEEDS_CONSTRUCTING (type))) TREE_READONLY (decl) = 1; if (type_quals & TYPE_QUAL_VOLATILE) { @@ -2779,11 +2835,15 @@ c_apply_type_quals_to_decl (int type_quals, tree decl) } if (type_quals & TYPE_QUAL_RESTRICT) { - if (!TREE_TYPE (decl) - || !POINTER_TYPE_P (TREE_TYPE (decl)) - || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (TREE_TYPE (decl)))) + while (type && TREE_CODE (type) == ARRAY_TYPE) + /* Allow 'restrict' on arrays of pointers. + FIXME currently we just ignore it. */ + type = TREE_TYPE (type); + if (!type + || !POINTER_TYPE_P (type) + || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))) error ("invalid use of `restrict'"); - else if (flag_strict_aliasing) + else if (flag_strict_aliasing && type == TREE_TYPE (decl)) /* Indicate we need to make a unique alias set for this pointer. We can't do it here because it might be pointing to an incomplete type. */ @@ -3692,14 +3752,16 @@ expand_tree_builtin (tree function, tree params, tree coerced_params) case BUILT_IN_CREALL: if (coerced_params == 0) return integer_zero_node; - return build_unary_op (REALPART_EXPR, TREE_VALUE (coerced_params), 0); + return non_lvalue (build_unary_op (REALPART_EXPR, + TREE_VALUE (coerced_params), 0)); case BUILT_IN_CIMAG: case BUILT_IN_CIMAGF: case BUILT_IN_CIMAGL: if (coerced_params == 0) return integer_zero_node; - return build_unary_op (IMAGPART_EXPR, TREE_VALUE (coerced_params), 0); + return non_lvalue (build_unary_op (IMAGPART_EXPR, + TREE_VALUE (coerced_params), 0)); case BUILT_IN_ISGREATER: return expand_unordered_cmp (function, params, UNLE_EXPR, LE_EXPR); @@ -3936,19 +3998,17 @@ c_add_case_label (splay_tree cases, tree cond, tree low_value, if (high_value) { error ("duplicate (or overlapping) case value"); - error ("%Hthis is the first entry overlapping that value", - &DECL_SOURCE_LOCATION (duplicate)); + error ("%Jthis is the first entry overlapping that value", duplicate); } else if (low_value) { error ("duplicate case value") ; - error ("%Hpreviously used here", &DECL_SOURCE_LOCATION (duplicate)); + error ("%Jpreviously used here", duplicate); } else { error ("multiple default labels in one switch"); - error ("%Hthis is the first default label", - &DECL_SOURCE_LOCATION (duplicate)); + error ("%Jthis is the first default label", duplicate); } if (!cases->root) add_stmt (build_case_label (NULL_TREE, NULL_TREE, label)); @@ -4249,7 +4309,7 @@ shadow_warning (enum sw_kind msgcode, const char *name, tree decl) }; warning (msgs[msgcode], name); - warning ("%Hshadowed declaration is here", &DECL_SOURCE_LOCATION (decl)); + warning ("%Jshadowed declaration is here", decl); } /* Attribute handlers common to C front ends. */ @@ -4690,8 +4750,8 @@ handle_section_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args, && current_function_decl != NULL_TREE && ! TREE_STATIC (decl)) { - error ("%Hsection attribute cannot be specified for " - "local variables", &DECL_SOURCE_LOCATION (decl)); + error ("%Jsection attribute cannot be specified for " + "local variables", decl); *no_add_attrs = true; } @@ -4701,8 +4761,8 @@ handle_section_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args, && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), TREE_STRING_POINTER (TREE_VALUE (args))) != 0) { - error ("%Hsection of '%D' conflicts with previous declaration", - &DECL_SOURCE_LOCATION (*node), *node); + error ("%Jsection of '%D' conflicts with previous declaration", + *node, *node); *no_add_attrs = true; } else @@ -4710,15 +4770,13 @@ handle_section_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args, } else { - error ("%Hsection attribute not allowed for '%D'", - &DECL_SOURCE_LOCATION (*node), *node); + error ("%Jsection attribute not allowed for '%D'", *node, *node); *no_add_attrs = true; } } else { - error ("%Hsection attributes are not supported for this target", - &DECL_SOURCE_LOCATION (*node)); + error ("%Jsection attributes are not supported for this target", *node); *no_add_attrs = true; } @@ -4792,8 +4850,7 @@ handle_aligned_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args, else if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FIELD_DECL) { - error ("%Halignment may not be specified for '%D'", - &DECL_SOURCE_LOCATION (decl), decl); + error ("%Jalignment may not be specified for '%D'", decl, decl); *no_add_attrs = true; } else @@ -4831,8 +4888,7 @@ handle_alias_attribute (tree *node, tree name, tree args, if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) || (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl))) { - error ("%H'%D' defined both normally and as an alias", - &DECL_SOURCE_LOCATION (decl), decl); + error ("%J'%D' defined both normally and as an alias", decl, decl); *no_add_attrs = true; } else if (decl_function_context (decl) == 0) @@ -4873,34 +4929,33 @@ handle_visibility_attribute (tree *node, tree name, tree args, bool *no_add_attrs) { tree decl = *node; + tree id = TREE_VALUE (args); + + *no_add_attrs = true; if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl)) { warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); - *no_add_attrs = true; + return NULL_TREE; } - else - { - tree id; - id = TREE_VALUE (args); - if (TREE_CODE (id) != STRING_CST) - { - error ("visibility arg not a string"); - *no_add_attrs = true; - return NULL_TREE; - } - if (strcmp (TREE_STRING_POINTER (id), "hidden") - && strcmp (TREE_STRING_POINTER (id), "protected") - && strcmp (TREE_STRING_POINTER (id), "internal") - && strcmp (TREE_STRING_POINTER (id), "default")) - { - error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\""); - *no_add_attrs = true; - return NULL_TREE; - } + if (TREE_CODE (id) != STRING_CST) + { + error ("visibility arg not a string"); + return NULL_TREE; } + if (strcmp (TREE_STRING_POINTER (id), "default") == 0) + DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; + else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0) + DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL; + else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0) + DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; + else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0) + DECL_VISIBILITY (decl) = VISIBILITY_PROTECTED; + else + error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\""); + return NULL_TREE; } @@ -4956,14 +5011,12 @@ handle_no_instrument_function_attribute (tree *node, tree name, if (TREE_CODE (decl) != FUNCTION_DECL) { - error ("%H'%E' attribute applies only to functions", - &DECL_SOURCE_LOCATION (decl), name); + error ("%J'%E' attribute applies only to functions", decl, name); *no_add_attrs = true; } else if (DECL_INITIAL (decl)) { - error ("%Hcan't set '%E' attribute after definition", - &DECL_SOURCE_LOCATION (decl), name); + error ("%Jcan't set '%E' attribute after definition", decl, name); *no_add_attrs = true; } else @@ -5004,14 +5057,12 @@ handle_no_limit_stack_attribute (tree *node, tree name, if (TREE_CODE (decl) != FUNCTION_DECL) { - error ("%H'%E' attribute applies only to functions", - &DECL_SOURCE_LOCATION (decl), name); + error ("%J'%E' attribute applies only to functions", decl, name); *no_add_attrs = true; } else if (DECL_INITIAL (decl)) { - error ("%Hcan't set '%E' attribute after definition", - &DECL_SOURCE_LOCATION (decl), name); + error ("%Jcan't set '%E' attribute after definition", decl, name); *no_add_attrs = true; } else @@ -5723,7 +5774,7 @@ c_estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) return NULL; switch (TREE_CODE (x)) { - /* Reconginze assignments of large structures and constructors of + /* Recognize assignments of large structures and constructors of big arrays. */ case MODIFY_EXPR: case CONSTRUCTOR: @@ -5842,4 +5893,36 @@ c_decl_uninit (tree t) return false; } +/* Issue the error given by MSGID, indicating that it occurred before + TOKEN, which had the associated VALUE. */ + +void +c_parse_error (const char *msgid, enum cpp_ttype token, tree value) +{ + const char *string = _(msgid); + + if (token == CPP_EOF) + error ("%s at end of input", string); + else if (token == CPP_CHAR || token == CPP_WCHAR) + { + unsigned int val = TREE_INT_CST_LOW (value); + const char *const ell = (token == CPP_CHAR) ? "" : "L"; + if (val <= UCHAR_MAX && ISGRAPH (val)) + error ("%s before %s'%c'", string, ell, val); + else + error ("%s before %s'\\x%x'", string, ell, val); + } + else if (token == CPP_STRING + || token == CPP_WSTRING) + error ("%s before string constant", string); + else if (token == CPP_NUMBER) + error ("%s before numeric constant", string); + else if (token == CPP_NAME) + error ("%s before \"%s\"", string, IDENTIFIER_POINTER (value)); + else if (token < N_TTYPES) + error ("%s before '%s' token", string, cpp_type2name (token)); + else + error ("%s", string); +} + #include "gt-c-common.h"