OSDN Git Service

* c-decl.c (c_decode_option): Don't handle -lang-objc.
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index b8421a7..98aae30 100644 (file)
@@ -41,11 +41,7 @@ Boston, MA 02111-1307, USA.  */
 #include "defaults.h"
 #include "ggc.h"
 #include "tm_p.h"
-
-#if USE_CPPLIB
 #include "cpplib.h"
-extern cpp_reader parse_in;
-#endif
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -77,10 +73,23 @@ enum decl_context
 #ifndef WINT_TYPE
 #define WINT_TYPE "unsigned int"
 #endif
-\f
-/* Do GC.  */
-int ggc_p = 1;
 
+#ifndef INTMAX_TYPE
+#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)    \
+                    ? "int"                                    \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long int"                            \
+                       : "long long int"))
+#endif
+
+#ifndef UINTMAX_TYPE
+#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)   \
+                    ? "unsigned int"                           \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long unsigned int"                   \
+                       : "long long unsigned int"))
+#endif
+\f
 /* Nonzero if we have seen an invalid cross reference
    to a struct, union, or enum, but not yet printed the message.  */
 
@@ -330,20 +339,11 @@ int flag_short_wchar;
 
 int flag_no_asm;
 
-/* Nonzero means don't recognize any builtin functions.  */
-
-int flag_no_builtin;
-
-/* Nonzero means don't recognize the non-ANSI builtin functions.
-   -ansi sets this.  */
-
-int flag_no_nonansi_builtin;
-
 /* Nonzero means do some things the same way PCC does.  */
 
 int flag_traditional;
 
-/* Nonzero means enable C89 Amendment 1 features, other than digraphs.  */
+/* Nonzero means enable C89 Amendment 1 features.  */
 
 int flag_isoc94 = 0;
 
@@ -351,10 +351,6 @@ int flag_isoc94 = 0;
 
 int flag_isoc99 = 0;
 
-/* Nonzero means accept digraphs.  */
-
-int flag_digraphs = 1;
-
 /* Nonzero means that we have builtin functions, and main is an int */
 
 int flag_hosted = 1;
@@ -403,9 +399,9 @@ int warn_cast_qual;
 
 int warn_bad_function_cast;
 
-/* Warn about functions which might be candidates for attribute noreturn.  */
+/* Warn about functions which might be candidates for format attributes.  */
 
-int warn_missing_noreturn;
+int warn_missing_format_attribute;
 
 /* Warn about traditional constructs whose meanings changed in ANSI C.  */
 
@@ -506,20 +502,15 @@ c_decode_option (argc, argv)
      char **argv;
 {
   int strings_processed;
+  const char *option_value = NULL;
   char *p = argv[0];
-#if USE_CPPLIB
-  strings_processed = cpp_handle_option (&parse_in, argc, argv);
-#else
-  strings_processed = 0;
-#endif /* ! USE_CPPLIB */
 
-  if (!strcmp (p, "-lang-objc"))
-    c_language = clk_objective_c;
-  else if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
+  strings_processed = cpp_handle_option (parse_in, argc, argv);
+
+  if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
     {
       flag_traditional = 1;
       flag_writable_strings = 1;
-      flag_digraphs = 0;
     }
   else if (!strcmp (p, "-fallow-single-precision"))
     flag_allow_single_precision = 1;
@@ -540,7 +531,6 @@ c_decode_option (argc, argv)
     {
       flag_traditional = 0;
       flag_writable_strings = 0;
-      flag_digraphs = 1;
     }
   else if (!strncmp (p, "-std=", 5))
     {
@@ -560,9 +550,8 @@ c_decode_option (argc, argv)
          || !strcmp (argstart, "c89"))
        {
        iso_1990:
-         flag_digraphs = 0;
          flag_isoc94 = 0;
-       iso_1990_digraphs:
+       iso_1994:
          flag_traditional = 0;
          flag_writable_strings = 0;
          flag_no_asm = 1;
@@ -572,9 +561,8 @@ c_decode_option (argc, argv)
        }
       else if (!strcmp (argstart, "iso9899:199409"))
        {
-         flag_digraphs = 1;
          flag_isoc94 = 1;
-         goto iso_1990_digraphs;
+         goto iso_1994;
        }
       else if (!strcmp (argstart, "iso9899:199x")
               || !strcmp (argstart, "iso9899:1999")
@@ -587,7 +575,6 @@ c_decode_option (argc, argv)
          flag_no_nonansi_builtin = 1;
          flag_noniso_default_format_attributes = 0;
          flag_isoc99 = 1;
-         flag_digraphs = 1;
          flag_isoc94 = 1;
        }
       else if (!strcmp (argstart, "gnu89"))
@@ -598,7 +585,6 @@ c_decode_option (argc, argv)
          flag_no_nonansi_builtin = 0;
          flag_noniso_default_format_attributes = 1;
          flag_isoc99 = 0;
-         flag_digraphs = 1;
          flag_isoc94 = 0;
        }
       else if (!strcmp (argstart, "gnu9x") || !strcmp (argstart, "gnu99"))
