OSDN Git Service

2002-04-12 Eric Norum <eric.norum@usask.ca>
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index 9deb193..3487aef 100644 (file)
@@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "debug.h"
 #include "timevar.h"
 #include "c-common.h"
+#include "c-pragma.h"
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -53,6 +54,7 @@ enum decl_context
   FUNCDEF,                     /* Function definition */
   PARM,                                /* Declaration of parm before function body */
   FIELD,                       /* Declaration inside struct or union */
+  BITFIELD,                    /* Likewise but with specified width */
   TYPENAME};                   /* Typename (inside cast or sizeof)  */
 
 \f
@@ -133,6 +135,11 @@ int current_function_returns_value;
 
 int current_function_returns_null;
 
+/* Set to 0 at beginning of a function definition, set to 1 if
+   a call to a noreturn function is seen.  */
+
+int current_function_returns_abnormally;
+
 /* Set to nonzero by `grokdeclarator' for a function
    whose return type is defaulted, if warnings for this are desired.  */
 
@@ -275,13 +282,12 @@ static tree lookup_tag                    PARAMS ((enum tree_code, tree,
                                                 struct binding_level *, int));
 static tree lookup_tag_reverse         PARAMS ((tree));
 static tree grokdeclarator             PARAMS ((tree, tree, enum decl_context,
-                                                int, tree));
+                                                int));
 static tree grokparms                  PARAMS ((tree, int));
 static void layout_array_type          PARAMS ((tree));
 static tree c_make_fname_decl           PARAMS ((tree, int));
 static void c_expand_body               PARAMS ((tree, int, int));
 static void warn_if_shadowing          PARAMS ((tree, tree));
-static tree build_bitfield_integer_type        PARAMS ((tree, tree, const char *));
 \f
 /* C-specific option variables.  */
 
@@ -294,10 +300,6 @@ int flag_cond_mismatch;
 
 int flag_no_asm;
 
-/* Nonzero means do some things the same way PCC does.  */
-
-int flag_traditional;
-
 /* Nonzero means enable C89 Amendment 1 features.  */
 
 int flag_isoc94 = 0;
@@ -315,11 +317,7 @@ int flag_hosted = 1;
 
 int flag_noniso_default_format_attributes = 1;
 
-/* Nonzero means to allow single precision math even if we're generally
-   being traditional.  */
-int flag_allow_single_precision = 0;
-
-/* Nonzero means to treat bit-fields as signed unless they say `unsigned'.  */
+/* Nonzero means to treat bitfields as signed unless they say `unsigned'.  */
 
 int flag_signed_bitfields = 1;
 int explicit_flag_signed_bitfields = 0;
@@ -463,17 +461,53 @@ c_decode_option (argc, argv)
   int strings_processed;
   char *p = argv[0];
 
+  static const struct {
+      /* The name of the option.  */
+      const char *option;
+      /* If non-NULL, a flag variable to set to 0 or 1.  If NULL,
+         this means that cpp handles this option.  */
+      int *flag;
+  } warn_options[] = {
+    /* This list is in alphabetical order.  Keep it like that.  */
+    { "bad-function-cast", &warn_bad_function_cast },
+    { "cast-qual", &warn_cast_qual },
+    { "char-subscripts", &warn_char_subscripts },
+    { "comment", NULL },
+    { "comments", NULL },
+    { "conversion", &warn_conversion },
+    { "div-by-zero", &warn_div_by_zero },
+    { "float-equal", &warn_float_equal },
+    { "format-extra-args", &warn_format_extra_args },
+    { "format-nonliteral", &warn_format_nonliteral },
+    { "format-security", &warn_format_security },
+    { "format-y2k", &warn_format_y2k },
+    { "implicit-function-declaration", &mesg_implicit_function_declaration },
+    { "implicit-int", &warn_implicit_int },
+    { "import", NULL },
+    { "long-long", &warn_long_long },
+    { "main", &warn_main },
+    { "missing-braces", &warn_missing_braces },
+    { "missing-declarations", &warn_missing_declarations },
+    { "missing-format-attribute", &warn_missing_format_attribute },
+    { "missing-prototypes", &warn_missing_prototypes },
+    { "multichar", &warn_multichar },
+    { "nested-externs", &warn_nested_externs },
+    { "parentheses", &warn_parentheses },
+    { "pointer-arith", &warn_pointer_arith },
+    { "redundant-decls", &warn_redundant_decls },
+    { "return-type", &warn_return_type },
+    { "sequence-point", &warn_sequence_point },
+    { "sign-compare", &warn_sign_compare },
+    { "strict-prototypes", &warn_strict_prototypes },
+    { "traditional", &warn_traditional },
+    { "trigraphs", NULL },
+    { "undef", NULL },
+    { "write-strings", &flag_const_strings }
+  };
+
   strings_processed = cpp_handle_option (parse_in, argc, argv, 0);
 
-  if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
-    {
-      warning ("-traditional is deprecated and may be removed");
-      flag_traditional = 1;
-      flag_writable_strings = 1;
-    }
-  else if (!strcmp (p, "-fallow-single-precision"))
-    flag_allow_single_precision = 1;
-  else if (!strcmp (p, "-fhosted") || !strcmp (p, "-fno-freestanding"))
+  if (!strcmp (p, "-fhosted") || !strcmp (p, "-fno-freestanding"))
     {
       flag_hosted = 1;
       flag_no_builtin = 0;
@@ -486,11 +520,6 @@ c_decode_option (argc, argv)
       if (warn_main == 2)
        warn_main = 0;
     }
-  else if (!strcmp (p, "-fnotraditional") || !strcmp (p, "-fno-traditional"))
-    {
-      flag_traditional = 0;
-      flag_writable_strings = 0;
-    }
   else if (!strncmp (p, "-std=", 5))
     {
       /* Select the appropriate language standard.  We currently
@@ -511,7 +540,6 @@ c_decode_option (argc, argv)
        iso_1990:
          flag_isoc94 = 0;
        iso_1994:
-         flag_traditional = 0;
          flag_writable_strings = 0;
          flag_no_asm = 1;
          flag_no_nonansi_builtin = 1;
@@ -528,7 +556,6 @@ c_decode_option (argc, argv)
               || !strcmp (argstart, "c9x")
               || !strcmp (argstart, "c99"))
        {
-         flag_traditional = 0;
          flag_writable_strings = 0;
          flag_no_asm = 1;
          flag_no_nonansi_builtin = 1;
@@ -538,7 +565,6 @@ c_decode_option (argc, argv)
        }
       else if (!strcmp (argstart, "gnu89"))
        {
-         flag_traditional = 0;
          flag_writable_strings = 0;
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
@@ -548,7 +574,6 @@ c_decode_option (argc, argv)
        }
       else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
        {
-         flag_traditional = 0;
          flag_writable_strings = 0;
          flag_no_asm = 0;
          flag_no_nonansi_builtin = 0;
@@ -556,6 +581,8 @@ c_decode_option (argc, argv)
          flag_isoc99 = 1;
          flag_isoc94 = 1;
        }
+      else if (!strcmp (argstart, "c++98"))
+       ; /* Handled by cpplib.  */
       else
        error ("unknown C standard `%s'", argstart);
     }
