OSDN Git Service

H
[pf3gnuchains/gcc-fork.git] / gcc / c-decl.c
index 0c6e1c3..91e3510 100644 (file)
@@ -1,5 +1,5 @@
 /* Process declarations and variables for C compiler.
-   Copyright (C) 1988, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -27,12 +27,20 @@ Boston, MA 02111-1307, USA.  */
    line numbers.  For example, the CONST_DECLs for enum values.  */
 
 #include "config.h"
+#include "system.h"
 #include "tree.h"
 #include "flags.h"
 #include "output.h"
 #include "c-tree.h"
 #include "c-lex.h"
-#include <stdio.h>
+#include "toplev.h"
+
+#if USE_CPPLIB
+#include "cpplib.h"
+extern cpp_reader  parse_in;
+extern cpp_options parse_options;
+static int cpp_initialized;
+#endif
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -143,11 +151,17 @@ tree intQI_type_node;
 tree intHI_type_node;
 tree intSI_type_node;
 tree intDI_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
+tree intTI_type_node;
+#endif
 
 tree unsigned_intQI_type_node;
 tree unsigned_intHI_type_node;
 tree unsigned_intSI_type_node;
 tree unsigned_intDI_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
+tree unsigned_intTI_type_node;
+#endif
 
 /* a VOID_TYPE node.  */
 
@@ -454,6 +468,10 @@ int flag_no_nonansi_builtin;
 
 int flag_traditional;
 
+/* Nonzero means use the ISO C9x dialect of C.  */
+
+int flag_isoc9x = 0;
+
 /* Nonzero means that we have builtin functions, and main is an int */
 
 int flag_hosted = 1;
@@ -471,15 +489,24 @@ int explicit_flag_signed_bitfields = 0;
 
 int flag_no_ident = 0;
 
-/* Nonzero means warn about implicit declarations.  */
+/* Nonzero means warn about use of implicit int. */
 
-int warn_implicit;
+int warn_implicit_int;
+
+/* Nonzero means warn about usage of long long when `-pedantic'.  */
+
+int warn_long_long = 1;
+
+/* Nonzero means message about use of implicit function declarations;
+ 1 means warning; 2 means error. */
+
+int mesg_implicit_function_declaration;
 
 /* Nonzero means give string constants the type `const char *'
    to get extra warnings from them.  These warnings will be too numerous
    to be useful, except in thoroughly ANSIfied programs.  */
 
-int warn_write_strings;
+int flag_const_strings;
 
 /* Nonzero means warn about pointer casts that can drop a type qualifier
    from the pointer target type.  */
@@ -492,6 +519,10 @@ int warn_cast_qual;
 
 int warn_bad_function_cast;
 
+/* Warn about functions which might be candidates for attribute noreturn. */
+
+int warn_missing_noreturn;
+
 /* Warn about traditional constructs whose meanings changed in ANSI C.  */
 
 int warn_traditional;
@@ -553,9 +584,18 @@ int warn_missing_braces;
 
 int warn_main;
 
-/* Warn about comparison of signed and unsigned values.  */
+/* Warn about #pragma directives that are not recognised.  */
 
-int warn_sign_compare;
+int warn_unknown_pragmas = 0; /* Tri state variable.  */  
+
+/* Warn about comparison of signed and unsigned values.
+   If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified.  */
+
+int warn_sign_compare = -1;
+
+/* Nonzero means warn about use of multicharacter literals.  */
+
+int warn_multichar = 1;
 
 /* Nonzero means `$' can be in an identifier.  */
 
@@ -565,13 +605,28 @@ int warn_sign_compare;
 int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
 
 /* Decode the string P as a language-specific option for C.
-   Return 1 if it is recognized (and handle it);
-   return 0 if not recognized.  */
+   Return the number of strings consumed.  */
    
 int
