X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-decl.c;h=5774f755b032c5ed56b625d19d2876bc8413183e;hb=d5ca5bf1cb8a3c767835b20c4f18ffdef823a774;hp=13d6887d14d45a33681b715abeb4a1fd2d49a67d;hpb=1a9e039312de98591d1aed1d6bcfb1e89dc93af0;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 13d6887d14d..5774f755b03 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1,5 +1,5 @@ /* Process declarations and variables for C compiler. - Copyright (C) 1988, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright (C) 1988, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. This file is part of GNU CC. @@ -454,6 +454,10 @@ int flag_no_nonansi_builtin; int flag_traditional; +/* Nonzero means that we have builtin functions, and main is an int */ + +int flag_hosted = 1; + /* Nonzero means to allow single precision math even if we're generally being traditional. */ int flag_allow_single_precision = 0; @@ -545,9 +549,14 @@ int warn_parentheses; int warn_missing_braces; -/* Warn about comparison of signed and unsigned values. */ +/* Warn if main is suspicious. */ + +int warn_main; + +/* Warn about comparison of signed and unsigned values. + If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified. */ -int warn_sign_compare; +int warn_sign_compare = -1; /* Nonzero means `$' can be in an identifier. */ @@ -571,6 +580,19 @@ c_decode_option (p) } else if (!strcmp (p, "-fallow-single-precision")) flag_allow_single_precision = 1; + else if (!strcmp (p, "-fhosted") || !strcmp (p, "-fno-freestanding")) + { + flag_hosted = 1; + flag_no_builtin = 0; + } + else if (!strcmp (p, "-ffreestanding") || !strcmp (p, "-fno-hosted")) + { + flag_hosted = 0; + flag_no_builtin = 1; + /* warn_main will be 2 if set by -Wall, 1 if set by -Wmain */ + if (warn_main == 2) + warn_main = 0; + } else if (!strcmp (p, "-fnotraditional") || !strcmp (p, "-fno-traditional")) { flag_traditional = 0; @@ -702,6 +724,10 @@ c_decode_option (p) ; /* cpp handles this one. */ else if (!strcmp (p, "-Wno-trigraphs")) ; /* cpp handles this one. */ + else if (!strcmp (p, "-Wundef")) + ; /* cpp handles this one. */ + else if (!strcmp (p, "-Wno-undef")) + ; /* cpp handles this one. */ else if (!strcmp (p, "-Wimport")) ; /* cpp handles this one. */ else if (!strcmp (p, "-Wno-import")) @@ -710,6 +736,10 @@ c_decode_option (p) warn_missing_braces = 1; else if (!strcmp (p, "-Wno-missing-braces")) warn_missing_braces = 0; + else if (!strcmp (p, "-Wmain")) + warn_main = 1; + else if (!strcmp (p, "-Wno-main")) + warn_main = 0; else if (!strcmp (p, "-Wsign-compare")) warn_sign_compare = 1; else if (!strcmp (p, "-Wno-sign-compare")) @@ -729,7 +759,9 @@ c_decode_option (p) warn_char_subscripts = 1; warn_parentheses = 1; warn_missing_braces = 1; - warn_sign_compare = 1; + /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding can turn + it off only if it's not explicit. */ + warn_main = 2; } else return 0; @@ -1003,7 +1035,7 @@ poplevel (keep, reverse, functionbody) if (DECL_ABSTRACT_ORIGIN (decl) != 0 && DECL_ABSTRACT_ORIGIN (decl) != decl) TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; - else + else if (DECL_SAVED_INSNS (decl) != 0) { push_function_context (); output_inline_function (decl); @@ -1324,6 +1356,10 @@ pushtag (name, type) tagged type. */ TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type)); + + /* An approximation for now, so we can tell this is a function-scope tag. + This will be updated in poplevel. */ + TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type)); } /* Handle when a new declaration NEWDECL @@ -1906,6 +1942,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level) DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl); DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); + if (DECL_INLINE (newdecl)) + DECL_ABSTRACT_ORIGIN (newdecl) = olddecl; } } if (different_binding_level) @@ -2811,7 +2849,7 @@ init_decl_processing () tree traditional_ptr_type_node; /* Data types of memcpy and strlen. */ tree memcpy_ftype, memset_ftype, strlen_ftype; - tree void_ftype_any; + tree void_ftype_any, ptr_ftype_void, ptr_ftype_ptr; int wchar_type_size; tree temp; tree array_domain_type; @@ -3127,6 +3165,11 @@ init_decl_processing () sizetype, endlink)))); + ptr_ftype_void = build_function_type (ptr_type_node, endlink); + ptr_ftype_ptr + = build_function_type (ptr_type_node, + tree_cons (NULL_TREE, ptr_type_node, endlink)); + builtin_function ("__builtin_constant_p", default_function_type, BUILT_IN_CONSTANT_P, NULL_PTR); @@ -3144,6 +3187,42 @@ init_decl_processing () endlink)), BUILT_IN_FRAME_ADDRESS, NULL_PTR); + builtin_function ("__builtin_aggregate_incoming_address", + build_function_type (ptr_type_node, NULL_TREE), + BUILT_IN_AGGREGATE_INCOMING_ADDRESS, NULL_PTR); + + /* Hooks for the DWARF 2 __throw routine. */ + builtin_function ("__builtin_unwind_init", + build_function_type (void_type_node, endlink), + BUILT_IN_UNWIND_INIT, NULL_PTR); + builtin_function ("__builtin_fp", ptr_ftype_void, BUILT_IN_FP, NULL_PTR); + builtin_function ("__builtin_sp", ptr_ftype_void, BUILT_IN_SP, NULL_PTR); + builtin_function ("__builtin_dwarf_fp_regnum", + build_function_type (unsigned_type_node, endlink), + BUILT_IN_DWARF_FP_REGNUM, NULL_PTR); + builtin_function ("__builtin_dwarf_reg_size", int_ftype_int, + BUILT_IN_DWARF_REG_SIZE, NULL_PTR); + builtin_function ("__builtin_frob_return_addr", ptr_ftype_ptr, + BUILT_IN_FROB_RETURN_ADDR, NULL_PTR); + builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr, + BUILT_IN_EXTRACT_RETURN_ADDR, NULL_PTR); + builtin_function ("__builtin_set_return_addr_reg", + build_function_type (void_type_node, + tree_cons (NULL_TREE, + ptr_type_node, + endlink)), + BUILT_IN_SET_RETURN_ADDR_REG, NULL_PTR); + builtin_function ("__builtin_eh_stub", ptr_ftype_void, + BUILT_IN_EH_STUB, NULL_PTR); + builtin_function + ("__builtin_set_eh_regs", + build_function_type (void_type_node, + tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULL_TREE, + type_for_mode (ptr_mode, 0), + endlink))), + BUILT_IN_SET_EH_REGS, NULL_PTR); + builtin_function ("__builtin_alloca", build_function_type (ptr_type_node, tree_cons (NULL_TREE, @@ -3536,6 +3615,9 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) /* The corresponding pop_obstacks is in finish_decl. */ push_obstacks_nochange (); + if (warn_main && !strcmp (IDENTIFIER_POINTER (declarator), "main")) + warning_with_decl (decl, "`%s' is usually a function"); + if (initialized) /* Is it valid for this decl to have an initializer at all? If not, set INITIALIZED to zero, which will indirectly @@ -4066,12 +4148,6 @@ complete_array_type (type, initial_value, do_default) TYPE_DOMAIN (type) = build_index_type (maxindex); if (!TREE_TYPE (maxindex)) TREE_TYPE (maxindex) = TYPE_DOMAIN (type); -#if 0 /* I took out this change - together with the change in build_array_type. --rms */ - change_main_variant (type, - build_array_type (TREE_TYPE (type), - TYPE_DOMAIN (type))); -#endif } /* Lay out the type now that we can get the real answer. */ @@ -4277,10 +4353,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) if (type == 0) { - if (funcdef_flag && warn_return_type - && ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT) - | (1 << (int) RID_SIGNED) | (1 << (int) RID_UNSIGNED)))) - warn_about_return_type = 1; + if (! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT) + | (1 << (int) RID_SIGNED) + | (1 << (int) RID_UNSIGNED)))) + { + /* C9x will probably require a diagnostic here. + For now, issue a warning if -Wreturn-type and this is a function, + or if -Wimplicit; prefer the former warning since it is more + explicit. */ + if ((warn_implicit || warn_return_type) && funcdef_flag) + warn_about_return_type = 1; + else if (warn_implicit) + warning ("type defaults to `int' in declaration of `%s'", name); + } + defaulted_int = 1; type = integer_type_node; } @@ -4290,7 +4376,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) /* Long double is a special combination. */ - if ((specbits & 1 << (int) RID_LONG) + if ((specbits & 1 << (int) RID_LONG) && ! longlong && TYPE_MAIN_VARIANT (type) == double_type_node) { specbits &= ~ (1 << (int) RID_LONG); @@ -4304,11 +4390,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) { int ok = 0; - if (TREE_CODE (type) != INTEGER_TYPE) - error ("long, short, signed or unsigned invalid for `%s'", name); - else if ((specbits & 1 << (int) RID_LONG) - && (specbits & 1 << (int) RID_SHORT)) - error ("long and short specified together for `%s'", name); + if ((specbits & 1 << (int) RID_LONG) + && (specbits & 1 << (int) RID_SHORT)) + error ("both long and short specified for `%s'", name); else if (((specbits & 1 << (int) RID_LONG) || (specbits & 1 << (int) RID_SHORT)) && explicit_char) @@ -4316,10 +4400,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) else if (((specbits & 1 << (int) RID_LONG) || (specbits & 1 << (int) RID_SHORT)) && TREE_CODE (type) == REAL_TYPE) - error ("long or short specified with floating type for `%s'", name); + { + static int already = 0; + + error ("long or short specified with floating type for `%s'", name); + if (! already && ! pedantic) + { + error ("the only valid combination is `long double'"); + already = 1; + } + } else if ((specbits & 1 << (int) RID_SIGNED) && (specbits & 1 << (int) RID_UNSIGNED)) - error ("signed and unsigned given together for `%s'", name); + error ("both signed and unsigned specified for `%s'", name); + else if (TREE_CODE (type) != INTEGER_TYPE) + error ("long, short, signed or unsigned invalid for `%s'", name); else { ok = 1; @@ -4985,6 +5080,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) && ! DECL_IN_SYSTEM_HEADER (decl)) pedwarn ("ANSI C forbids const or volatile functions"); + if (pedantic + && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node + && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (decl))) + || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (decl)))) + && ! DECL_IN_SYSTEM_HEADER (decl)) + pedwarn ("ANSI C forbids const or volatile void function return type"); + if (volatilep && TREE_TYPE (TREE_TYPE (decl)) != void_type_node) warning ("`noreturn' function returns non-void value"); @@ -5324,7 +5426,7 @@ parmlist_tags_warning () enum tree_code code = TREE_CODE (TREE_VALUE (elt)); /* An anonymous union parm type is meaningful as a GNU extension. So don't warn for that. */ - if (code == UNION_TYPE && !pedantic) + if (code == UNION_TYPE && TREE_PURPOSE (elt) == 0 && !pedantic) continue; if (TREE_PURPOSE (elt) != 0) warning ("`%s %s' declared inside parameter list", @@ -6201,6 +6303,67 @@ start_function (declspecs, declarator, prefix_attributes, attributes, nested) if (current_function_decl != 0) TREE_PUBLIC (decl1) = 0; + /* Warn for unlikely, improbable, or stupid declarations of `main'. */ + if (warn_main + && strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1))) == 0) + { + tree args; + int argct = 0; + + if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1))) + != integer_type_node) + pedwarn_with_decl (decl1, "return type of `%s' is not `int'"); + + for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args; + args = TREE_CHAIN (args)) + { + tree type = args ? TREE_VALUE (args) : 0; + + if (type == void_type_node) + break; + + ++argct; + switch (argct) + { + case 1: + if (TYPE_MAIN_VARIANT (type) != integer_type_node) + pedwarn_with_decl (decl1, + "first argument of `%s' should be `int'"); + break; + + case 2: + if (TREE_CODE (type) != POINTER_TYPE + || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE + || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))) + != char_type_node)) + pedwarn_with_decl (decl1, + "second argument of `%s' should be `char **'"); + break; + + case 3: + if (TREE_CODE (type) != POINTER_TYPE + || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE + || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))) + != char_type_node)) + pedwarn_with_decl (decl1, + "third argument of `%s' should probably be `char **'"); + break; + } + } + + /* It is intentional that this message does not mention the third + argument, which is warned for only pedantically, because it's + blessed by mention in an appendix of the standard. */ + if (argct > 0 && (argct < 2 || argct > 3)) + pedwarn_with_decl (decl1, "`%s' takes only zero or two arguments"); + + if (argct == 3 && pedantic) + pedwarn_with_decl (decl1, "third argument of `%s' is deprecated"); + + if (! TREE_PUBLIC (decl1)) + pedwarn_with_decl (decl1, "`%s' is normally a non-static function"); + } + /* Record the decl so that the function name is defined. If we already have a decl for this name, and it is a FUNCTION_DECL, use the old decl. */ @@ -6857,7 +7020,16 @@ finish_function (nested) { if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) != integer_type_node) - pedwarn_with_decl (fndecl, "return type of `%s' is not `int'"); + { + /* You would expect the sense of this test to be the other way + around, but if warn_main is set, we will already have warned, + so this would be a duplicate. This is the warning you get + in some environments even if you *don't* ask for it, because + these are environments where it may be more of a problem than + usual. */ + if (! warn_main) + pedwarn_with_decl (fndecl, "return type of `%s' is not `int'"); + } else { #ifdef DEFAULT_MAIN_RETURN