@@ -615,14 +642,12 @@ c_decode_option (argc, argv)
     goto iso_1990;
   else if (!strcmp (p, "-Werror-implicit-function-declaration"))
     mesg_implicit_function_declaration = 2;
-  else if (!strcmp (p, "-Wimplicit-function-declaration"))
-    mesg_implicit_function_declaration = 1;
-  else if (!strcmp (p, "-Wno-implicit-function-declaration"))
-    mesg_implicit_function_declaration = 0;
-  else if (!strcmp (p, "-Wimplicit-int"))
-    warn_implicit_int = 1;
-  else if (!strcmp (p, "-Wno-implicit-int"))
-    warn_implicit_int = 0;
+  else if (!strncmp (p, "-Wformat=", 9))
+    set_Wformat (atoi (p + 9));
+  else if (!strcmp (p, "-Wformat"))
+    set_Wformat (1);
+  else if (!strcmp (p, "-Wno-format"))
+    set_Wformat (0);
   else if (!strcmp (p, "-Wimplicit"))
     {
       warn_implicit_int = 1;
@@ -631,142 +656,8 @@ c_decode_option (argc, argv)
     }
   else if (!strcmp (p, "-Wno-implicit"))
     warn_implicit_int = 0, mesg_implicit_function_declaration = 0;
-  else if (!strcmp (p, "-Wlong-long"))
-    warn_long_long = 1;
-  else if (!strcmp (p, "-Wno-long-long"))
-    warn_long_long = 0;
-  else if (!strcmp (p, "-Wwrite-strings"))
-    flag_const_strings = 1;
-  else if (!strcmp (p, "-Wno-write-strings"))
-    flag_const_strings = 0;
-  else if (!strcmp (p, "-Wcast-qual"))
-    warn_cast_qual = 1;
-  else if (!strcmp (p, "-Wno-cast-qual"))
-    warn_cast_qual = 0;
-  else if (!strcmp (p, "-Wbad-function-cast"))
-    warn_bad_function_cast = 1;
-  else if (!strcmp (p, "-Wno-bad-function-cast"))
-    warn_bad_function_cast = 0;
-  else if (!strcmp (p, "-Wno-missing-noreturn"))
-    warn_missing_noreturn = 0;
-  else if (!strcmp (p, "-Wmissing-format-attribute"))
-    warn_missing_format_attribute = 1;
-  else if (!strcmp (p, "-Wno-missing-format-attribute"))
-    warn_missing_format_attribute = 0;
-  else if (!strcmp (p, "-Wpointer-arith"))
-    warn_pointer_arith = 1;
-  else if (!strcmp (p, "-Wno-pointer-arith"))
-    warn_pointer_arith = 0;
-  else if (!strcmp (p, "-Wstrict-prototypes"))
-    warn_strict_prototypes = 1;
-  else if (!strcmp (p, "-Wno-strict-prototypes"))
-    warn_strict_prototypes = 0;
-  else if (!strcmp (p, "-Wmissing-prototypes"))
-    warn_missing_prototypes = 1;
-  else if (!strcmp (p, "-Wno-missing-prototypes"))
-    warn_missing_prototypes = 0;
-  else if (!strcmp (p, "-Wmissing-declarations"))
-    warn_missing_declarations = 1;
-  else if (!strcmp (p, "-Wno-missing-declarations"))
-    warn_missing_declarations = 0;
-  else if (!strcmp (p, "-Wredundant-decls"))
-    warn_redundant_decls = 1;
-  else if (!strcmp (p, "-Wno-redundant-decls"))
-    warn_redundant_decls = 0;
-  else if (!strcmp (p, "-Wnested-externs"))
-    warn_nested_externs = 1;
-  else if (!strcmp (p, "-Wno-nested-externs"))
-    warn_nested_externs = 0;
-  else if (!strcmp (p, "-Wtraditional"))
-    warn_traditional = 1;
-  else if (!strcmp (p, "-Wno-traditional"))
-    warn_traditional = 0;
-  else if (!strncmp (p, "-Wformat=", 9))
-    set_Wformat (atoi (p + 9));
-  else if (!strcmp (p, "-Wformat"))
-    set_Wformat (1);
-  else if (!strcmp (p, "-Wno-format"))
-    set_Wformat (0);
-  else if (!strcmp (p, "-Wformat-y2k"))
-    warn_format_y2k = 1;
-  else if (!strcmp (p, "-Wno-format-y2k"))
-    warn_format_y2k = 0;
-  else if (!strcmp (p, "-Wformat-extra-args"))
-    warn_format_extra_args = 1;
-  else if (!strcmp (p, "-Wno-format-extra-args"))
-    warn_format_extra_args = 0;
-  else if (!strcmp (p, "-Wformat-nonliteral"))
-    warn_format_nonliteral = 1;
-  else if (!strcmp (p, "-Wno-format-nonliteral"))
-    warn_format_nonliteral = 0;
-  else if (!strcmp (p, "-Wformat-security"))
-    warn_format_security = 1;
-  else if (!strcmp (p, "-Wno-format-security"))
-    warn_format_security = 0;
-  else if (!strcmp (p, "-Wchar-subscripts"))
-    warn_char_subscripts = 1;
-  else if (!strcmp (p, "-Wno-char-subscripts"))
-    warn_char_subscripts = 0;
-  else if (!strcmp (p, "-Wconversion"))
-    warn_conversion = 1;
-  else if (!strcmp (p, "-Wno-conversion"))
-    warn_conversion = 0;
-  else if (!strcmp (p, "-Wparentheses"))
-    warn_parentheses = 1;
-  else if (!strcmp (p, "-Wno-parentheses"))
-    warn_parentheses = 0;
-  else if (!strcmp (p, "-Wreturn-type"))
-    warn_return_type = 1;
-  else if (!strcmp (p, "-Wno-return-type"))
-    warn_return_type = 0;
-  else if (!strcmp (p, "-Wsequence-point"))
-    warn_sequence_point = 1;
-  else if (!strcmp (p, "-Wno-sequence-point"))
-    warn_sequence_point = 0;
-  else if (!strcmp (p, "-Wcomment"))
-    ; /* cpp handles this one.  */
-  else if (!strcmp (p, "-Wno-comment"))
-    ; /* cpp handles this one.  */
-  else if (!strcmp (p, "-Wcomments"))
-    ; /* cpp handles this one.  */
-  else if (!strcmp (p, "-Wno-comments"))
-    ; /* cpp handles this one.  */
-  else if (!strcmp (p, "-Wtrigraphs"))
-    ; /* 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"))
-    ; /* cpp handles this one.  */
-  else if (!strcmp (p, "-Wmissing-braces"))
-    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 = -1;
-  else if (!strcmp (p, "-Wsign-compare"))
-    warn_sign_compare = 1;
-  else if (!strcmp (p, "-Wno-sign-compare"))
-    warn_sign_compare = 0;
-  else if (!strcmp (p, "-Wfloat-equal"))
-    warn_float_equal = 1;
-  else if (!strcmp (p, "-Wno-float-equal"))
-    warn_float_equal = 0;
-  else if (!strcmp (p, "-Wmultichar"))
-    warn_multichar = 1;
-  else if (!strcmp (p, "-Wno-multichar"))
-    warn_multichar = 0;
-  else if (!strcmp (p, "-Wdiv-by-zero"))
-    warn_div_by_zero = 1;
-  else if (!strcmp (p, "-Wno-div-by-zero"))
-    warn_div_by_zero = 0;
   else if (!strcmp (p, "-Wunknown-pragmas"))
     /* Set to greater than 1, so that even unknown pragmas in system
        headers will be warned about.  */