-c_decode_option (p)
-     char *p;
+c_decode_option (argc, argv)
+     int argc ATTRIBUTE_UNUSED;
+     char **argv;
 {
+  int strings_processed;
+  char *p = argv[0];
+#if USE_CPPLIB
+  if (! cpp_initialized)
+    {
+      cpp_reader_init (&parse_in);
+      parse_in.data = &parse_options;
+      cpp_options_init (&parse_options);
+      cpp_initialized = 1;
+    }
+  strings_processed = cpp_handle_option (&parse_in, argc, argv);
+#else
+  strings_processed = 0;
+#endif /* ! USE_CPPLIB */
+
   if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
     {
       flag_traditional = 1;
@@ -597,6 +652,8 @@ c_decode_option (p)
       flag_traditional = 0;
       flag_writable_strings = 0;
     }
+  else if (!strcmp (p, "-flang-isoc9x"))
+    flag_isoc9x = 1;
   else if (!strcmp (p, "-fdollars-in-identifiers"))
     dollars_in_ident = 1;
   else if (!strcmp (p, "-fno-dollars-in-identifiers"))
@@ -647,14 +704,32 @@ c_decode_option (p)
     flag_no_ident = 0;
   else if (!strcmp (p, "-ansi"))
     flag_no_asm = 1, flag_no_nonansi_builtin = 1;
+  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 (!strcmp (p, "-Wimplicit"))
-    warn_implicit = 1;
+    {
+      warn_implicit_int = 1;
+      if (mesg_implicit_function_declaration != 2)
+        mesg_implicit_function_declaration = 1;
+    }
   else if (!strcmp (p, "-Wno-implicit"))
-    warn_implicit = 0;
+    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"))
-    warn_write_strings = 1;
+    flag_const_strings = 1;
   else if (!strcmp (p, "-Wno-write-strings"))
-    warn_write_strings = 0;
+    flag_const_strings = 0;
   else if (!strcmp (p, "-Wcast-qual"))
     warn_cast_qual = 1;
   else if (!strcmp (p, "-Wno-cast-qual"))
@@ -663,6 +738,10 @@ c_decode_option (p)
     warn_bad_function_cast = 1;
   else if (!strcmp (p, "-Wno-bad-function-cast"))
     warn_bad_function_cast = 0;
+  else if (!strcmp (p, "-Wmissing-noreturn"))
+    warn_missing_noreturn = 1;
+  else if (!strcmp (p, "-Wno-missing-noreturn"))
+    warn_missing_noreturn = 0;
   else if (!strcmp (p, "-Wpointer-arith"))
     warn_pointer_arith = 1;
   else if (!strcmp (p, "-Wno-pointer-arith"))
@@ -723,6 +802,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"))
@@ -739,6 +822,16 @@ c_decode_option (p)
     warn_sign_compare = 1;
   else if (!strcmp (p, "-Wno-sign-compare"))
     warn_sign_compare = 0;
+  else if (!strcmp (p, "-Wmultichar"))
+    warn_multichar = 1;
+  else if (!strcmp (p, "-Wno-multichar"))
+    warn_multichar = 0;
+  else if (!strcmp (p, "-Wunknown-pragmas"))
+    /* Set to greater than 1, so that even unknown pragmas in system
+       headers will be warned about.  */
+    warn_unknown_pragmas = 2;
+  else if (!strcmp (p, "-Wno-unknown-pragmas"))
+    warn_unknown_pragmas = 0;
   else if (!strcmp (p, "-Wall"))
     {
       /* We save the value of warn_uninitialized, since if they put
@@ -746,7 +839,8 @@ c_decode_option (p)
         warning about not using it without also specifying -O.  */
       if (warn_uninitialized != 1)
        warn_uninitialized = 2;
-      warn_implicit = 1;
+      warn_implicit_int = 1;
+      mesg_implicit_function_declaration = 1;
       warn_return_type = 1;
       warn_unused = 1;
       warn_switch = 1;
@@ -754,13 +848,14 @@ 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;
+      /* Only warn about unknown pragmas that are not in system headers.  */
+      warn_unknown_pragmas = 1;
     }
   else
-    return 0;
+    return strings_processed;
 
   return 1;
 }
@@ -769,17 +864,17 @@ c_decode_option (p)
 
 void
 print_lang_decl (file, node, indent)
-     FILE *file;
-     tree node;
-     int indent;
+     FILE *file ATTRIBUTE_UNUSED;
+     tree node ATTRIBUTE_UNUSED;
+     int indent ATTRIBUTE_UNUSED;
 {
 }
 
 void
 print_lang_type (file, node, indent)
-     FILE *file;
-     tree node;
-     int indent;
+     FILE *file ATTRIBUTE_UNUSED;
+     tree node ATTRIBUTE_UNUSED;
+     int indent ATTRIBUTE_UNUSED;
 {
 }
 
@@ -865,7 +960,7 @@ kept_level_p ()
 
 void
 declare_parm_level (definition_flag)
-     int definition_flag;
+     int definition_flag ATTRIBUTE_UNUSED;
 {
   current_binding_level->parm_flag = 1;
 }
@@ -1382,7 +1477,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
   char *errmsg = 0;
 
   if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd')