@@ -609,7 +595,6 @@ c_decode_option (argc, argv)
          flag_no_nonansi_builtin = 0;
          flag_noniso_default_format_attributes = 1;
          flag_isoc99 = 1;
-         flag_digraphs = 1;
          flag_isoc94 = 1;
        }
       else
@@ -663,6 +648,14 @@ c_decode_option (argc, argv)
     flag_no_builtin = 0;
   else if (!strcmp (p, "-fno-builtin"))
     flag_no_builtin = 1;
+  else if ((option_value
+           = skip_leading_substring (p, "-fdump-translation-unit-")))
+    {
+      if (p[22] == '\0')
+       error ("no file specified with -fdump-translation-unit");
+      else
+       flag_dump_translation_unit = option_value;
+    }
   else if (!strcmp (p, "-ansi"))
     goto iso_1990;
   else if (!strcmp (p, "-Werror-implicit-function-declaration"))
@@ -703,6 +696,10 @@ c_decode_option (argc, argv)
     warn_missing_noreturn = 1;
   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"))
@@ -753,6 +750,10 @@ c_decode_option (argc, argv)
     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"))
@@ -814,6 +815,7 @@ c_decode_option (argc, argv)
       warn_format = 1;
       warn_char_subscripts = 1;
       warn_parentheses = 1;
+      warn_sequence_point = 1;
       warn_missing_braces = 1;
       /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding can turn
         it off only if it's not explicit.  */
@@ -1100,6 +1102,12 @@ poplevel (keep, reverse, functionbody)
          TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
       }
 
+  /* We used to warn about unused variables in expand_end_bindings,
+     i.e. while generating RTL.  But in function-at-a-time mode we may
+     choose to never expand a function at all (e.g. auto inlining), so
+     we do this explicitly now.  */
+  warn_about_unused_variables (getdecls ());
+
   /* If there were any declarations or structure tags in that level,
      or if this level is a function body,
      create a BLOCK to record them for the life of this function.  */
@@ -2035,9 +2043,9 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
   {
     register unsigned olddecl_uid = DECL_UID (olddecl);
 
-    bcopy ((char *) newdecl + sizeof (struct tree_common),
-          (char *) olddecl + sizeof (struct tree_common),
-          sizeof (struct tree_decl) - sizeof (struct tree_common));
+    memcpy ((char *) olddecl + sizeof (struct tree_common),
+           (char *) newdecl + sizeof (struct tree_common),
+           sizeof (struct tree_decl) - sizeof (struct tree_common));
     DECL_UID (olddecl) = olddecl_uid;
   }
 
@@ -3076,10 +3084,28 @@ init_decl_processing ()
   wint_type_node =
     TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WINT_TYPE)));
 
+  intmax_type_node =
+    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (INTMAX_TYPE)));
+  uintmax_type_node =
+    TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (UINTMAX_TYPE)));
+
   boolean_type_node = integer_type_node;
   boolean_true_node = integer_one_node;
   boolean_false_node = integer_zero_node;
 
+  /* With GCC, C99's _Bool is always of size 1.  */
+  c_bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+  TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
+  TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
+  TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
+  TYPE_PRECISION (c_bool_type_node) = 1;
+  pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
+                       c_bool_type_node));
+  c_bool_false_node = build_int_2 (0, 0);
+  TREE_TYPE (c_bool_false_node) = c_bool_type_node;
+  c_bool_true_node = build_int_2 (1, 0);
+  TREE_TYPE (c_bool_true_node) = c_bool_type_node;
+
   string_type_node = build_pointer_type (char_type_node);
   const_string_type_node
     = build_pointer_type (build_type_variant (char_type_node, 1, 0));