@@ -796,8 +687,23 @@ c_decode_option (argc, argv)
       /* Only warn about unknown pragmas that are not in system headers.  */
       warn_unknown_pragmas = 1;
     }
+  else if (!strcmp (p, "-E"))
+    flag_preprocess_only = 1;
   else
-    return strings_processed;
+    {
+      size_t i;
+      for (i = 0; i < sizeof (warn_options) / sizeof (warn_options[0]); i++)
+       if (strncmp (p, "-W", 2) == 0 
+           && warn_options[i].flag
+           && (strcmp (p+2, warn_options[i].option) == 0
+               || (strncmp (p+2, "no-", 3) == 0
+                   && strcmp (p+5, warn_options[i].option) == 0)))
+         {
+           *(warn_options[i].flag) = strncmp (p+2, "no-", 3) != 0;
+           return 1;
+         }
+      return strings_processed;
+    }
 
   return 1;
 }
@@ -828,7 +734,7 @@ c_print_identifier (file, node, indent)
    for a top-level tentative array defn that wasn't complete before.  */
 
 void
-finish_incomplete_decl (decl)
+c_finish_incomplete_decl (decl)
      tree decl;
 {
   if (TREE_CODE (decl) == VAR_DECL)
@@ -1477,14 +1383,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
      match enough.  Ultimately, copy most of the information from the new
      decl to the old one, and keep using the old one.  */
 
-  if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL
-      && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (newdecl)) == olddecl
-      && DECL_INITIAL (olddecl) == 0)
-    /* If -traditional, avoid error for redeclaring fcn
-       after implicit decl.  */
-    ;
-  else if (TREE_CODE (olddecl) == FUNCTION_DECL
-          && DECL_BUILT_IN (olddecl))
+  if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_BUILT_IN (olddecl))
     {
       /* A function declaration for a built-in function.  */
       if (!TREE_PUBLIC (newdecl))
@@ -1543,6 +1442,22 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
          if (! different_binding_level)
            TREE_TYPE (olddecl) = oldtype;
        }
+      else if (TYPE_ARG_TYPES (oldtype) == NULL
+              && TYPE_ARG_TYPES (newtype) != NULL)
+       {
+         /* For bcmp, bzero, fputs the builtin type has arguments not
+            specified.  Use the ones from the prototype so that type checking
+            is done for them.  */
+         tree trytype
+           = build_function_type (TREE_TYPE (oldtype),
+                                  TYPE_ARG_TYPES (newtype));
+         trytype = build_type_attribute_variant (trytype,
+                                                 TYPE_ATTRIBUTES (oldtype));
+
+         oldtype = trytype;
+         if (! different_binding_level)
+           TREE_TYPE (olddecl) = oldtype;
+       }
       if (!types_match)
        {
          /* If types don't match for a built-in, throw away the built-in.  */
@@ -1669,6 +1584,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
                             && current_binding_level == global_binding_level)
                            ? "`%s' previously defined here"
                            : "`%s' previously declared here"));
+         return 0;
        }
       else if (TREE_CODE (newdecl) == TYPE_DECL
                && (DECL_IN_SYSTEM_HEADER (olddecl)
@@ -1716,12 +1632,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
                }
              /* Type for passing arg must be consistent
                 with that declared for the arg.  */
-             if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type))
-                 /* If -traditional, allow `unsigned int' instead of `int'
-                    in the prototype.  */
-                 && (! (flag_traditional
-                        && TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node
-                        && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node)))
+             if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type)))
                {
                  error_with_decl (newdecl,
                                   "prototype for `%s' follows and argument %d doesn't match",
@@ -2172,16 +2083,15 @@ pushdecl (x)
                 IDENTIFIER_POINTER (name));
 
       t = lookup_name_current_level (name);
-      /* Don't type check externs here when -traditional.  This is so that
-        code with conflicting declarations inside blocks will get warnings
-        not errors.  X11 for instance depends on this.  */
-      if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x) && ! flag_traditional)
+      if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x))
        {
-         t = lookup_name (name);
+         t = IDENTIFIER_GLOBAL_VALUE (name);
          /* Type decls at global scope don't conflict with externs declared
             inside lexical blocks.  */
-         if (t && TREE_CODE (t) == TYPE_DECL)
-           t = 0;
+         if (! t || TREE_CODE (t) == TYPE_DECL)
+           /* If there's no visible global declaration, try for an
+               invisible one.  */
+           t = IDENTIFIER_LIMBO_VALUE (name);
          different_binding_level = 1;
        }
       if (t != 0 && t == error_mark_node)