-    DECL_MACHINE_ATTRIBUTES (newdecl) = DECL_MACHINE_ATTRIBUTES (olddecl);
+    DECL_MACHINE_ATTRIBUTES (newdecl)
+      =  merge_machine_decl_attributes (olddecl, newdecl);
 
   if (TREE_CODE (newtype) == ERROR_MARK
       || TREE_CODE (oldtype) == ERROR_MARK)
@@ -1734,7 +1830,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
 
   /* Optionally warn about more than one declaration for the same name.  */
   if (errmsg == 0 && warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0
-      /* Dont warn about a function declaration
+      /* Don't warn about a function declaration
         followed by a definition.  */
       && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0
           && DECL_INITIAL (olddecl) == 0)
@@ -1853,6 +1949,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
        {
          DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
          DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
+
+         DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
+           |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
+         DECL_NO_CHECK_MEMORY_USAGE (newdecl)
+           |= DECL_NO_CHECK_MEMORY_USAGE (olddecl);
        }
 
       pop_obstacks ();
@@ -1938,17 +2039,27 @@ 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) = DECL_ORIGIN (olddecl);
        }
     }
   if (different_binding_level)
     {
-      /* Don't output a duplicate symbol for this declaration.  */
-      TREE_ASM_WRITTEN (newdecl) = 1;
+      /* Don't output a duplicate symbol or debugging information for this
+        declaration.
+
+        Do not set TREE_ASM_WRITTEN for a FUNCTION_DECL since we may actually
+        just have two declarations without a definition.  VAR_DECLs may need
+        the same treatment, I'm not sure.  */
+      if (TREE_CODE (newdecl) == FUNCTION_DECL)
+       DECL_IGNORED_P (newdecl) = 1;
+      else
+       TREE_ASM_WRITTEN (newdecl) = DECL_IGNORED_P (newdecl) = 1;
       return 0;
     }
 
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
-     But preserve OLDdECL's DECL_UID.  */
+     But preserve OLDDECL's DECL_UID.  */
   {
     register unsigned olddecl_uid = DECL_UID (olddecl);
 
@@ -1958,6 +2069,10 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
     DECL_UID (olddecl) = olddecl_uid;
   }
 
+  /* NEWDECL contains the merged attribute lists.
+     Update OLDDECL to be the same.  */
+  DECL_MACHINE_ATTRIBUTES (olddecl) = DECL_MACHINE_ATTRIBUTES (newdecl);
+
   return 1;
 }
 
@@ -2042,6 +2157,7 @@ pushdecl (x)
             DECL_SOURCE_LINE (IDENTIFIER_IMPLICIT_DECL (name)),
             "previous declaration of `%s'",
             IDENTIFIER_POINTER (name));
+         TREE_THIS_VOLATILE (name) = 1;
        }
 
       if (t != 0 && duplicate_decls (x, t, different_binding_level))
@@ -2075,7 +2191,7 @@ pushdecl (x)
                MY_TYPE object;
 
         Later parts of the compiler might only know that `object' was of
-        type `struct S' if if were not for code just below.  With this
+        type `struct S' if it were not for code just below.  With this
         code however, later parts of the compiler see something like:
 
                struct S' == struct S
@@ -2106,7 +2222,8 @@ pushdecl (x)
              if (TYPE_NAME (TREE_TYPE (x)) == 0)
                TYPE_NAME (TREE_TYPE (x)) = x;
             }
-          else if (TREE_TYPE (x) != error_mark_node)
+          else if (TREE_TYPE (x) != error_mark_node
+                  && DECL_ORIGINAL_TYPE (x) == NULL_TREE)
             {
               tree tt = TREE_TYPE (x);
              DECL_ORIGINAL_TYPE (x) = tt;
@@ -2244,8 +2361,11 @@ pushdecl (x)
              else if (TREE_CODE (x) == TYPE_DECL)
                ;
              else if (IDENTIFIER_IMPLICIT_DECL (name))
-               pedwarn ("`%s' was declared implicitly `extern' and later `static'",
-                        IDENTIFIER_POINTER (name));
+               {
+                 if (! TREE_THIS_VOLATILE (name))
+                   pedwarn ("`%s' was declared implicitly `extern' and later `static'",
+                            IDENTIFIER_POINTER (name));
+               }
              else
                pedwarn ("`%s' was declared `extern' and later `static'",
                         IDENTIFIER_POINTER (name));
@@ -2284,7 +2404,7 @@ pushdecl (x)
                      DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal);
                      DECL_RESULT (x) = DECL_RESULT (oldglobal);
                      TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal);
-                     DECL_ABSTRACT_ORIGIN (x) = oldglobal;
+                     DECL_ABSTRACT_ORIGIN (x) = DECL_ORIGIN (oldglobal);
                    }
                  /* Inner extern decl is built-in if global one is.  */
                  if (DECL_BUILT_IN (oldglobal))
@@ -2447,7 +2567,6 @@ implicitly_declare (functionid)
 
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 1;
-  DECL_ARTIFICIAL (decl);
 
   /* Record that we have an implicit decl and this is it.  */
   IDENTIFIER_IMPLICIT_DECL (functionid) = decl;
@@ -2462,9 +2581,15 @@ implicitly_declare (functionid)
 
   rest_of_decl_compilation (decl, NULL_PTR, 0, 0);
 
-  if (warn_implicit && implicit_warning)
-    warning ("implicit declaration of function `%s'",
-            IDENTIFIER_POINTER (functionid));
+  if (mesg_implicit_function_declaration && implicit_warning)
+    {
+      if (mesg_implicit_function_declaration == 2)
+        error ("implicit declaration of function `%s'",
+                 IDENTIFIER_POINTER (functionid));
+      else
+        warning ("implicit declaration of function `%s'",
+                 IDENTIFIER_POINTER (functionid));
+    }
   else if (warn_traditional && traditional_warning)
     warning ("function `%s' was previously declared within a block",
             IDENTIFIER_POINTER (functionid));