@@ -3111,7 +3137,7 @@ init_decl_processing ()
     = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
   unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_type_node);
 
-  c_common_nodes_and_builtins (0, flag_no_builtin, flag_no_nonansi_builtin);
+  c_common_nodes_and_builtins ();
 
   endlink = void_list_node;
   ptr_ftype_void = build_function_type (ptr_type_node, endlink);
@@ -3482,7 +3508,12 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
       default:
        /* Don't allow initializations for incomplete types
           except for arrays which might be completed by the initialization.  */
-       if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
+
+       /* This can happen if the array size is an undefined macro.  We already
+          gave a warning, so we don't need another one.  */
+       if (TREE_TYPE (decl) == error_mark_node)
+         initialized = 0;
+       else if (COMPLETE_TYPE_P (TREE_TYPE (decl)))
          {
            /* A complete type is ok if size is fixed.  */
 
@@ -3560,7 +3591,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
       && DECL_RTL (tem) == 0
       && !DECL_CONTEXT (tem))
     {
-      if (COMPLETE_TYPE_P (TREE_TYPE (tem)))
+      if (TREE_TYPE (tem) != error_mark_node
+         && COMPLETE_TYPE_P (TREE_TYPE (tem)))
        expand_decl (tem);
       else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
               && DECL_INITIAL (tem) != 0)