@@ -2192,9 +2102,8 @@ pushdecl (x)
        }
 
       /* If this decl is `static' and an implicit decl was seen previously,
-        warn.  But don't complain if -traditional,
-        since traditional compilers don't complain.  */
-      if (! flag_traditional && TREE_PUBLIC (name)
+        warn.  */
+      if (TREE_PUBLIC (name)
          /* Don't test for DECL_EXTERNAL, because grokdeclarator
             sets this for all functions.  */
          && ! TREE_PUBLIC (x)
@@ -2288,9 +2197,6 @@ pushdecl (x)
        }
 
       /* Multiple external decls of the same identifier ought to match.
-        Check against both global declarations (when traditional) and out of
-        scope (limbo) block level declarations.
-
         We get warnings about inline functions where they are defined.
         Avoid duplicate warnings where they are used.  */
       if (TREE_PUBLIC (x)
@@ -2298,11 +2204,7 @@ pushdecl (x)
        {
          tree decl;
 
-         if (flag_traditional && IDENTIFIER_GLOBAL_VALUE (name) != 0
-             && (DECL_EXTERNAL (IDENTIFIER_GLOBAL_VALUE (name))
-                 || TREE_PUBLIC (IDENTIFIER_GLOBAL_VALUE (name))))
-           decl = IDENTIFIER_GLOBAL_VALUE (name);
-         else if (IDENTIFIER_LIMBO_VALUE (name) != 0)
+         if (IDENTIFIER_LIMBO_VALUE (name) != 0)
            /* Decls in limbo are always extern, so no need to check that.  */
            decl = IDENTIFIER_LIMBO_VALUE (name);
          else
@@ -2332,39 +2234,6 @@ pushdecl (x)
                             "previous implicit declaration of `%s'");
        }
 
-      /* In PCC-compatibility mode, extern decls of vars with no current decl
-        take effect at top level no matter where they are.  */
-      if (flag_traditional && DECL_EXTERNAL (x)
-         && lookup_name (name) == 0)
-       {
-         tree type = TREE_TYPE (x);
-
-         /* But don't do this if the type contains temporary nodes.  */
-         while (type)
-           {
-             if (type == error_mark_node)
-               break;
-             if (TYPE_CONTEXT (type))
-               {
-                 warning_with_decl (x, "type of external `%s' is not global");
-                 /* By exiting the loop early, we leave TYPE nonzero,
-                    and thus prevent globalization of the decl.  */
-                 break;
-               }
-             else if (TREE_CODE (type) == FUNCTION_TYPE
-                      && TYPE_ARG_TYPES (type) != 0)
-               /* The types might not be truly local,
-                  but the list of arg types certainly is temporary.
-                  Since prototypes are nontraditional,
-                  ok not to do the traditional thing.  */
-               break;
-             type = TREE_TYPE (type);
-           }
-
-         if (type == 0)
-           b = global_binding_level;
-       }
-
       /* This name is new in its binding level.
         Install the new declaration and return it.  */
       if (b == global_binding_level)
@@ -2598,8 +2467,7 @@ implicitly_declare (functionid)
   IDENTIFIER_IMPLICIT_DECL (functionid) = decl;
 
   /* ANSI standard says implicit declarations are in the innermost block.
-     So we record the decl in the standard fashion.
-     If flag_traditional is set, pushdecl does it top-level.  */
+     So we record the decl in the standard fashion.  */
   pushdecl (decl);
 
   /* This is a no-op in c-lang.c or something real in objc-actions.c.  */
@@ -2647,17 +2515,8 @@ redeclaration_error_message (newdecl, olddecl)
 {
   if (TREE_CODE (newdecl) == TYPE_DECL)
     {
-      if (flag_traditional && TREE_TYPE (newdecl) == TREE_TYPE (olddecl))
-       return 0;
-      /* pushdecl creates distinct types for TYPE_DECLs by calling
-        build_type_copy, so the above comparison generally fails.  We do
-        another test against the TYPE_MAIN_VARIANT of the olddecl, which
-        is equivalent to what this code used to do before the build_type_copy
-        call.  The variant type distinction should not matter for traditional
-        code, because it doesn't have type qualifiers.  */
-      if (flag_traditional
-         && TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)) == TREE_TYPE (newdecl))
-       return 0;
+      /* Do not complain about type redeclarations where at least one
+        declaration was in a system header.  */
       if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
        return 0;
       return 1;
@@ -3072,62 +2931,11 @@ c_init_decl_processing ()
     = build_function_type (ptr_type_node,
                           tree_cons (NULL_TREE, ptr_type_node, endlink));
 
-  /* Types which are common to the fortran compiler and libf2c.  When
-     changing these, you also need to be concerned with f/com.h.  */
-
-  if (TYPE_PRECISION (float_type_node)
-      == TYPE_PRECISION (long_integer_type_node))
-    {
-      g77_integer_type_node = long_integer_type_node;
-      g77_uinteger_type_node = long_unsigned_type_node;
-    }
-  else if (TYPE_PRECISION (float_type_node)
-          == TYPE_PRECISION (integer_type_node))
-    {
-      g77_integer_type_node = integer_type_node;
-      g77_uinteger_type_node = unsigned_type_node;
-    }
-  else
-    g77_integer_type_node = g77_uinteger_type_node = NULL_TREE;
-
-  if (g77_integer_type_node != NULL_TREE)
-    {
-      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_integer"),
-                           g77_integer_type_node));
-      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_uinteger"),
-                           g77_uinteger_type_node));
-    }
-
-  if (TYPE_PRECISION (float_type_node) * 2
-      == TYPE_PRECISION (long_integer_type_node))
-    {
-      g77_longint_type_node = long_integer_type_node;
-      g77_ulongint_type_node = long_unsigned_type_node;
-    }
-  else if (TYPE_PRECISION (float_type_node) * 2
-          == TYPE_PRECISION (long_long_integer_type_node))
-    {
-      g77_longint_type_node = long_long_integer_type_node;
-      g77_ulongint_type_node = long_long_unsigned_type_node;
-    }
-  else
-    g77_longint_type_node = g77_ulongint_type_node = NULL_TREE;
-
-  if (g77_longint_type_node != NULL_TREE)
-    {
-      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_longint"),
-                           g77_longint_type_node));
-      pushdecl (build_decl (TYPE_DECL, get_identifier ("__g77_ulongint"),
-                           g77_ulongint_type_node));
-    }
-
   pedantic_lvalues = pedantic;
 
   make_fname_decl = c_make_fname_decl;
   start_fname_decls ();
 
-  incomplete_decl_finalize_hook = finish_incomplete_decl;
-
   /* Record our roots.  */
 
   ggc_add_tree_root (c_global_trees, CTI_MAX);
@@ -3202,11 +3010,6 @@ builtin_function (name, type, function_code, class, library_name)
   tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 1;
-  /* If -traditional, permit redefining a builtin function any way you like.
-     (Though really, if the program redefines these functions,
-     it probably won't work right unless compiled with -fno-builtin.)  */
-  if (flag_traditional && name[0] != '_')
-    DECL_BUILT_IN_NONANSI (decl) = 1;
   if (library_name)
     SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
   make_decl_rtl (decl, NULL);
@@ -3214,6 +3017,10 @@ builtin_function (name, type, function_code, class, library_name)
   DECL_BUILT_IN_CLASS (decl) = class;
   DECL_FUNCTION_CODE (decl) = function_code;
 
+  /* The return builtins leave the current function.  */
+  if (function_code == BUILT_IN_RETURN || function_code == BUILT_IN_EH_RETURN)
+    TREE_THIS_VOLATILE (decl) = 1;
+
   /* Warn if a function in the namespace for users
      is used without an occasion to consider it declared.  */
   if (name[0] != '_' || name[1] != '_')
@@ -3229,7 +3036,7 @@ builtin_function (name, type, function_code, class, library_name)
    attributes.  */
 
 void