@@ -2844,7 +2969,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;
@@ -2903,25 +3028,15 @@ init_decl_processing ()
   /* `unsigned long' is the standard type for sizeof.
      Traditionally, use a signed type.
      Note that stddef.h uses `unsigned long',
-     and this must agree, even of long and int are the same size.  */
-  sizetype
-    = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
+     and this must agree, even if long and int are the same size.  */
+  set_sizetype
+    (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
   if (flag_traditional && TREE_UNSIGNED (sizetype))
-    sizetype = signed_type (sizetype);
+    set_sizetype (signed_type (sizetype));
 
   ptrdiff_type_node
     = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
 
-  TREE_TYPE (TYPE_SIZE (integer_type_node)) = sizetype;
-  TREE_TYPE (TYPE_SIZE (char_type_node)) = sizetype;
-  TREE_TYPE (TYPE_SIZE (unsigned_type_node)) = sizetype;
-  TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = sizetype;
-  TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype;
-  TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = sizetype;
-  TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = sizetype;
-  TREE_TYPE (TYPE_SIZE (short_integer_type_node)) = sizetype;
-  TREE_TYPE (TYPE_SIZE (short_unsigned_type_node)) = sizetype;
-
   error_mark_node = make_node (ERROR_MARK);
   TREE_TYPE (error_mark_node) = error_mark_node;
 
@@ -2946,6 +3061,11 @@ init_decl_processing ()
   intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
 
+#if HOST_BITS_PER_WIDE_INT >= 64
+  intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
+  pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node));
+#endif
+
   unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
 
@@ -2958,6 +3078,11 @@ init_decl_processing ()
   unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
   pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
 
+#if HOST_BITS_PER_WIDE_INT >= 64
+  unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
+  pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node));
+#endif
+
   float_type_node = make_node (REAL_TYPE);
   TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
   pushdecl (build_decl (TYPE_DECL, ridpointers[(int) RID_FLOAT],
@@ -3160,6 +3285,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);
 
@@ -3177,6 +3307,36 @@ 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_dwarf_cfa", ptr_ftype_void,
+                   BUILT_IN_DWARF_CFA, 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_eh_return",
+     build_function_type (void_type_node,
+                         tree_cons (NULL_TREE, ptr_type_node,
+                                    tree_cons (NULL_TREE,
+                                               type_for_mode (ptr_mode, 0),
+                                               tree_cons (NULL_TREE,
+                                                          ptr_type_node,
+                                                          endlink)))),
+     BUILT_IN_EH_RETURN, NULL_PTR);
+
   builtin_function ("__builtin_alloca",
                    build_function_type (ptr_type_node,
                                         tree_cons (NULL_TREE,
@@ -3269,7 +3429,7 @@ init_decl_processing ()
   builtin_function ("__builtin_memcmp", int_ftype_cptr_cptr_sizet,
                    BUILT_IN_MEMCMP, "memcmp");
   builtin_function ("__builtin_memset", memset_ftype,
-                   BUILT_IN_MEMSET, NULL_PTR);
+                   BUILT_IN_MEMSET, "memset");
   builtin_function ("__builtin_strcmp", int_ftype_string_string,
                    BUILT_IN_STRCMP, "strcmp");
   builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr,
@@ -3307,6 +3467,9 @@ init_decl_processing ()
                                           integer_type_node,
                                           endlink))),
                    BUILT_IN_LONGJMP, NULL_PTR);