@@ -3582,7 +3614,7 @@ finish_decl (decl, init, asmspec_tree)
 {
   register tree type = TREE_TYPE (decl);
   int was_incomplete = (DECL_SIZE (decl) == 0);
-  char *asmspec = 0;
+  const char *asmspec = 0;
 
   /* If a name was specified, get the string.   */
   if (asmspec_tree)
@@ -3629,7 +3661,7 @@ finish_decl (decl, init, asmspec_tree)
       if (failure == 1)
        error_with_decl (decl, "initializer fails to determine size of `%s'");
 
-      if (failure == 2)
+      else if (failure == 2)
        {
          if (do_default)
            error_with_decl (decl, "array size missing in `%s'");
@@ -3646,8 +3678,8 @@ finish_decl (decl, init, asmspec_tree)
       /* TYPE_MAX_VALUE is always one less than the number of elements
         in the array, because we start counting at zero.  Therefore,
         warn only if the value is less than zero.  */
-      if (pedantic && TYPE_DOMAIN (type) != 0
-         && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
+      else if (pedantic && TYPE_DOMAIN (type) != 0
+             && tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
        error_with_decl (decl, "zero or negative size array `%s'");
 
       layout_decl (decl, 0);
@@ -3655,10 +3687,13 @@ finish_decl (decl, init, asmspec_tree)
 
   if (TREE_CODE (decl) == VAR_DECL)
     {
-      if (DECL_SIZE (decl) == 0 && COMPLETE_TYPE_P (TREE_TYPE (decl)))
+      if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node
+         && COMPLETE_TYPE_P (TREE_TYPE (decl)))
        layout_decl (decl, 0);
 
       if (DECL_SIZE (decl) == 0
+         /* Don't give an error if we already gave one earlier.  */
+         && TREE_TYPE (decl) != error_mark_node
          && (TREE_STATIC (decl)
              ?
                /* A static variable with an incomplete type
@@ -3716,7 +3751,10 @@ finish_decl (decl, init, asmspec_tree)
       else
        {
          if (asmspec)
-           DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+           {
+             DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
+             DECL_C_HARD_REGISTER (decl) = 1;
+           }
          add_decl_stmt (decl);
        }
 
@@ -4078,7 +4116,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
     {
       if ((! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
                          | (1 << (int) RID_SIGNED)
-                         | (1 << (int) RID_UNSIGNED))))
+                         | (1 << (int) RID_UNSIGNED)
+                         | (1 << (int) RID_COMPLEX))))
          /* Don't warn about typedef foo = bar.  */
          && ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
          && ! in_system_header)
@@ -4209,6 +4248,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
   if (specbits & 1 << (int) RID_COMPLEX)
     {
+      if (pedantic && !flag_isoc99)
+       pedwarn ("ISO C89 does not support complex types");
       /* If we just have "complex", it is equivalent to
         "complex double", but if any modifiers at all are specified it is
         the complex form of TYPE.  E.g, "complex short" is
@@ -4218,9 +4259,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          && ! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
                            | (1 << (int) RID_SIGNED)
                            | (1 << (int) RID_UNSIGNED))))
-       type = complex_double_type_node;
+       {
+         if (pedantic)
+           pedwarn ("ISO C does not support plain `complex' meaning `double complex'");
+         type = complex_double_type_node;
+       }
       else if (type == integer_type_node)
-       type = complex_integer_type_node;
+       {
+         if (pedantic)
+           pedwarn ("ISO C does not support complex integer types");
+         type = complex_integer_type_node;
+       }
       else if (type == float_type_node)
        type = complex_float_type_node;
       else if (type == double_type_node)
@@ -4228,7 +4277,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       else if (type == long_double_type_node)
        type = complex_long_double_type_node;
       else
-       type = build_complex_type (type);
+       {
+         if (pedantic)
+           pedwarn ("ISO C does not support complex integer types");
+         type = build_complex_type (type);
+       }
     }
 
   /* Figure out the type qualifiers for the declaration.  There are
@@ -4424,27 +4477,53 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                    }
                }
 
-             /* Convert size to index_type, so that if it is a variable
-                the computations will be done in the proper mode.  */
-             itype = fold (build (MINUS_EXPR, index_type,
-                                  convert (index_type, size),
-                                  convert (index_type, size_one_node)));
-
-             /* If that overflowed, the array is too big.
-                ??? While a size of INT_MAX+1 technically shouldn't cause
-                an overflow (because we subtract 1), the overflow is recorded
-                during the conversion to index_type, before the subtraction.
-                Handling this case seems like an unnecessary complication.  */
-             if (TREE_OVERFLOW (itype))
+             if (integer_zerop (size))
                {
-                 error ("size of array `%s' is too large", name);
-                 type = error_mark_node;
-                 continue;
+                 /* A zero-length array cannot be represented with an
+                    unsigned index type, which is what we'll get with
+                    build_index_type.  Create an open-ended range instead.  */
+                 itype = build_range_type (sizetype, size, NULL_TREE);
+               }
+             else
+               {
+                 /* Compute the maximum valid index, that is, size - 1.
+                    Do the calculation in index_type, so that if it is
+                    a variable the computations will be done in the
+                    proper mode.  */
+                 itype = fold (build (MINUS_EXPR, index_type,
+                                      convert (index_type, size),
+                                      convert (index_type, size_one_node)));
+
+                 /* If that overflowed, the array is too big.
+                    ??? While a size of INT_MAX+1 technically shouldn't
+                    cause an overflow (because we subtract 1), the overflow
+                    is recorded during the conversion to index_type, before
+                    the subtraction.  Handling this case seems like an
+                    unnecessary complication.  */
+                 if (TREE_OVERFLOW (itype))
+                   {
+                     error ("size of array `%s' is too large", name);
+                     type = error_mark_node;
+                     continue;
+                   }
+
+                 if (size_varies)
+                   itype = variable_size (itype);
+                 itype = build_index_type (itype);
                }
+           }
+         else if (decl_context == FIELD)
+           {
+             /* ??? Need to check somewhere that this is a structure
+                and not a union, that this field is last, and that 
+                this structure has at least one other named member.  */
+
+             if (pedantic && !flag_isoc99 && !in_system_header)
+               pedwarn ("ISO C89 does not support flexible array members");
 
-             if (size_varies)
-               itype = variable_size (itype);
-             itype = build_index_type (itype);
+             /* ISO C99 Flexible array members are effectively identical
+                to GCC's zero-length array extension.  */
+             itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
            }
 
 #if 0
@@ -4529,7 +4608,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          /* Type qualifiers before the return type of the function
             qualify the return type, not the function type.  */
          if (type_quals)
-           type = c_build_qualified_type (type, type_quals);
+           {
+             /* Type qualifiers on a function return type are normally
+                permitted by the standard but have no effect, so give a
+                warning at -W.  Qualifiers on a void return type have
+                meaning as a GNU extension, and are banned on function
+                definitions in ISO C.  FIXME: strictly we shouldn't
+                pedwarn for qualified void return types except on function
+                definitions, but not doing so could lead to the undesirable
+                state of a "volatile void" function return type not being
+                warned about, and a use of the function being compiled
+                with GNU semantics, with no diagnostics under -pedantic.  */
+             if (VOID_TYPE_P (type) && pedantic && !in_system_header)
+               pedwarn ("ISO C forbids qualified void function return type");
+             else if (extra_warnings
+                      && !(VOID_TYPE_P (type)
+                           && type_quals == TYPE_QUAL_VOLATILE))
+               warning ("type qualifiers ignored on function return type");
+
+             type = c_build_qualified_type (type, type_quals);
+           }
          type_quals = TYPE_UNQUALIFIED;
 
          type = build_function_type (type, arg_types);
@@ -4650,8 +4748,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
      controlled separately by its own initializer.  */
 
   if (type != 0 && typedef_type != 0
-      && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type)
-      && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0)
+      && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0
+      && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))
     {
       type = build_array_type (TREE_TYPE (type), 0);
       if (size_varies)
@@ -4806,12 +4904,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
          pedwarn ("ISO C forbids qualified function types");
 
-       if (pedantic
-           && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
-           && TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl)))
-           && ! DECL_IN_SYSTEM_HEADER (decl))
-         pedwarn ("ISO C forbids qualified void function return type");
-
        /* GNU C interprets a `volatile void' return type to indicate
           that the function does not return.  */
        if ((type_quals & TYPE_QUAL_VOLATILE)
@@ -5361,6 +5453,7 @@ finish_struct (t, fieldlist, attributes)
       /* 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");
@@ -5370,6 +5463,7 @@ finish_struct (t, fieldlist, attributes)
       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))
@@ -5380,10 +5474,14 @@ finish_struct (t, fieldlist, attributes)
         field widths.  */
       if (DECL_INITIAL (x))
        {
+         int max_width;
+         if (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node)
+           max_width = CHAR_TYPE_SIZE;
+         else
+           max_width = 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),
-                                        TYPE_PRECISION (TREE_TYPE (x))))
+         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'");
@@ -5403,7 +5501,8 @@ finish_struct (t, fieldlist, attributes)
                                   "`%s' is narrower than values of its type");
 
              DECL_SIZE (x) = bitsize_int (width);