-insert_default_attributes (decl)
+c_insert_default_attributes (decl)
      tree decl;
 {
   if (!TREE_PUBLIC (decl))
@@ -3390,8 +3197,7 @@ groktypename (typename)
 
   split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
 
-  typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0,
-                            NULL_TREE);
+  typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0);
 
   /* Apply attributes.  */
   decl_attributes (&typename, attrs, 0);
@@ -3409,7 +3215,7 @@ groktypename_in_parm_context (typename)
     return typename;
   return grokdeclarator (TREE_VALUE (typename),
                         TREE_PURPOSE (typename),
-                        PARM, 0, NULL_TREE);
+                        PARM, 0);
 }
 
 /* Decode a declarator in an ordinary declaration or data definition.
@@ -3442,7 +3248,7 @@ start_decl (declarator, declspecs, initialized, attributes)
     deprecated_state = DEPRECATED_SUPPRESS;
 
   decl = grokdeclarator (declarator, declspecs,
-                        NORMAL, initialized, NULL_TREE);
+                        NORMAL, initialized);
   
   deprecated_state = DEPRECATED_NORMAL;
 
@@ -3545,12 +3351,16 @@ start_decl (declarator, declspecs, initialized, attributes)
      initializer equal to zero.  (Section 3.7.2)
      -fno-common gives strict ANSI behavior.  Usually you don't want it.
      This matters only for variables with external linkage.  */
-  if (! flag_no_common || ! TREE_PUBLIC (decl))
+  if (!initialized && (! flag_no_common || ! TREE_PUBLIC (decl)))
     DECL_COMMON (decl) = 1;
 
   /* Set attributes here so if duplicate decl, will have proper attributes.  */
   decl_attributes (&decl, attributes, 0);
 
+  /* If #pragma weak was used, mark the decl weak now.  */
+  if (current_binding_level == global_binding_level)
+    maybe_apply_pragma_weak (decl);
+
   if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
@@ -3596,6 +3406,8 @@ finish_decl (decl, init, asmspec_tree)
   const char *asmspec = 0;
 
   /* If a name was specified, get the string.  */
+  if (current_binding_level == global_binding_level)
+    asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
   if (asmspec_tree)
     asmspec = TREE_STRING_POINTER (asmspec_tree);
 
@@ -3794,17 +3606,6 @@ finish_decl (decl, init, asmspec_tree)
     get_pending_sizes ();
 }
 
-/* If DECL has a cleanup, build and return that cleanup here.
-   This is a callback called by expand_expr.  */
-
-tree
-maybe_build_cleanup (decl)
-     tree decl ATTRIBUTE_UNUSED;
-{
-  /* There are no cleanups in C.  */
-  return NULL_TREE;
-}
-
 /* Given a parsed parameter declaration,
    decode it into a PARM_DECL and push that on the current binding level.
    Also, for the sake of forward parm decls,
@@ -3820,8 +3621,7 @@ push_parm_decl (parm)
   immediate_size_expand = 0;
 
   decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
-                        TREE_PURPOSE (TREE_PURPOSE (parm)),
-                        PARM, 0, NULL_TREE);
+                        TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
   decl_attributes (&decl, TREE_VALUE (parm), 0);
 
 #if 0
@@ -3981,92 +3781,6 @@ complete_array_type (type, initial_value, do_default)
   return value;
 }
 \f
-/* A bit-field NAME should have an integer type whose precision
-   accurately reflects its WIDTH.  If TYPE is good for that, return
-   it, otherwise create and return the appropriate type.
-
-   This routine also performs sanity checks on the bit-field's type
-   and width, and uses appropriate values if they are invalid.  */
-static tree
-build_bitfield_integer_type (type, width, orig_name)
-     tree type, width;
-     const char *orig_name;
-{
-  tree type_mv;
-  unsigned int max_width;
-  unsigned HOST_WIDE_INT w;
-  const char *name = orig_name ? orig_name: _("<anonymous>");
-
-  /* Necessary?  */
-  STRIP_NOPS (width);
-
-  /* Detect and ignore out of range field width and process valid
-     field widths.  */
-  if (TREE_CODE (width) != INTEGER_CST)
-    {
-      error ("bit-field `%s' width not an integer constant", name);
-      width = integer_one_node;
-    }
-  else
-    {
-      constant_expression_warning (width);
-      if (tree_int_cst_sgn (width) < 0)
-       {
-         error ("negative width in bit-field `%s'", name);
-         width = integer_one_node;
-       }
-      else if (integer_zerop (width) && orig_name)
-       {
-         error ("zero width for bit-field `%s'", name);
-         width = integer_one_node;
-       }
-    }
-
-  /* Detect invalid bit-field type.  */
-  if (TREE_CODE (type) != INTEGER_TYPE
-      && TREE_CODE (type) != BOOLEAN_TYPE
-      && TREE_CODE (type) != ENUMERAL_TYPE)
-    {
-      error ("bit-field `%s' has invalid type", name);
-      type = unsigned_type_node;
-    }
-
-  type_mv = TYPE_MAIN_VARIANT (type);
-  if (pedantic
-      && type_mv != integer_type_node
-      && type_mv != unsigned_type_node
-      && type_mv != c_bool_type_node
-      /* Accept an enum that's equivalent to int or unsigned int.  */
-      && (TREE_CODE (type) != ENUMERAL_TYPE
-         || TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)))
-    pedwarn ("type of bit-field `%s' is a GCC extension", name);
-
-  if (type_mv == c_bool_type_node)
-    max_width = CHAR_TYPE_SIZE;
-  else
-    max_width = TYPE_PRECISION (type);
-
-  if (0 < compare_tree_int (width, max_width))
-    {
-      error ("width of `%s' exceeds its type", name);
-      w = max_width;
-    }
-  else
-    w = tree_low_cst (width, 1);
-
-  if (TREE_CODE (type) == ENUMERAL_TYPE
-      && (w < min_precision (TYPE_MIN_VALUE (type), TREE_UNSIGNED (type))
-         || w < min_precision (TYPE_MAX_VALUE (type), TREE_UNSIGNED (type))))
-    warning ("`%s' is narrower than values of its type", name);
-
-  /* The type of a bit-field should have precision the same as the
-     bit-field's width.  */
-  if (w != TYPE_PRECISION (type))
-    type = build_nonstandard_integer_type (w, TREE_UNSIGNED (type));
-
-  return type;
-}
-\f
 /* Given declspecs and a declarator,
    determine the name and type of the object declared
    and construct a ..._DECL node for it.
@@ -4086,9 +3800,8 @@ build_bitfield_integer_type (type, width, orig_name)
      TYPENAME if for a typename (in a cast or sizeof).
       Don't make a DECL node; just return the ..._TYPE node.
      FIELD for a struct or union field; make a FIELD_DECL.
+     BITFIELD for a field with specified width.
    INITIALIZED is 1 if the decl has an initializer.
-   WIDTH is non-NULL for bit-fields, and is an INTEGER_CST node representing
-   the width of the bit-field.
 
    In the TYPENAME case, DECLARATOR is really an absolute declarator.
    It may also be so in the PARM case, for a prototype where the
@@ -4098,12 +3811,11 @@ build_bitfield_integer_type (type, width, orig_name)
    and `extern' are interpreted.  */
 
 static tree