+  builtin_function ("__builtin_trap",
+                   build_function_type (void_type_node, endlink),
+                   BUILT_IN_TRAP, NULL_PTR);
 
   /* In an ANSI C program, it is okay to supply built-in meanings
      for these functions, since applications cannot validly use them
@@ -3366,8 +3529,6 @@ init_decl_processing ()
                    BUILT_IN_FMOD, NULL_PTR);
   builtin_function ("__builtin_frem", double_ftype_double_double,
                    BUILT_IN_FREM, NULL_PTR);
-  builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int,
-                   BUILT_IN_MEMSET, NULL_PTR);
   builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP,
                    NULL_PTR);
   builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN,
@@ -3387,6 +3548,8 @@ init_decl_processing ()
   init_iterators ();
 
   incomplete_decl_finalize_hook = finish_incomplete_decl;
+
+  lang_get_alias_set = c_get_alias_set;
 }
 
 /* Return a definition for a builtin function named NAME and whose data type
@@ -3453,10 +3616,15 @@ shadow_tag_warned (declspecs, warned)
 {
   int found_tag = 0;
   register tree link;
+  tree specs, attrs;
 
   pending_invalid_xref = 0;
 
-  for (link = declspecs; link; link = TREE_CHAIN (link))
+  /* Remove the attributes from declspecs, since they will confuse the
+     following code.  */
+  split_specs_attrs (declspecs, &specs, &attrs);
+
+  for (link = specs; link; link = TREE_CHAIN (link))
     {
       register tree value = TREE_VALUE (link);
       register enum tree_code code = TREE_CODE (value);
@@ -3569,7 +3737,8 @@ 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"))
+  if (warn_main && TREE_CODE (decl) != FUNCTION_DECL 
+      && !strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "main"))
     warning_with_decl (decl, "`%s' is usually a function");
 
   if (initialized)
@@ -3664,6 +3833,10 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
   if (! flag_no_common || ! TREE_PUBLIC (decl))
     DECL_COMMON (decl) = 1;
 
+#ifdef SET_DEFAULT_DECL_ATTRIBUTES
+  SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes);
+#endif
+
   /* Set attributes here so if duplicate decl, will have proper attributes.  */
   decl_attributes (decl, attributes, prefix_attributes);
 
@@ -3816,7 +3989,7 @@ finish_decl (decl, init, asmspec_tree)
                 declaration into a file scope one.  This can be detected
                 by TREE_ASM_WRITTEN being set.  */
                (DECL_INITIAL (decl) != 0
-                || DECL_CONTEXT (decl) != 0 && ! TREE_ASM_WRITTEN (decl))
+                || (DECL_CONTEXT (decl) != 0 && ! TREE_ASM_WRITTEN (decl)))
              :
                /* An automatic variable with an incomplete type
                   is an error.  */
@@ -3834,6 +4007,9 @@ finish_decl (decl, init, asmspec_tree)
          else
            error_with_decl (decl, "storage size of `%s' isn't constant");
        }
+
+      if (TREE_USED  (type))
+       TREE_USED (decl) = 1;
     }
 
   /* If this is a function and an assembler name is specified, it isn't
@@ -3983,7 +4159,7 @@ finish_decl (decl, init, asmspec_tree)
 
 tree
 maybe_build_cleanup (decl)
-     tree decl;
+     tree decl ATTRIBUTE_UNUSED;
 {
   /* There are no cleanups in C.  */
   return NULL_TREE;
@@ -4102,12 +4278,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.  */
@@ -4158,7 +4328,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
   tree type = NULL_TREE;
   int longlong = 0;
   int constp;
+  int restrictp;
   int volatilep;
+  int type_quals = TYPE_UNQUALIFIED;
   int inlinep;
   int explicit_int = 0;
   int explicit_char = 0;
@@ -4263,7 +4435,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                      error ("`long long long' is too long for GCC");
                    else
                      {
-                       if (pedantic && ! in_system_header)
+                       if (pedantic && ! in_system_header && warn_long_long)
                          pedwarn ("ANSI C does not support `long long'");
                        longlong = 1;
                      }