-             DECL_BIT_FIELD (x) = DECL_C_BIT_FIELD (x) = 1;
+             DECL_BIT_FIELD (x) = 1;
+             SET_DECL_C_BIT_FIELD (x);
 
              if (width == 0)
                {
@@ -5512,7 +5611,7 @@ finish_struct (t, fieldlist, attributes)
       tree decl;
       for (decl = current_binding_level->names; decl; decl = TREE_CHAIN (decl))
        {
-         if (TREE_TYPE (decl) == t
+         if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t)
              && TREE_CODE (decl) != TYPE_DECL)
            {
              layout_decl (decl, 0);
@@ -6672,6 +6771,7 @@ finish_function (nested)
         function.  For a nested function, this value is used in
         pop_c_function_context and then reset via pop_function_context.  */
       current_function_decl = NULL;
+      c_function_name_declared_p = 0;
     }
 }
 
@@ -6684,13 +6784,18 @@ c_expand_body (fndecl, nested_p)
      tree fndecl;
      int nested_p;
 {
+  /* There's no reason to do any of the work here if we're only doing
+     semantic analysis; this code just generates RTL.  */
+  if (flag_syntax_only)
+    return;
+
   /* Squirrel away our current state.  */
   if (nested_p)
     push_function_context ();
 
   /* Initialize the RTL code for the function.  */
   current_function_decl = fndecl;
-  init_function_start (fndecl, input_filename, lineno);
+  init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
 
   /* This function is being processed in whole-function mode.  */
   cfun->x_whole_function_mode_p = 1;
@@ -6702,6 +6807,10 @@ c_expand_body (fndecl, nested_p)
   immediate_size_expand = 0;
   cfun->x_dont_save_pending_sizes_p = 1;
 
+  /* If this is a varargs function, inform function.c.  */
+  if (c_function_varargs)
+    mark_varargs ();
+
   /* Set up parameters and prepare for return, for the function.  */
   expand_function_start (fndecl, 0);
 
@@ -6712,10 +6821,6 @@ c_expand_body (fndecl, nested_p)
       && DECL_CONTEXT (fndecl) == NULL_TREE)
     expand_main_function ();
 
-  /* If this is a varargs function, inform function.c.  */
-  if (c_function_varargs)
-    mark_varargs ();
-
   /* Generate the RTL for this function.  */
   expand_stmt (DECL_SAVED_TREE (fndecl));
   /* Allow the body of the function to be garbage collected.  */
@@ -6734,9 +6839,6 @@ c_expand_body (fndecl, nested_p)
   /* Generate rtl for function exit.  */
   expand_function_end (input_filename, lineno, 0);
 