-grokdeclarator (declarator, declspecs, decl_context, initialized, width)
+grokdeclarator (declarator, declspecs, decl_context, initialized)
      tree declspecs;
      tree declarator;
      enum decl_context decl_context;
      int initialized;
-     tree width;
 {
   int specbits = 0;
   tree spec;
@@ -4118,16 +3830,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
   int explicit_char = 0;
   int defaulted_int = 0;
   tree typedef_decl = 0;
-  const char *name, *orig_name;
+  const char *name;
   tree typedef_type = 0;
   int funcdef_flag = 0;
   enum tree_code innermost_code = ERROR_MARK;
+  int bitfield = 0;
   int size_varies = 0;
   tree decl_attr = NULL_TREE;
   tree array_ptr_quals = NULL_TREE;
   int array_parm_static = 0;
   tree returned_attrs = NULL_TREE;
-  bool bitfield = width != NULL_TREE;
+
+  if (decl_context == BITFIELD)
+    bitfield = 1, decl_context = FIELD;
 
   if (decl_context == FUNCDEF)
     funcdef_flag = 1, decl_context = NORMAL;
@@ -4160,7 +3875,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
        default:
          abort ();
        }
-    orig_name = name;
     if (name == 0)
       name = "type name";
   }
@@ -4377,11 +4091,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
     }
 
   /* Decide whether an integer type is signed or not.
-     Optionally treat bit-fields as signed by default.  */
+     Optionally treat bitfields as signed by default.  */
   if (specbits & 1 << (int) RID_UNSIGNED
-      /* Traditionally, all bit-fields are unsigned.  */
-      || (bitfield && flag_traditional
-         && (! explicit_flag_signed_bitfields || !flag_signed_bitfields))
       || (bitfield && ! flag_signed_bitfields
          && (explicit_int || defaulted_int || explicit_char
              /* A typedef for plain `int' without `signed'
@@ -4400,7 +4111,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
       else if (type == char_type_node)
        type = unsigned_char_type_node;
       else if (typedef_decl)
-       type = unsigned_type (type);
+       type = c_common_unsigned_type (type);
       else
        type = unsigned_type_node;
     }
@@ -4452,11 +4163,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
        }
     }
 
-  /* A bit-field needs its type to have precision equal to its width,
-     rather than the precision of the specified standard type.  */
-  if (bitfield)
-    type = build_bitfield_integer_type (type, width, orig_name);
-
   /* Figure out the type qualifiers for the declaration.  There are
      two ways a declaration can become qualified.  One is something
      like `const int i' where the `const' is explicit.  Another is
@@ -4602,9 +4308,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
          if (inner_decl == NULL_TREE
              || TREE_CODE (inner_decl) == IDENTIFIER_NODE)
            attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
-         if (TREE_CODE (inner_decl) == CALL_EXPR)
+         else if (TREE_CODE (inner_decl) == CALL_EXPR)
            attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
-         if (TREE_CODE (inner_decl) == ARRAY_REF)
+         else if (TREE_CODE (inner_decl) == ARRAY_REF)
            attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
          returned_attrs = decl_attributes (&type,
                                            chainon (returned_attrs, attrs),
@@ -4615,7 +4321,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
          tree itype = NULL_TREE;
          tree size = TREE_OPERAND (declarator, 1);
          /* The index is a signed object `sizetype' bits wide.  */
-         tree index_type = signed_type (sizetype);
+         tree index_type = c_common_signed_type (sizetype);
 
          array_ptr_quals = TREE_TYPE (declarator);
          array_parm_static = TREE_STATIC (declarator);
@@ -4800,13 +4506,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
              type = integer_type_node;
            }
 
-#ifndef TRADITIONAL_RETURN_FLOAT
-         /* Traditionally, declaring return type float means double.  */
-
-         if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node)
-           type = double_type_node;
-#endif /* TRADITIONAL_RETURN_FLOAT */
-
          /* Construct the function type and go to the next
             inner layer of declarator.  */
 
@@ -5106,6 +4805,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
     else if (decl_context == FIELD)
       {
        /* Structure field.  It may not be a function.  */
+
        if (TREE_CODE (type) == FUNCTION_TYPE)
          {
            error ("field `%s' declared as a function", name);
@@ -5129,29 +4829,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
 #endif
          }
        decl = build_decl (FIELD_DECL, declarator, type);
-       if (bitfield)
-         {
-           DECL_SIZE (decl) = bitsize_int (TYPE_PRECISION (type));
-           DECL_BIT_FIELD (decl) = 1;
-           SET_DECL_C_BIT_FIELD (decl);
-
-           /* Bit-field width 0 => force desired amount of alignment.  */
-           if (TYPE_PRECISION (type) == 0)
-             {
-#ifdef EMPTY_FIELD_BOUNDARY
-               DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
-                                        EMPTY_FIELD_BOUNDARY);
-#endif
-#ifdef PCC_BITFIELD_TYPE_MATTERS
-               if (PCC_BITFIELD_TYPE_MATTERS)
-                 {
-                   DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
-                                            TYPE_ALIGN (type));
-                   DECL_USER_ALIGN (decl) |= TYPE_USER_ALIGN (type);
-                 }
-#endif
-             }
-         }
        DECL_NONADDRESSABLE_P (decl) = bitfield;
 
        if (size_varies)
@@ -5201,6 +4878,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
        TREE_PUBLIC (decl)
          = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
 
+       if (defaulted_int)
+         C_FUNCTION_IMPLICIT_INT (decl) = 1;
+
        /* Record presence of `inline', if it is reasonable.  */
        if (MAIN_NAME_P (declarator))
          {
@@ -5293,7 +4973,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, width)
        Otherwise, the fact that those components are volatile
        will be ignored, and would even crash the compiler.  */
     if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl)))
-      mark_addressable (decl);
+      c_mark_addressable (decl);
 
     decl_attributes (&decl, returned_attrs, 0);
 