@@ -4313,17 +4485,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
   if (type == 0)
     {
-      if (! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
-                        | (1 << (int) RID_SIGNED)
-                        | (1 << (int) RID_UNSIGNED))))
+      if ((! (specbits & ((1 << (int) RID_LONG) | (1 << (int) RID_SHORT)
+                         | (1 << (int) RID_SIGNED)
+                         | (1 << (int) RID_UNSIGNED))))
+         /* Don't warn about typedef foo = bar.  */
+         && ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
+         && ! (in_system_header && ! allocation_temporary_p ()))
        {
          /* 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)
+         if ((warn_implicit_int || warn_return_type) && funcdef_flag)
            warn_about_return_type = 1;
-         else if (warn_implicit)
+         else if (warn_implicit_int)
            warning ("type defaults to `int' in declaration of `%s'", name);
        }
 
@@ -4336,7 +4511,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);
@@ -4350,11 +4525,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)
@@ -4362,10 +4535,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;
@@ -4456,19 +4640,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        type = build_complex_type (type);
     }
 
-  /* Set CONSTP if this declaration is `const', whether by
-     explicit specification or via a typedef.
-     Likewise for VOLATILEP.  */
-
+  /* 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
+     something like `typedef const int CI; CI i' where the type of the
+     declaration contains the `const'.  */
   constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type);
+  restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
   volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
   inlinep = !! (specbits & (1 << (int) RID_INLINE));
   if (constp > 1)
     pedwarn ("duplicate `const'");
+  if (restrictp > 1)
+    pedwarn ("duplicate `restrict'");
   if (volatilep > 1)
     pedwarn ("duplicate `volatile'");
-  if (! flag_gen_aux_info && (TYPE_READONLY (type) || TYPE_VOLATILE (type)))
+  if (! flag_gen_aux_info && (TYPE_QUALS (type)))
     type = TYPE_MAIN_VARIANT (type);
+  type_quals = ((constp ? TYPE_QUAL_CONST : 0)
+               | (restrictp ? TYPE_QUAL_RESTRICT : 0)
+               | (volatilep ? TYPE_QUAL_VOLATILE : 0));
 
   /* Warn if two storage classes are given. Default to `auto'.  */
 
@@ -4660,6 +4851,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                                   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);
@@ -4690,13 +4893,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
             is set correctly.  */
 
          type = build_array_type (type, itype);
-         if (constp || volatilep)
-           type = c_build_type_variant (type, constp, volatilep);
+         if (type_quals)
+           type = c_build_qualified_type (type, type_quals);
 
 #if 0  /* don't clear these; leave them set so that the array type
           or the variable is itself const or volatile.  */
-         constp = 0;
-         volatilep = 0;
+         type_quals = TYPE_UNQUALIFIED;
 #endif
 
          if (size_varies)
@@ -4761,12 +4963,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                                      flag_traditional 
                                      ? NULL_TREE : arg_types);
 #endif
-         /* ANSI seems to say that `const int foo ();'
-            does not make the function foo const.  */
-         if (constp || volatilep)
-           type = c_build_type_variant (type, constp, volatilep);
-         constp = 0;
-         volatilep = 0;
+         /* 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_quals = TYPE_UNQUALIFIED;
 
          type = build_function_type (type, arg_types);
          declarator = TREE_OPERAND (declarator, 0);
@@ -4778,7 +4979,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          {
            register tree link;
 
-           for (link = current_function_parm_tags;
+           for (link = last_function_parm_tags;
                 link;
                 link = TREE_CHAIN (link))
              TYPE_CONTEXT (TREE_VALUE (link)) = type;
@@ -4790,12 +4991,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
             for the pointer.  */
 
          if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
-             && (constp || volatilep))
-           pedwarn ("ANSI C forbids const or volatile function types");
-         if (constp || volatilep)
-           type = c_build_type_variant (type, constp, volatilep);
-         constp = 0;
-         volatilep = 0;
+             && type_quals)
+           pedwarn ("ANSI C forbids qualified function types");
+         if (type_quals)
+           type = c_build_qualified_type (type, type_quals);
+         type_quals = TYPE_UNQUALIFIED;
          size_varies = 0;
 
          type = build_pointer_type (type);
@@ -4807,13 +5007,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
            {
              register tree typemodlist;
              int erred = 0;
+
+             constp = 0;
+             volatilep = 0;
+             restrictp = 0;
              for (typemodlist = TREE_TYPE (declarator); typemodlist;
                   typemodlist = TREE_CHAIN (typemodlist))
                {
-                 if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST])
+                 tree qualifier = TREE_VALUE (typemodlist);
+
+                 if (qualifier == ridpointers[(int) RID_CONST])
                    constp++;
-                 else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE])
+                 else if (qualifier == ridpointers[(int) RID_VOLATILE])
                    volatilep++;