-  /* So we can tell if jump_optimize sets it to 1.  */
-  can_reach_end = 0;
-
   /* If this is a nested function, protect the local variables in the stack
      above us from being collected while we're compiling this function.  */
   if (nested_p)
@@ -6749,25 +6851,11 @@ c_expand_body (fndecl, nested_p)
   if (nested_p)
     ggc_pop_context ();
 
-  current_function_returns_null |= can_reach_end;
-
-  if (warn_missing_noreturn
-      && !TREE_THIS_VOLATILE (fndecl)
-      && !current_function_returns_null
-      && !current_function_returns_value)
-    warning ("function might be possible candidate for attribute `noreturn'");
-
-  if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null)
-    warning ("`noreturn' function does return");
-  else if (warn_return_type && can_reach_end
-          && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))))
-    /* If this function returns non-void and control can drop through,
-       complain.  */
-    warning ("control reaches end of non-void function");
   /* With just -W, complain only if function returns both with
      and without a value.  */
-  else if (extra_warnings
-          && current_function_returns_value && current_function_returns_null)
+  if (extra_warnings
+      && current_function_returns_value
+      && current_function_returns_null)
     warning ("this function may return with or without a value");
 
   /* If requested, warn about function definitions where the function will
@@ -6845,6 +6933,55 @@ c_expand_body (fndecl, nested_p)
       
 }
 \f
+/* Check the declarations given in a for-loop for satisfying the C99
+   constraints.  */
+void
+check_for_loop_decls ()
+{
+  tree t;
+
+  if (!flag_isoc99)
+    {
+      /* If we get here, declarations have been used in a for loop without
+        the C99 for loop scope.  This doesn't make much sense, so don't
+        allow it.  */
+      error ("`for' loop initial declaration used outside C99 mode");
+      return;
+    }
+  /* C99 subclause 6.8.5 paragraph 3:
+
+       [#3]  The  declaration  part  of  a for statement shall only
+       declare identifiers for objects having storage class auto or
+       register.
+
+     It isn't clear whether, in this sentence, "identifiers" binds to
+     "shall only declare" or to "objects" - that is, whether all identifiers
+     declared must be identifiers for objects, or whether the restriction
+     only applies to those that are.  (A question on this in comp.std.c
+     in November 2000 received no answer.)  We implement the strictest
+     interpretation, to avoid creating an extension which later causes
+     problems.  */
+
+  for (t = gettags (); t; t = TREE_CHAIN (t))
+    {
+      if (TREE_PURPOSE (t) != 0)
+       error ("`%s %s' declared in `for' loop initial declaration",
+              (TREE_CODE (TREE_VALUE (t)) == RECORD_TYPE ? "struct"
+               : TREE_CODE (TREE_VALUE (t)) == UNION_TYPE ? "union"
+               : "enum"),
+              IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+    }
+  for (t = getdecls (); t; t = TREE_CHAIN (t))
+    {
+      if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
+       error_with_decl (t, "declaration of non-variable `%s' in `for' loop initial declaration");
+      else if (TREE_STATIC (t))
+       error_with_decl (t, "declaration of static variable `%s' in `for' loop initial declaration");
+      else if (DECL_EXTERNAL (t))
+       error_with_decl (t, "declaration of `extern' variable `%s' in `for' loop initial declaration");
+    }
+}
+\f
 /* Save and restore the variables in this file and elsewhere
    that keep track of the progress of compilation of the current function.
    Used for nested functions.  */
@@ -6956,22 +7093,11 @@ copy_lang_decl (decl)
     return;
 
   ld = (struct lang_decl *) ggc_alloc (sizeof (struct lang_decl));
-  bcopy ((char *)DECL_LANG_SPECIFIC (decl), (char *)ld, 
-        sizeof (struct lang_decl));
+  memcpy ((char *) ld, (char *) DECL_LANG_SPECIFIC (decl),
+         sizeof (struct lang_decl));
   DECL_LANG_SPECIFIC (decl) = ld;
 }
 
-/* Mark ARG for GC.  */
-
-void
-lang_mark_false_label_stack (arg)
-     struct label_node *arg;
-{
-  /* C doesn't use false_label_stack.  It better be NULL.  */
-  if (arg != NULL)
-    abort ();
-}
-
 /* Mark the language specific bits in T for GC.  */
 
 void