@@ -5654,7 +5334,7 @@ start_struct (code, name)
 
 /* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
    of a structure component, returning a FIELD_DECL node.
-   WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
+   WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.
 
    This is done during the parsing of the struct declaration.
    The FIELD_DECL nodes are chained together and the lot of them
@@ -5680,9 +5360,10 @@ grokfield (filename, line, declarator, declspecs, width)
        }
     }
 
-  value = grokdeclarator (declarator, declspecs, FIELD, 0, width);
+  value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
 
   finish_decl (value, NULL_TREE, NULL_TREE);
+  DECL_INITIAL (value) = width;
 
   maybe_objc_check_decl (value);
   return value;
@@ -5717,7 +5398,7 @@ finish_struct (t, fieldlist, attributes)
        if (pedantic)
          pedwarn ("%s defined inside parms",
                   TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
-       else if (! flag_traditional)
+       else
          warning ("%s defined inside parms",
                   TREE_CODE (t) == UNION_TYPE ? _("union") : _("structure"));
       }
@@ -5734,7 +5415,10 @@ finish_struct (t, fieldlist, attributes)
                 fieldlist ? _("named members") : _("members"));
     }
 
-  /* Install struct as DECL_CONTEXT of each field decl.  */
+  /* Install struct as DECL_CONTEXT of each field decl.
+     Also process specified field sizes,m which is found in the DECL_INITIAL.
+     Store 0 there, except for ": 0" fields (so we can find them
+     and delete them, below).  */
 
   saw_named_field = 0;
   for (x = fieldlist; x; x = TREE_CHAIN (x))
@@ -5770,7 +5454,94 @@ finish_struct (t, fieldlist, attributes)
        error ("nested redefinition of `%s'",
               IDENTIFIER_POINTER (TYPE_NAME (t)));
 
-      if (TREE_TYPE (x) != error_mark_node && !DECL_BIT_FIELD (x))
+      /* Detect invalid bit-field size.  */
+      if (DECL_INITIAL (x))
+       STRIP_NOPS (DECL_INITIAL (x));
+      if (DECL_INITIAL (x))
+       {
+         if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
+           constant_expression_warning (DECL_INITIAL (x));
+         else
+           {
+             error_with_decl (x,
+                              "bit-field `%s' width not an integer constant");
+             DECL_INITIAL (x) = NULL;
+           }
+       }
+
+      /* Detect invalid bit-field type.  */
+      if (DECL_INITIAL (x)
+         && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
+         && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
+         && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
+       {
+         error_with_decl (x, "bit-field `%s' has invalid type");
+         DECL_INITIAL (x) = NULL;
+       }
+
+      if (DECL_INITIAL (x) && pedantic
+         && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
+         && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
+         && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
+         /* Accept an enum that's equivalent to int or unsigned int.  */
+         && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
+              && (TYPE_PRECISION (TREE_TYPE (x))
+                  == TYPE_PRECISION (integer_type_node))))
+       pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C");
+
+      /* Detect and ignore out of range field width and process valid
+        field widths.  */
+      if (DECL_INITIAL (x))
+       {
+         int max_width
+           = (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node
+              ? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
+
+         if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
+           error_with_decl (x, "negative width in bit-field `%s'");
+         else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
+           pedwarn_with_decl (x, "width of `%s' exceeds its type");
+         else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
+           error_with_decl (x, "zero width for bit-field `%s'");
+         else
+           {
+             /* The test above has assured us that TREE_INT_CST_HIGH is 0.  */
+             unsigned HOST_WIDE_INT width
+               = tree_low_cst (DECL_INITIAL (x), 1);
+
+             if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
+                 && (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
+                                            TREE_UNSIGNED (TREE_TYPE (x)))
+                     || (width
+                         < min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
+                                          TREE_UNSIGNED (TREE_TYPE (x))))))
+               warning_with_decl (x,
+                                  "`%s' is narrower than values of its type");
+
+             DECL_SIZE (x) = bitsize_int (width);
+             DECL_BIT_FIELD (x) = 1;
+             SET_DECL_C_BIT_FIELD (x);
+
+             if (width == 0
+                 && ! (* targetm.ms_bitfield_layout_p) (t))
+               {
+                 /* field size 0 => force desired amount of alignment.  */
+#ifdef EMPTY_FIELD_BOUNDARY
+                 DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
+#endif
+#ifdef PCC_BITFIELD_TYPE_MATTERS
+                 if (PCC_BITFIELD_TYPE_MATTERS)
+                   {
+                     DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
+                                           TYPE_ALIGN (TREE_TYPE (x)));
+                     DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
+                   }
+#endif
+               }
+           }
+       }
+
+      else if (TREE_TYPE (x) != error_mark_node)
        {
          unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
                                    : TYPE_ALIGN (TREE_TYPE (x)));
@@ -5782,6 +5553,8 @@ finish_struct (t, fieldlist, attributes)
            DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
        }
 
+      DECL_INITIAL (x) = 0;
+
       /* Detect flexible array member in an invalid context.  */
       if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
          && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
@@ -6020,7 +5793,7 @@ finish_enum (enumtype, values, attributes)
                   min_precision (maxnode, unsign));
   if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
     {
-      tree narrowest = type_for_size (precision, unsign);
+      tree narrowest = c_common_type_for_size (precision, unsign);
       if (narrowest == 0)
        {
          warning ("enumeration values exceed range of largest integer");
@@ -6033,7 +5806,7 @@ finish_enum (enumtype, values, attributes)
     precision = TYPE_PRECISION (integer_type_node);
 
   if (precision == TYPE_PRECISION (integer_type_node))
-    enum_value_type = type_for_size (precision, 0);
+    enum_value_type = c_common_type_for_size (precision, 0);
   else
     enum_value_type = enumtype;
 
@@ -6161,11 +5934,11 @@ build_enumerator (name, value)
   /* Now create a declaration for the enum value name.  */
 
   type = TREE_TYPE (value);
-  type = type_for_size (MAX (TYPE_PRECISION (type),
-                            TYPE_PRECISION (integer_type_node)),
-                       ((flag_traditional
-                         || TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node))
-                        && TREE_UNSIGNED (type)));
+  type = c_common_type_for_size (MAX (TYPE_PRECISION (type),
+                                     TYPE_PRECISION (integer_type_node)),
+                                (TYPE_PRECISION (type)
+                                 >= TYPE_PRECISION (integer_type_node)
+                                 && TREE_UNSIGNED (type)));
 
   decl = build_decl (CONST_DECL, name, type);
   DECL_INITIAL (decl) = convert (type, value);
@@ -6197,6 +5970,7 @@ start_function (declspecs, declarator, attributes)
 
   current_function_returns_value = 0;  /* Assume, until we see it does.  */
   current_function_returns_null = 0;
+  current_function_returns_abnormally = 0;
   warn_about_return_type = 0;
   current_extern_inline = 0;
   c_function_varargs = 0;
@@ -6206,7 +5980,7 @@ start_function (declspecs, declarator, attributes)
   /* Don't expand any sizes in the return type of the function.  */
   immediate_size_expand = 0;
 
-  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE);
+  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
 
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
@@ -6218,6 +5992,10 @@ start_function (declspecs, declarator, attributes)
 
   decl_attributes (&decl1, attributes, 0);
 