+                 else if (qualifier == ridpointers[(int) RID_RESTRICT])
+                   restrictp++;
                  else if (!erred)
                    {
                      erred = 1;
@@ -4824,6 +5032,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                pedwarn ("duplicate `const'");
              if (volatilep > 1)
                pedwarn ("duplicate `volatile'");
+             if (restrictp > 1)
+               pedwarn ("duplicate `restrict'");
+
+             type_quals = ((constp ? TYPE_QUAL_CONST : 0)
+                           | (restrictp ? TYPE_QUAL_RESTRICT : 0)
+                           | (volatilep ? TYPE_QUAL_VOLATILE : 0));
            }
 
          declarator = TREE_OPERAND (declarator, 0);
@@ -4835,6 +5049,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
   /* Now TYPE has the actual type.  */
 
+  /* Did array size calculations overflow?  */
+
+  if (TREE_CODE (type) == ARRAY_TYPE
+      && TYPE_SIZE (type)
+      && TREE_OVERFLOW (TYPE_SIZE (type)))
+    error ("size of array `%s' is too large", name);
+
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
 
   if (specbits & (1 << (int) RID_TYPEDEF))
@@ -4843,10 +5064,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       /* Note that the grammar rejects storage classes
         in typenames, fields or parameters */
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
-         && (constp || volatilep))
-       pedwarn ("ANSI C forbids const or volatile function types");
-      if (constp || volatilep)
-       type = c_build_type_variant (type, constp, volatilep);
+         && type_quals)
+       pedwarn ("ANSI C forbids qualified function types");
+      if (type_quals)
+       type = c_build_qualified_type (type, type_quals);
       decl = build_decl (TYPE_DECL, declarator, type);
       if ((specbits & (1 << (int) RID_SIGNED))
          || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
@@ -4878,10 +5099,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       /* Note that the grammar rejects storage classes
         in typenames, fields or parameters */
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
-         && (constp || volatilep))
+         && type_quals)
        pedwarn ("ANSI C forbids const or volatile function types");
-      if (constp || volatilep)
-       type = c_build_type_variant (type, constp, volatilep);
+      if (type_quals)
+       type = c_build_qualified_type (type, type_quals);
       pop_obstacks ();
       return type;
     }
@@ -4921,20 +5142,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
          {
            /* Transfer const-ness of array into that of type pointed to.  */
            type = TREE_TYPE (type);
-           if (constp || volatilep)
-             type = c_build_type_variant (type, constp, volatilep);
+           if (type_quals)
+             type = c_build_qualified_type (type, type_quals);
            type = build_pointer_type (type);
-           volatilep = constp = 0;
+           type_quals = TYPE_UNQUALIFIED;
            size_varies = 0;
          }
        else if (TREE_CODE (type) == FUNCTION_TYPE)
          {
-           if (pedantic && (constp || volatilep))
-             pedwarn ("ANSI C forbids const or volatile function types");
-           if (constp || volatilep)
-             type = c_build_type_variant (type, constp, volatilep);
+           if (pedantic && type_quals)
+             pedwarn ("ANSI C forbids qualified function types");
+           if (type_quals)
+             type = c_build_qualified_type (type, type_quals);
            type = build_pointer_type (type);
-           volatilep = constp = 0;
+           type_quals = TYPE_UNQUALIFIED;
          }
 
        decl = build_decl (PARM_DECL, declarator, type);
@@ -4982,13 +5203,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
            type = error_mark_node;
          }
        /* Move type qualifiers down to element of an array.  */
-       if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep))
+       if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
          {
-           type = build_array_type (c_build_type_variant (TREE_TYPE (type),
-                                                          constp, volatilep),
+           type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
+                                                            type_quals),
                                     TYPE_DOMAIN (type));
 #if 0 /* Leave the field const or volatile as well.  */
-           constp = volatilep = 0;
+           type_quals = TYPE_UNQUALIFIED;
 #endif
          }
        decl = build_decl (FIELD_DECL, declarator, type);
@@ -5027,11 +5248,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        decl = build_decl (FUNCTION_DECL, declarator, type);
        decl = build_decl_attribute_variant (decl, decl_machine_attr);
 
-       if (pedantic && (constp || volatilep)
+       if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
+         pedwarn ("ANSI C forbids qualified function types");
+
+       if (pedantic
+           && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node
+           && TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl)))
            && ! DECL_IN_SYSTEM_HEADER (decl))
-         pedwarn ("ANSI C forbids const or volatile functions");
+         pedwarn ("ANSI C forbids qualified void function return type");
 
-       if (volatilep
+       /* GNU C interprets a `volatile void' return type to indicate
+          that the function does not return.  */
+       if ((type_quals & TYPE_QUAL_VOLATILE)
            && TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
          warning ("`noreturn' function returns non-void value");
 
@@ -5044,13 +5272,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        /* Record presence of `inline', if it is reasonable.  */
        if (inlinep)
          {
-           tree last = tree_last (TYPE_ARG_TYPES (type));
-
            if (! strcmp (IDENTIFIER_POINTER (declarator), "main"))
              warning ("cannot inline function `main'");
-           else if (last && (TYPE_MAIN_VARIANT (TREE_VALUE (last))
-                             != void_type_node))
-             warning ("inline declaration ignored for function with `...'");
            else
              /* Assume that otherwise the function can be inlined.  */
              DECL_INLINE (decl) = 1;
@@ -5066,13 +5289,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
        int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN));
 
        /* Move type qualifiers down to element of an array.  */
-       if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep))
+       if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
          {
-           type = build_array_type (c_build_type_variant (TREE_TYPE (type),
-                                                          constp, volatilep),
+           type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
+                                                            type_quals),
                                     TYPE_DOMAIN (type));
 #if 0 /* Leave the variable const or volatile as well.  */
-           constp = volatilep = 0;
+           type_quals = TYPE_UNQUALIFIED;
 #endif
          }
 
@@ -5119,14 +5342,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
       DECL_REGISTER (decl) = 1;
 
     /* Record constancy and volatility.  */
+    c_apply_type_quals_to_decl (type_quals, decl);
 
-    if (constp)
-      TREE_READONLY (decl) = 1;
-    if (volatilep)
-      {
-       TREE_SIDE_EFFECTS (decl) = 1;
-       TREE_THIS_VOLATILE (decl) = 1;
-      }
     /* If a type has volatile components, it should be stored in memory.
        Otherwise, the fact that those components are volatile
        will be ignored, and would even crash the compiler.  */
@@ -5370,7 +5587,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",
@@ -5473,6 +5690,7 @@ start_struct (code, name)
   if (ref && TREE_CODE (ref) == code)
     {
       C_TYPE_BEING_DEFINED (ref) = 1;
+      TYPE_PACKED (ref) = flag_pack_struct;
       if (TYPE_FIELDS (ref))
        error ((code == UNION_TYPE ? "redefinition of `union %s'"
                : "redefinition of `struct %s'"),
@@ -5714,7 +5932,7 @@ finish_struct (t, fieldlist, attributes)
        }
       else if (TREE_TYPE (x) != error_mark_node)
        {
-         int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
+         unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
                           : TYPE_ALIGN (TREE_TYPE (x)));
          /* Non-bit-fields are aligned for their type, except packed
             fields which require only BITS_PER_UNIT alignment.  */
@@ -6031,6 +6249,7 @@ finish_enum (enumtype, values, attributes)
       TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype);
       TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype);
       TYPE_SIZE (tem) = TYPE_SIZE (enumtype);
+      TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype);
       TYPE_MODE (tem) = TYPE_MODE (enumtype);
       TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
       TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
@@ -6154,7 +6373,10 @@ start_function (declspecs, declarator, prefix_attributes, attributes, nested)
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
   if (decl1 == 0)
-    return 0;
+    {
+      immediate_size_expand = old_immediate_size_expand;
+      return 0;
+    }
 
   decl_attributes (decl1, prefix_attributes, attributes);
 
@@ -6239,6 +6461,10 @@ start_function (declspecs, declarator, prefix_attributes, attributes, nested)
      except for defining how to inline.  So set DECL_EXTERNAL in that case.  */
   DECL_EXTERNAL (decl1) = current_extern_inline;
 
+#ifdef SET_DEFAULT_DECL_ATTRIBUTES
+  SET_DEFAULT_DECL_ATTRIBUTES (decl1, attributes);
+#endif
+  
   /* This function exists in static storage.
      (This does not mean `static' in the C sense!)  */
   TREE_STATIC (decl1) = 1;
@@ -6256,7 +6482,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes, nested)
 
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
           != integer_type_node)
-       pedwarn_with_decl (fndecl, "return type of `%s' is not `int'");
+       pedwarn_with_decl (decl1, "return type of `%s' is not `int'");
 
       for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
           args = TREE_CHAIN (args))
@@ -6293,16 +6519,16 @@ start_function (declspecs, declarator, prefix_attributes, attributes, nested)
                   "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");
+      /* 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 (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");
@@ -6994,6 +7220,12 @@ finish_function (nested)
 
   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
@@ -7165,6 +7397,6 @@ pop_c_function_context ()
 
 void
 copy_lang_decl (node)
-     tree node;
+     tree node ATTRIBUTE_UNUSED;
 {
 }