+  /* If #pragma weak was used, mark the decl weak now.  */
+  if (current_binding_level == global_binding_level)
+    maybe_apply_pragma_weak (decl1);
+
   if (DECL_DECLARED_INLINE_P (decl1)
       && DECL_UNINLINABLE (decl1)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
@@ -6392,12 +6170,10 @@ start_function (declspecs, declarator, attributes)
   /* Promote the value to int before returning it.  */
   if (c_promoting_integer_type_p (restype))
     {
-      /* It retains unsignedness if traditional
-        or if not really getting wider.  */
+      /* It retains unsignedness if not really getting wider.  */
       if (TREE_UNSIGNED (restype)
-         && (flag_traditional
-             || (TYPE_PRECISION (restype)
-                 == TYPE_PRECISION (integer_type_node))))
+         && (TYPE_PRECISION (restype)
+                 == TYPE_PRECISION (integer_type_node)))
        restype = unsigned_type_node;
       else
        restype = integer_type_node;
@@ -6616,15 +6392,6 @@ store_parm_decls ()
              layout_decl (found, 0);
            }
 
-         /* Traditionally, a parm declared float is actually a double.  */
-         if (found && flag_traditional
-             && TYPE_MAIN_VARIANT (TREE_TYPE (found)) == float_type_node)
-           {
-             TREE_TYPE (found) = double_type_node;
-             DECL_ARG_TYPE (found) = double_type_node;
-             layout_decl (found, 0);
-           }
-
          /* If no declaration found, default to int.  */
          if (!found)
            {
@@ -6758,11 +6525,7 @@ store_parm_decls ()
                             "prototype declaration");
                        }
                    }
-                 /* If -traditional, allow `int' argument to match
-                    `unsigned' prototype.  */
-                 else if (! (flag_traditional
-                             && TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == integer_type_node
-                             && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node))
+                 else
                    {
                      error ("argument `%s' doesn't match prototype",
                             IDENTIFIER_POINTER (DECL_NAME (parm)));
@@ -6874,17 +6637,21 @@ store_parm_decls ()
 
    This is called after parsing the body of the function definition.
 
-   NESTED is nonzero if the function being finished is nested in another.  */
+   NESTED is nonzero if the function being finished is nested in another.
+   CAN_DEFER_P is nonzero if the function may be deferred.  */
 
 void
-finish_function (nested)
+finish_function (nested, can_defer_p)
      int nested;
+     int can_defer_p;
 {
   tree fndecl = current_function_decl;
 
-/*  TREE_READONLY (fndecl) = 1;
-    This caused &foo to be of type ptr-to-const-function
-    which then got a warning when stored in a ptr-to-function variable.  */
+#if 0
+  /* This caused &foo to be of type ptr-to-const-function which then
+     got a warning when stored in a ptr-to-function variable.  */
+  TREE_READONLY (fndecl) = 1;
+#endif
 
   poplevel (1, 0, 1);
   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
@@ -6893,13 +6660,6 @@ finish_function (nested)
 
   DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
 
-  /* Obey `register' declarations if `setjmp' is called in this fn.  */
-  if (flag_traditional && current_function_calls_setjmp)
-    {
-      setjmp_protect (DECL_INITIAL (fndecl));
-      setjmp_protect_args ();
-    }
-
   if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted)
     {
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
@@ -6926,6 +6686,22 @@ finish_function (nested)
 
   /* Tie off the statement tree for this function.  */
   finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
+
+  /* Complain if there's just no return statement.  */
+  if (warn_return_type
+      && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
+      && !current_function_returns_value && !current_function_returns_null
+      /* Don't complain if we abort.  */
+      && !current_function_returns_abnormally
+      /* Don't warn for main().  */
+      && !MAIN_NAME_P (DECL_NAME (fndecl))
+      /* Or if they didn't actually specify a return type.  */
+      && !C_FUNCTION_IMPLICIT_INT (fndecl)
+      /* Normally, with -Wreturn-type, flow will complain.  Unless we're an
+        inline function, as we might never be compiled separately.  */
+      && DECL_INLINE (fndecl))
+    warning ("no return statement in function returning non-void");
+
   /* Clear out memory we no longer need.  */
   free_after_parsing (cfun);
   /* Since we never call rest_of_compilation, we never clear
@@ -6936,7 +6712,8 @@ finish_function (nested)
   if (! nested)
     {
       /* Generate RTL for the body of this function.  */
-      c_expand_body (fndecl, nested, 1);
+      c_expand_body (fndecl, nested, can_defer_p);
+
       /* Let the error reporting routines know that we're outside a
         function.  For a nested function, this value is used in
         pop_c_function_context and then reset via pop_function_context.  */
@@ -7014,6 +6791,7 @@ c_expand_body (fndecl, nested_p, can_defer_p)
 
   /* Initialize the RTL code for the function.  */
   current_function_decl = fndecl;
+  input_filename = DECL_SOURCE_FILE (fndecl);
   init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
 
   /* This function is being processed in whole-function mode.  */
@@ -7214,6 +6992,7 @@ struct c_language_function
   tree shadowed_labels;
   int returns_value;
   int returns_null;
+  int returns_abnormally;
   int warn_about_return_type;
   int extern_inline;
   struct binding_level *binding_level;
@@ -7237,6 +7016,7 @@ push_c_function_context (f)
   p->shadowed_labels = shadowed_labels;
   p->returns_value = current_function_returns_value;
   p->returns_null = current_function_returns_null;
+  p->returns_abnormally = current_function_returns_abnormally;
   p->warn_about_return_type = warn_about_return_type;
   p->extern_inline = current_extern_inline;
   p->binding_level = current_binding_level;
@@ -7274,6 +7054,7 @@ pop_c_function_context (f)
   shadowed_labels = p->shadowed_labels;
   current_function_returns_value = p->returns_value;
   current_function_returns_null = p->returns_null;
+  current_function_returns_abnormally = p->returns_abnormally;
   warn_about_return_type = p->warn_about_return_type;
   current_extern_inline = p->extern_inline;
   current_binding_level = p->binding_level;
@@ -7300,10 +7081,10 @@ mark_c_function_context (f)
   mark_binding_level (&p->binding_level);
 }
 
-/* Copy the DECL_LANG_SPECIFIC data associated with NODE.  */
+/* Copy the DECL_LANG_SPECIFIC data associated with DECL.  */
 
 void
-copy_lang_decl (decl)
+c_dup_lang_specific_decl (decl)
      tree decl;
 {
   struct lang_decl *ld;
@@ -7320,7 +7101,7 @@ copy_lang_decl (decl)
 /* Mark the language specific bits in T for GC.  */
 
 void
-lang_mark_tree (t)
+c_mark_tree (t)
      tree t;
 {
   if (TREE_CODE (t) == IDENTIFIER_NODE)