Reimplement diagnostic_show_locus, introducing rich_location classes
[platform/upstream/gcc.git] / gcc / c / c-decl.c
index 6fe418e..e9bdceb 100644 (file)
@@ -1,5 +1,5 @@
 /* Process declarations and variables for C compiler.
-   Copyright (C) 1988-2013 Free Software Foundation, Inc.
+   Copyright (C) 1988-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -27,37 +27,37 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "input.h"
-#include "tm.h"
-#include "intl.h"
+#include "target.h"
+#include "function.h"
 #include "tree.h"
+#include "c-family/c-common.h"
+#include "c-tree.h"
+#include "timevar.h"
+#include "tm_p.h"
+#include "stringpool.h"
+#include "cgraph.h"
+#include "intl.h"
+#include "print-tree.h"
+#include "stor-layout.h"
+#include "varasm.h"
+#include "attribs.h"
 #include "tree-inline.h"
 #include "flags.h"
-#include "function.h"
-#include "c-tree.h"
 #include "toplev.h"
-#include "tm_p.h"
-#include "cpplib.h"
-#include "target.h"
 #include "debug.h"
 #include "opts.h"
-#include "timevar.h"
-#include "c-family/c-common.h"
 #include "c-family/c-objc.h"
 #include "c-family/c-pragma.h"
 #include "c-family/c-ubsan.h"
 #include "c-lang.h"
 #include "langhooks.h"
 #include "tree-iterator.h"
-#include "diagnostic-core.h"
 #include "dumpfile.h"
-#include "cgraph.h"
-#include "hash-table.h"
 #include "langhooks-def.h"
-#include "pointer-set.h"
 #include "plugin.h"
 #include "c-family/c-ada-spec.h"
 #include "cilk.h"
+#include "builtins.h"
 
 /* In grokdeclarator, distinguish syntactic contexts of declarators.  */
 enum decl_context
@@ -145,10 +145,6 @@ static int warn_about_return_type;
 
 static bool undef_nested_function;
 
-/* Mode used to build pointers (VOIDmode means ptr_mode).  */
-
-enum machine_mode c_default_pointer_mode = VOIDmode;
-
 /* If non-zero, implicit "omp declare target" attribute is added into the
    attribute lists.  */
 int current_omp_declare_target_attribute;
@@ -210,21 +206,6 @@ struct GTY((chain_next ("%h.prev"))) c_binding {
 #define B_IN_FILE_SCOPE(b) ((b)->depth == 1 /*file_scope->depth*/)
 #define B_IN_EXTERNAL_SCOPE(b) ((b)->depth == 0 /*external_scope->depth*/)
 
-#define I_SYMBOL_BINDING(node) \
-  (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->symbol_binding)
-#define I_SYMBOL_DECL(node) \
- (I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
-
-#define I_TAG_BINDING(node) \
-  (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->tag_binding)
-#define I_TAG_DECL(node) \
- (I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
-
-#define I_LABEL_BINDING(node) \
-  (((struct lang_identifier *) IDENTIFIER_NODE_CHECK(node))->label_binding)
-#define I_LABEL_DECL(node) \
- (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
-
 /* Each C symbol points to three linked lists of c_binding structures.
    These describe the values of the identifier in the three different
    namespaces defined by the language.  */
@@ -240,6 +221,96 @@ struct GTY(()) lang_identifier {
 extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
 [(sizeof(struct lang_identifier) == C_SIZEOF_STRUCT_LANG_IDENTIFIER) ? 1 : -1];
 
+/* The binding oracle; see c-tree.h.  */
+void (*c_binding_oracle) (enum c_oracle_request, tree identifier);
+
+/* This flag is set on an identifier if we have previously asked the
+   binding oracle for this identifier's symbol binding.  */
+#define I_SYMBOL_CHECKED(node) \
+  (TREE_LANG_FLAG_4 (IDENTIFIER_NODE_CHECK (node)))
+
+static inline struct c_binding* *
+i_symbol_binding (tree node)
+{
+  struct lang_identifier *lid
+    = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
+
+  if (lid->symbol_binding == NULL
+      && c_binding_oracle != NULL
+      && !I_SYMBOL_CHECKED (node))
+    {
+      /* Set the "checked" flag first, to avoid infinite recursion
+        when the binding oracle calls back into gcc.  */
+      I_SYMBOL_CHECKED (node) = 1;
+      c_binding_oracle (C_ORACLE_SYMBOL, node);
+    }
+
+  return &lid->symbol_binding;
+}
+
+#define I_SYMBOL_BINDING(node) (*i_symbol_binding (node))
+
+#define I_SYMBOL_DECL(node) \
+ (I_SYMBOL_BINDING(node) ? I_SYMBOL_BINDING(node)->decl : 0)
+
+/* This flag is set on an identifier if we have previously asked the
+   binding oracle for this identifier's tag binding.  */
+#define I_TAG_CHECKED(node) \
+  (TREE_LANG_FLAG_5 (IDENTIFIER_NODE_CHECK (node)))
+
+static inline struct c_binding **
+i_tag_binding (tree node)
+{
+  struct lang_identifier *lid
+    = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
+
+  if (lid->tag_binding == NULL
+      && c_binding_oracle != NULL
+      && !I_TAG_CHECKED (node))
+    {
+      /* Set the "checked" flag first, to avoid infinite recursion
+        when the binding oracle calls back into gcc.  */
+      I_TAG_CHECKED (node) = 1;
+      c_binding_oracle (C_ORACLE_TAG, node);
+    }
+
+  return &lid->tag_binding;
+}
+
+#define I_TAG_BINDING(node) (*i_tag_binding (node))
+
+#define I_TAG_DECL(node) \
+ (I_TAG_BINDING(node) ? I_TAG_BINDING(node)->decl : 0)
+
+/* This flag is set on an identifier if we have previously asked the
+   binding oracle for this identifier's label binding.  */
+#define I_LABEL_CHECKED(node) \
+  (TREE_LANG_FLAG_6 (IDENTIFIER_NODE_CHECK (node)))
+
+static inline struct c_binding **
+i_label_binding (tree node)
+{
+  struct lang_identifier *lid
+    = (struct lang_identifier *) IDENTIFIER_NODE_CHECK (node);
+
+  if (lid->label_binding == NULL
+      && c_binding_oracle != NULL
+      && !I_LABEL_CHECKED (node))
+    {
+      /* Set the "checked" flag first, to avoid infinite recursion
+        when the binding oracle calls back into gcc.  */
+      I_LABEL_CHECKED (node) = 1;
+      c_binding_oracle (C_ORACLE_LABEL, node);
+    }
+
+  return &lid->label_binding;
+}
+
+#define I_LABEL_BINDING(node) (*i_label_binding (node))
+
+#define I_LABEL_DECL(node) \
+ (I_LABEL_BINDING(node) ? I_LABEL_BINDING(node)->decl : 0)
+
 /* The resulting tree type.  */
 
 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
@@ -532,6 +603,8 @@ static tree grokdeclarator (const struct c_declarator *,
                            bool *, enum deprecated_states);
 static tree grokparms (struct c_arg_info *, bool);
 static void layout_array_type (tree);
+static void warn_defaults_to (location_t, int, const char *, ...)
+    ATTRIBUTE_GCC_DIAG(3,4);
 \f
 /* T is a statement.  Add it to the statement-tree.  This is the
    C/ObjC version--C++ has a slightly different version of this
@@ -567,7 +640,7 @@ c_build_pointer_type (tree to_type)
 {
   addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
                                              : TYPE_ADDR_SPACE (to_type);
-  enum machine_mode pointer_mode;
+  machine_mode pointer_mode;
 
   if (as != ADDR_SPACE_GENERIC || c_default_pointer_mode == VOIDmode)
     pointer_mode = targetm.addr_space.pointer_mode (as);
@@ -587,14 +660,14 @@ decl_jump_unsafe (tree decl)
     return false;
 
   /* Always warn about crossing variably modified types.  */
-  if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == TYPE_DECL)
+  if ((VAR_P (decl) || TREE_CODE (decl) == TYPE_DECL)
       && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
     return true;
 
   /* Otherwise, only warn if -Wgoto-misses-init and this is an
      initialized automatic decl.  */
   if (warn_jump_misses_init
-      && TREE_CODE (decl) == VAR_DECL
+      && VAR_P (decl)
       && !TREE_STATIC (decl)
       && DECL_INITIAL (decl) != NULL_TREE)
     return true;
@@ -606,6 +679,15 @@ decl_jump_unsafe (tree decl)
 void
 c_print_identifier (FILE *file, tree node, int indent)
 {
+  void (*save) (enum c_oracle_request, tree identifier);
+
+  /* Temporarily hide any binding oracle.  Without this, calls to
+     debug_tree from the debugger will end up calling into the oracle,
+     making for a confusing debug session.  As the oracle isn't needed
+     here for normal operation, it's simplest to suppress it.  */
+  save = c_binding_oracle;
+  c_binding_oracle = NULL;
+
   print_node (file, "symbol", I_SYMBOL_DECL (node), indent + 4);
   print_node (file, "tag", I_TAG_DECL (node), indent + 4);
   print_node (file, "label", I_LABEL_DECL (node), indent + 4);
@@ -616,6 +698,8 @@ c_print_identifier (FILE *file, tree node, int indent)
       fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"",
               (void *) rid, IDENTIFIER_POINTER (rid));
     }
+
+  c_binding_oracle = save;
 }
 
 /* Establish a binding between NAME, an IDENTIFIER_NODE, and DECL,
@@ -633,7 +717,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible,
       binding_freelist = b->prev;
     }
   else
-    b = ggc_alloc_c_binding ();
+    b = ggc_alloc<c_binding> ();
 
   b->shadowed = 0;
   b->decl = decl;
@@ -724,7 +808,7 @@ bind_label (tree name, tree label, struct c_scope *scope,
 void
 c_finish_incomplete_decl (tree decl)
 {
-  if (TREE_CODE (decl) == VAR_DECL)
+  if (VAR_P (decl))
     {
       tree type = TREE_TYPE (decl);
       if (type != error_mark_node
@@ -750,7 +834,7 @@ void
 record_inline_static (location_t loc, tree func, tree decl,
                      enum c_inline_static_type type)
 {
-  struct c_inline_static *csi = ggc_alloc_c_inline_static ();
+  c_inline_static *csi = ggc_alloc<c_inline_static> ();
   csi->location = loc;
   csi->function = func;
   csi->static_decl = decl;
@@ -947,7 +1031,7 @@ push_scope (void)
          scope_freelist = scope->outer;
        }
       else
-       scope = ggc_alloc_cleared_c_scope ();
+       scope = ggc_cleared_alloc<c_scope> ();
 
       /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes.  */
       if (current_scope)
@@ -1100,6 +1184,7 @@ pop_scope (void)
     {
       tree file_decl = build_translation_unit_decl (NULL_TREE);
       context = file_decl;
+      debug_hooks->register_main_translation_unit (file_decl);
     }
   else
     context = block;
@@ -1169,7 +1254,9 @@ pop_scope (void)
              /* C99 6.7.4p6: "a function with external linkage... declared
                 with an inline function specifier ... shall also be defined
                 in the same translation unit."  */
-             if (!flag_gnu89_inline)
+             if (!flag_gnu89_inline
+                 && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (p))
+                 && scope != external_scope)
                pedwarn (input_location, 0,
                         "inline function %q+D declared but never defined", p);
              DECL_EXTERNAL (p) = 1;
@@ -1480,6 +1567,54 @@ pushtag (location_t loc, tree name, tree type)
        }
     }
 }
+
+/* An exported interface to pushtag.  This is used by the gdb plugin's
+   binding oracle to introduce a new tag binding.  */
+
+void
+c_pushtag (location_t loc, tree name, tree type)
+{
+  pushtag (loc, name, type);
+}
+
+/* An exported interface to bind a declaration.  LOC is the location
+   to use.  DECL is the declaration to bind.  The decl's name is used
+   to determine how it is bound.  If DECL is a VAR_DECL, then
+   IS_GLOBAL determines whether the decl is put into the global (file
+   and external) scope or the current function's scope; if DECL is not
+   a VAR_DECL then it is always put into the file scope.  */
+
+void
+c_bind (location_t loc, tree decl, bool is_global)
+{
+  struct c_scope *scope;
+  bool nested = false;
+
+  if (!VAR_P (decl) || current_function_scope == NULL)
+    {
+      /* Types and functions are always considered to be global.  */
+      scope = file_scope;
+      DECL_EXTERNAL (decl) = 1;
+      TREE_PUBLIC (decl) = 1;
+    }
+  else if (is_global)
+    {
+      /* Also bind it into the external scope.  */
+      bind (DECL_NAME (decl), decl, external_scope, true, false, loc);
+      nested = true;
+      scope = file_scope;
+      DECL_EXTERNAL (decl) = 1;
+      TREE_PUBLIC (decl) = 1;
+    }
+  else
+    {
+      DECL_CONTEXT (decl) = current_function_decl;
+      TREE_PUBLIC (decl) = 0;
+      scope = current_function_scope;
+    }
+
+  bind (DECL_NAME (decl), decl, scope, false, nested, loc);
+}
 \f
 /* Subroutine of compare_decls.  Allow harmless mismatches in return
    and argument types provided that the type modes match.  This function
@@ -1518,7 +1653,19 @@ match_builtin_function_types (tree newtype, tree oldtype)
     }
 
   trytype = build_function_type (newrettype, tryargs);
-  return build_type_attribute_variant (trytype, TYPE_ATTRIBUTES (oldtype));
+
+  /* Allow declaration to change transaction_safe attribute.  */
+  tree oldattrs = TYPE_ATTRIBUTES (oldtype);
+  tree oldtsafe = lookup_attribute ("transaction_safe", oldattrs);
+  tree newattrs = TYPE_ATTRIBUTES (newtype);
+  tree newtsafe = lookup_attribute ("transaction_safe", newattrs);
+  if (oldtsafe && !newtsafe)
+    oldattrs = remove_attribute ("transaction_safe", oldattrs);
+  else if (newtsafe && !oldtsafe)
+    oldattrs = tree_cons (get_identifier ("transaction_safe"),
+                         NULL_TREE, oldattrs);
+
+  return build_type_attribute_variant (trytype, oldattrs);
 }
 
 /* Subroutine of diagnose_mismatched_decls.  Check for function type
@@ -1838,12 +1985,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                 newdecl);
          locate_old_decl (olddecl);
        }
-      else if (pedantic && !flag_isoc11)
-       {
-         pedwarn (input_location, OPT_Wpedantic,
-                  "redefinition of typedef %q+D", newdecl);
-         locate_old_decl (olddecl);
-       }
+      else if (pedwarn_c99 (input_location, OPT_Wpedantic,
+                           "redefinition of typedef %q+D", newdecl))
+       locate_old_decl (olddecl);
 
       return true;
     }
@@ -1970,7 +2114,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
            }
        }
     }
-  else if (TREE_CODE (newdecl) == VAR_DECL)
+  else if (VAR_P (newdecl))
     {
       /* Only variables can be thread-local, and all declarations must
         agree on this property.  */
@@ -2094,18 +2238,38 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       /* Diagnose inline __attribute__ ((noinline)) which is silly.  */
       if (DECL_DECLARED_INLINE_P (newdecl)
          && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
-       {
-         warned |= warning (OPT_Wattributes,
-                            "inline declaration of %qD follows "
-                            "declaration with attribute noinline", newdecl);
-       }
+       warned |= warning (OPT_Wattributes,
+                          "inline declaration of %qD follows "
+                          "declaration with attribute noinline", newdecl);
       else if (DECL_DECLARED_INLINE_P (olddecl)
               && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
-       {
-         warned |= warning (OPT_Wattributes,
-                            "declaration of %q+D with attribute "
-                            "noinline follows inline declaration ", newdecl);
-       }
+       warned |= warning (OPT_Wattributes,
+                          "declaration of %q+D with attribute "
+                          "noinline follows inline declaration ", newdecl);
+      else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))
+              && lookup_attribute ("always_inline", DECL_ATTRIBUTES (olddecl)))
+       warned |= warning (OPT_Wattributes,
+                          "declaration of %q+D with attribute "
+                          "%qs follows declaration with attribute %qs",
+                          newdecl, "noinline", "always_inline");
+      else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (newdecl))
+              && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
+       warned |= warning (OPT_Wattributes,
+                          "declaration of %q+D with attribute "
+                          "%qs follows declaration with attribute %qs",
+                          newdecl, "always_inline", "noinline");
+      else if (lookup_attribute ("cold", DECL_ATTRIBUTES (newdecl))
+              && lookup_attribute ("hot", DECL_ATTRIBUTES (olddecl)))
+       warned |= warning (OPT_Wattributes,
+                          "declaration of %q+D with attribute %qs follows "
+                          "declaration with attribute %qs", newdecl, "cold",
+                          "hot");
+      else if (lookup_attribute ("hot", DECL_ATTRIBUTES (newdecl))
+              && lookup_attribute ("cold", DECL_ATTRIBUTES (olddecl)))
+       warned |= warning (OPT_Wattributes,
+                          "declaration of %q+D with attribute %qs follows "
+                          "declaration with attribute %qs", newdecl, "hot",
+                          "cold");
     }
   else /* PARM_DECL, VAR_DECL */
     {
@@ -2145,7 +2309,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       && !(TREE_CODE (newdecl) == PARM_DECL
           && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
       /* Don't warn about a variable definition following a declaration.  */
-      && !(TREE_CODE (newdecl) == VAR_DECL
+      && !(VAR_P (newdecl)
           && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl)))
     {
       warned = warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D",
@@ -2266,21 +2430,11 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
     DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
 
   /* Merge the threadprivate attribute.  */
-  if (TREE_CODE (olddecl) == VAR_DECL && C_DECL_THREADPRIVATE_P (olddecl))
-    {
-      DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl);
-      C_DECL_THREADPRIVATE_P (newdecl) = 1;
-    }
+  if (VAR_P (olddecl) && C_DECL_THREADPRIVATE_P (olddecl))
+    C_DECL_THREADPRIVATE_P (newdecl) = 1;
 
   if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS))
     {
-      /* Merge the section attribute.
-        We want to issue an error if the sections conflict but that
-        must be done later in decl_attributes since we are called
-        before attributes are assigned.  */
-      if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
-       DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
-
       /* Copy the assembler name.
         Currently, it can only be defined in the prototype.  */
       COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
@@ -2338,6 +2492,14 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
       && !current_function_decl)
     DECL_EXTERNAL (newdecl) = 0;
 
+  /* An inline definition following a static declaration is not
+     DECL_EXTERNAL.  */
+  if (new_is_definition
+      && (DECL_DECLARED_INLINE_P (newdecl)
+         || DECL_DECLARED_INLINE_P (olddecl))
+      && !TREE_PUBLIC (olddecl))
+    DECL_EXTERNAL (newdecl) = 0;
+
   if (DECL_EXTERNAL (newdecl))
     {
       TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
@@ -2406,6 +2568,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
                        set_builtin_decl_implicit_p (fncode, true);
                      break;
                    default:
+                     if (builtin_decl_explicit_p (fncode))
+                       set_builtin_decl_declared_p (fncode, true);
                      break;
                    }
                }
@@ -2450,13 +2614,19 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
     TREE_USED (newdecl) = 1;
   else if (TREE_USED (newdecl))
     TREE_USED (olddecl) = 1;
-  if (TREE_CODE (olddecl) == VAR_DECL || TREE_CODE (olddecl) == PARM_DECL)
+  if (VAR_P (olddecl) || TREE_CODE (olddecl) == PARM_DECL)
     DECL_READ_P (newdecl) |= DECL_READ_P (olddecl);
   if (DECL_PRESERVE_P (olddecl))
     DECL_PRESERVE_P (newdecl) = 1;
   else if (DECL_PRESERVE_P (newdecl))
     DECL_PRESERVE_P (olddecl) = 1;
 
+  /* Merge DECL_COMMON */
+  if (VAR_P (olddecl) && VAR_P (newdecl)
+      && !lookup_attribute ("common", DECL_ATTRIBUTES (newdecl))
+      && !lookup_attribute ("nocommon", DECL_ATTRIBUTES (newdecl)))
+    DECL_COMMON (newdecl) = DECL_COMMON (newdecl) && DECL_COMMON (olddecl);
+
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
      But preserve OLDDECL's DECL_UID, DECL_CONTEXT and
      DECL_ARGUMENTS (if appropriate).  */
@@ -2474,8 +2644,31 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
     switch (TREE_CODE (olddecl))
       {
       case FUNCTION_DECL:
-      case FIELD_DECL:
       case VAR_DECL:
+       {
+         struct symtab_node *snode = olddecl->decl_with_vis.symtab_node;
+
+         memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
+                 (char *) newdecl + sizeof (struct tree_decl_common),
+                 tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common));
+         olddecl->decl_with_vis.symtab_node = snode;
+
+         if ((DECL_EXTERNAL (olddecl)
+              || TREE_PUBLIC (olddecl)
+              || TREE_STATIC (olddecl))
+             && DECL_SECTION_NAME (newdecl) != NULL)
+           set_decl_section_name (olddecl, DECL_SECTION_NAME (newdecl));
+
+         /* This isn't quite correct for something like
+               int __thread x attribute ((tls_model ("local-exec")));
+               extern int __thread x;
+            as we'll lose the "local-exec" model.  */
+         if (VAR_P (olddecl) && DECL_THREAD_LOCAL_P (newdecl))
+           set_decl_tls_model (olddecl, DECL_TLS_MODEL (newdecl));
+         break;
+       }
+
+      case FIELD_DECL:
       case PARM_DECL:
       case LABEL_DECL:
       case RESULT_DECL:
@@ -2503,8 +2696,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
      flags and attributes.  */
   if (DECL_RTL_SET_P (olddecl)
       && (TREE_CODE (olddecl) == FUNCTION_DECL
-         || (TREE_CODE (olddecl) == VAR_DECL
-             && TREE_STATIC (olddecl))))
+         || (VAR_P (olddecl) && TREE_STATIC (olddecl))))
     make_decl_rtl (olddecl);
 }
 
@@ -2528,6 +2720,22 @@ duplicate_decls (tree newdecl, tree olddecl)
     }
 
   merge_decls (newdecl, olddecl, newtype, oldtype);
+
+  /* The NEWDECL will no longer be needed.
+
+     Before releasing the node, be sure to remove function from symbol
+     table that might have been inserted there to record comdat group.
+     Be sure to however do not free DECL_STRUCT_FUNCTION because this
+     structure is shared in between NEWDECL and OLDECL.  */
+  if (TREE_CODE (newdecl) == FUNCTION_DECL)
+    DECL_STRUCT_FUNCTION (newdecl) = NULL;
+  if (VAR_OR_FUNCTION_DECL_P (newdecl))
+    {
+      struct symtab_node *snode = symtab_node::get (newdecl);
+      if (snode)
+       snode->remove ();
+    }
+  ggc_free (newdecl);
   return true;
 }
 
@@ -2554,6 +2762,7 @@ warn_if_shadowing (tree new_decl)
                                             DECL_SOURCE_LOCATION (b->decl))))
       {
        tree old_decl = b->decl;
+       bool warned = false;
 
        if (old_decl == error_mark_node)
          {
@@ -2562,8 +2771,9 @@ warn_if_shadowing (tree new_decl)
            break;
          }
        else if (TREE_CODE (old_decl) == PARM_DECL)
-         warning (OPT_Wshadow, "declaration of %q+D shadows a parameter",
-                  new_decl);
+         warned = warning (OPT_Wshadow,
+                           "declaration of %q+D shadows a parameter",
+                           new_decl);
        else if (DECL_FILE_SCOPE_P (old_decl))
          {
            /* Do not warn if a variable shadows a function, unless
@@ -2573,9 +2783,10 @@ warn_if_shadowing (tree new_decl)
                && !FUNCTION_POINTER_TYPE_P (TREE_TYPE (new_decl)))
                continue;
 
-           warning_at (DECL_SOURCE_LOCATION (new_decl), OPT_Wshadow, 
-                       "declaration of %qD shadows a global declaration",
-                       new_decl);
+           warned = warning_at (DECL_SOURCE_LOCATION (new_decl), OPT_Wshadow,
+                                "declaration of %qD shadows a global "
+                                "declaration",
+                                new_decl);
          }
        else if (TREE_CODE (old_decl) == FUNCTION_DECL
                 && DECL_BUILT_IN (old_decl))
@@ -2585,11 +2796,12 @@ warn_if_shadowing (tree new_decl)
            break;
          }
        else
-         warning (OPT_Wshadow, "declaration of %q+D shadows a previous local",
-                  new_decl);
+         warned = warning (OPT_Wshadow, "declaration of %q+D shadows a "
+                           "previous local", new_decl);
 
-       warning_at (DECL_SOURCE_LOCATION (old_decl), OPT_Wshadow,
-                   "shadowed declaration is here");
+       if (warned)
+         inform (DECL_SOURCE_LOCATION (old_decl),
+                 "shadowed declaration is here");
 
        break;
       }
@@ -2616,7 +2828,7 @@ pushdecl (tree x)
      DECL_FILE_SCOPE_P won't work.  Local externs don't count
      unless they have initializers (which generate code).  */
   if (current_function_decl
-      && ((TREE_CODE (x) != FUNCTION_DECL && TREE_CODE (x) != VAR_DECL)
+      && (!VAR_OR_FUNCTION_DECL_P (x)
          || DECL_INITIAL (x) || !DECL_EXTERNAL (x)))
     DECL_CONTEXT (x) = current_function_decl;
 
@@ -2707,8 +2919,7 @@ pushdecl (tree x)
       tree visdecl = 0;
       bool type_saved = false;
       if (b && !B_IN_EXTERNAL_SCOPE (b)
-         && (TREE_CODE (b->decl) == FUNCTION_DECL
-             || TREE_CODE (b->decl) == VAR_DECL)
+         && VAR_OR_FUNCTION_DECL_P (b->decl)
          && DECL_FILE_SCOPE_P (b->decl))
        {
          visdecl = b->decl;
@@ -2734,7 +2945,7 @@ pushdecl (tree x)
              type_saved = true;
            }
          if (B_IN_FILE_SCOPE (b)
-             && TREE_CODE (b->decl) == VAR_DECL
+             && VAR_P (b->decl)
              && TREE_STATIC (b->decl)
              && TREE_CODE (TREE_TYPE (b->decl)) == ARRAY_TYPE
              && !TYPE_DOMAIN (TREE_TYPE (b->decl))
@@ -2865,7 +3076,7 @@ pushdecl_top_level (tree x)
 {
   tree name;
   bool nested = false;
-  gcc_assert (TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == CONST_DECL);
+  gcc_assert (VAR_P (x) || TREE_CODE (x) == CONST_DECL);
 
   name = DECL_NAME (x);
 
@@ -2884,23 +3095,206 @@ pushdecl_top_level (tree x)
 }
 \f
 static void
-implicit_decl_warning (tree id, tree olddecl)
+implicit_decl_warning (location_t loc, tree id, tree olddecl)
 {
   if (warn_implicit_function_declaration)
     {
       bool warned;
 
       if (flag_isoc99)
-       warned = pedwarn (input_location, OPT_Wimplicit_function_declaration,
+       warned = pedwarn (loc, OPT_Wimplicit_function_declaration,
                          "implicit declaration of function %qE", id);
       else
-       warned = warning (OPT_Wimplicit_function_declaration,
-                         G_("implicit declaration of function %qE"), id);
+       warned = warning_at (loc, OPT_Wimplicit_function_declaration,
+                            G_("implicit declaration of function %qE"), id);
       if (olddecl && warned)
        locate_old_decl (olddecl);
     }
 }
 
+/* This function represents mapping of a function code FCODE
+   to its respective header.  */
+
+static const char *
+header_for_builtin_fn (enum built_in_function fcode)
+{
+  switch (fcode)
+    {
+    CASE_FLT_FN (BUILT_IN_ACOS):
+    CASE_FLT_FN (BUILT_IN_ACOSH):
+    CASE_FLT_FN (BUILT_IN_ASIN):
+    CASE_FLT_FN (BUILT_IN_ASINH):
+    CASE_FLT_FN (BUILT_IN_ATAN):
+    CASE_FLT_FN (BUILT_IN_ATANH):
+    CASE_FLT_FN (BUILT_IN_ATAN2):
+    CASE_FLT_FN (BUILT_IN_CBRT):
+    CASE_FLT_FN (BUILT_IN_CEIL):
+    CASE_FLT_FN (BUILT_IN_COPYSIGN):
+    CASE_FLT_FN (BUILT_IN_COS):
+    CASE_FLT_FN (BUILT_IN_COSH):
+    CASE_FLT_FN (BUILT_IN_ERF):
+    CASE_FLT_FN (BUILT_IN_ERFC):
+    CASE_FLT_FN (BUILT_IN_EXP):
+    CASE_FLT_FN (BUILT_IN_EXP2):
+    CASE_FLT_FN (BUILT_IN_EXPM1):
+    CASE_FLT_FN (BUILT_IN_FABS):
+    CASE_FLT_FN (BUILT_IN_FDIM):
+    CASE_FLT_FN (BUILT_IN_FLOOR):
+    CASE_FLT_FN (BUILT_IN_FMA):
+    CASE_FLT_FN (BUILT_IN_FMAX):
+    CASE_FLT_FN (BUILT_IN_FMIN):
+    CASE_FLT_FN (BUILT_IN_FMOD):
+    CASE_FLT_FN (BUILT_IN_FREXP):
+    CASE_FLT_FN (BUILT_IN_HYPOT):
+    CASE_FLT_FN (BUILT_IN_ILOGB):
+    CASE_FLT_FN (BUILT_IN_LDEXP):
+    CASE_FLT_FN (BUILT_IN_LGAMMA):
+    CASE_FLT_FN (BUILT_IN_LLRINT):
+    CASE_FLT_FN (BUILT_IN_LLROUND):
+    CASE_FLT_FN (BUILT_IN_LOG):
+    CASE_FLT_FN (BUILT_IN_LOG10):
+    CASE_FLT_FN (BUILT_IN_LOG1P):
+    CASE_FLT_FN (BUILT_IN_LOG2):
+    CASE_FLT_FN (BUILT_IN_LOGB):
+    CASE_FLT_FN (BUILT_IN_LRINT):
+    CASE_FLT_FN (BUILT_IN_LROUND):
+    CASE_FLT_FN (BUILT_IN_MODF):
+    CASE_FLT_FN (BUILT_IN_NAN):
+    CASE_FLT_FN (BUILT_IN_NEARBYINT):
+    CASE_FLT_FN (BUILT_IN_NEXTAFTER):
+    CASE_FLT_FN (BUILT_IN_NEXTTOWARD):
+    CASE_FLT_FN (BUILT_IN_POW):
+    CASE_FLT_FN (BUILT_IN_REMAINDER):
+    CASE_FLT_FN (BUILT_IN_REMQUO):
+    CASE_FLT_FN (BUILT_IN_RINT):
+    CASE_FLT_FN (BUILT_IN_ROUND):
+    CASE_FLT_FN (BUILT_IN_SCALBLN):
+    CASE_FLT_FN (BUILT_IN_SCALBN):
+    CASE_FLT_FN (BUILT_IN_SIN):
+    CASE_FLT_FN (BUILT_IN_SINH):
+    CASE_FLT_FN (BUILT_IN_SINCOS):
+    CASE_FLT_FN (BUILT_IN_SQRT):
+    CASE_FLT_FN (BUILT_IN_TAN):
+    CASE_FLT_FN (BUILT_IN_TANH):
+    CASE_FLT_FN (BUILT_IN_TGAMMA):
+    CASE_FLT_FN (BUILT_IN_TRUNC):
+    case BUILT_IN_ISINF:
+    case BUILT_IN_ISNAN:
+      return "<math.h>";
+    CASE_FLT_FN (BUILT_IN_CABS):
+    CASE_FLT_FN (BUILT_IN_CACOS):
+    CASE_FLT_FN (BUILT_IN_CACOSH):
+    CASE_FLT_FN (BUILT_IN_CARG):
+    CASE_FLT_FN (BUILT_IN_CASIN):
+    CASE_FLT_FN (BUILT_IN_CASINH):
+    CASE_FLT_FN (BUILT_IN_CATAN):
+    CASE_FLT_FN (BUILT_IN_CATANH):
+    CASE_FLT_FN (BUILT_IN_CCOS):
+    CASE_FLT_FN (BUILT_IN_CCOSH):
+    CASE_FLT_FN (BUILT_IN_CEXP):
+    CASE_FLT_FN (BUILT_IN_CIMAG):
+    CASE_FLT_FN (BUILT_IN_CLOG):
+    CASE_FLT_FN (BUILT_IN_CONJ):
+    CASE_FLT_FN (BUILT_IN_CPOW):
+    CASE_FLT_FN (BUILT_IN_CPROJ):
+    CASE_FLT_FN (BUILT_IN_CREAL):
+    CASE_FLT_FN (BUILT_IN_CSIN):
+    CASE_FLT_FN (BUILT_IN_CSINH):
+    CASE_FLT_FN (BUILT_IN_CSQRT):
+    CASE_FLT_FN (BUILT_IN_CTAN):
+    CASE_FLT_FN (BUILT_IN_CTANH):
+      return "<complex.h>";
+    case BUILT_IN_MEMCHR:
+    case BUILT_IN_MEMCMP:
+    case BUILT_IN_MEMCPY:
+    case BUILT_IN_MEMMOVE:
+    case BUILT_IN_MEMSET:
+    case BUILT_IN_STRCAT:
+    case BUILT_IN_STRCHR:
+    case BUILT_IN_STRCMP:
+    case BUILT_IN_STRCPY:
+    case BUILT_IN_STRCSPN:
+    case BUILT_IN_STRLEN:
+    case BUILT_IN_STRNCAT:
+    case BUILT_IN_STRNCMP:
+    case BUILT_IN_STRNCPY:
+    case BUILT_IN_STRPBRK:
+    case BUILT_IN_STRRCHR:
+    case BUILT_IN_STRSPN:
+    case BUILT_IN_STRSTR:
+      return "<string.h>";
+    case BUILT_IN_FPRINTF:
+    case BUILT_IN_PUTC:
+    case BUILT_IN_FPUTC:
+    case BUILT_IN_FPUTS:
+    case BUILT_IN_FSCANF:
+    case BUILT_IN_FWRITE:
+    case BUILT_IN_PRINTF:
+    case BUILT_IN_PUTCHAR:
+    case BUILT_IN_PUTS:
+    case BUILT_IN_SCANF:
+    case BUILT_IN_SNPRINTF:
+    case BUILT_IN_SPRINTF:
+    case BUILT_IN_SSCANF:
+    case BUILT_IN_VFPRINTF:
+    case BUILT_IN_VFSCANF:
+    case BUILT_IN_VPRINTF:
+    case BUILT_IN_VSCANF:
+    case BUILT_IN_VSNPRINTF:
+    case BUILT_IN_VSPRINTF:
+    case BUILT_IN_VSSCANF:
+      return "<stdio.h>";
+    case BUILT_IN_ISALNUM:
+    case BUILT_IN_ISALPHA:
+    case BUILT_IN_ISBLANK:
+    case BUILT_IN_ISCNTRL:
+    case BUILT_IN_ISDIGIT:
+    case BUILT_IN_ISGRAPH:
+    case BUILT_IN_ISLOWER:
+    case BUILT_IN_ISPRINT:
+    case BUILT_IN_ISPUNCT:
+    case BUILT_IN_ISSPACE:
+    case BUILT_IN_ISUPPER:
+    case BUILT_IN_ISXDIGIT:
+    case BUILT_IN_TOLOWER:
+    case BUILT_IN_TOUPPER:
+      return "<ctype.h>";
+    case BUILT_IN_ISWALNUM:
+    case BUILT_IN_ISWALPHA:
+    case BUILT_IN_ISWBLANK:
+    case BUILT_IN_ISWCNTRL:
+    case BUILT_IN_ISWDIGIT:
+    case BUILT_IN_ISWGRAPH:
+    case BUILT_IN_ISWLOWER:
+    case BUILT_IN_ISWPRINT:
+    case BUILT_IN_ISWPUNCT:
+    case BUILT_IN_ISWSPACE:
+    case BUILT_IN_ISWUPPER:
+    case BUILT_IN_ISWXDIGIT:
+    case BUILT_IN_TOWLOWER:
+    case BUILT_IN_TOWUPPER:
+      return "<wctype.h>";
+    case BUILT_IN_ABORT:
+    case BUILT_IN_ABS:
+    case BUILT_IN_CALLOC:
+    case BUILT_IN_EXIT:
+    case BUILT_IN_FREE:
+    case BUILT_IN_LABS:
+    case BUILT_IN_LLABS:
+    case BUILT_IN_MALLOC:
+    case BUILT_IN_REALLOC:
+    case BUILT_IN__EXIT2:
+    case BUILT_IN_ALIGNED_ALLOC:
+      return "<stdlib.h>";
+    case BUILT_IN_IMAXABS:
+      return "<inttypes.h>";
+    case BUILT_IN_STRFTIME:
+      return "<time.h>";
+    default:
+      return NULL;
+    }
+}
+
 /* Generate an implicit declaration for identifier FUNCTIONID at LOC as a
    function of type int ().  */
 
@@ -2948,7 +3342,7 @@ implicitly_declare (location_t loc, tree functionid)
             then recycle the old declaration but with the new type.  */
          if (!C_DECL_IMPLICIT (decl))
            {
-             implicit_decl_warning (functionid, decl);
+             implicit_decl_warning (loc, functionid, decl);
              C_DECL_IMPLICIT (decl) = 1;
            }
          if (DECL_BUILT_IN (decl))
@@ -2958,8 +3352,15 @@ implicitly_declare (location_t loc, tree functionid)
                                                      (TREE_TYPE (decl)));
              if (!comptypes (newtype, TREE_TYPE (decl)))
                {
-                 warning_at (loc, 0, "incompatible implicit declaration of "
-                             "built-in function %qD", decl);
+                 bool warned = warning_at (loc, 0, "incompatible implicit "
+                                           "declaration of built-in "
+                                           "function %qD", decl);
+                 /* See if we can hint which header to include.  */
+                 const char *header
+                   = header_for_builtin_fn (DECL_FUNCTION_CODE (decl));
+                 if (header != NULL && warned)
+                   inform (loc, "include %qs or provide a declaration of %qD",
+                           header, decl);
                  newtype = TREE_TYPE (decl);
                }
            }
@@ -2967,7 +3368,8 @@ implicitly_declare (location_t loc, tree functionid)
            {
              if (!comptypes (newtype, TREE_TYPE (decl)))
                {
-                 error_at (loc, "incompatible implicit declaration of function %qD", decl);
+                 error_at (loc, "incompatible implicit declaration of "
+                           "function %qD", decl);
                  locate_old_decl (decl);
                }
            }
@@ -2985,7 +3387,7 @@ implicitly_declare (location_t loc, tree functionid)
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 1;
   C_DECL_IMPLICIT (decl) = 1;
-  implicit_decl_warning (functionid, 0);
+  implicit_decl_warning (loc, functionid, 0);
   asmspec_tree = maybe_apply_renaming_pragma (decl, /*asmname=*/NULL);
   if (asmspec_tree)
     set_user_assembler_name (decl, TREE_STRING_POINTER (asmspec_tree));
@@ -3051,12 +3453,10 @@ make_label (location_t location, tree name, bool defining,
            struct c_label_vars **p_label_vars)
 {
   tree label = build_decl (location, LABEL_DECL, name, void_type_node);
-  struct c_label_vars *label_vars;
-
   DECL_CONTEXT (label) = current_function_decl;
   DECL_MODE (label) = VOIDmode;
 
-  label_vars = ggc_alloc_c_label_vars ();
+  c_label_vars *label_vars = ggc_alloc<c_label_vars> ();
   label_vars->shadowed = NULL;
   set_spot_bindings (&label_vars->label_bindings, defining);
   label_vars->decls_in_scope = make_tree_vector ();
@@ -3080,7 +3480,7 @@ lookup_label (tree name)
   if (current_function_scope == 0)
     {
       error ("label %qE referenced outside of any function", name);
-      return 0;
+      return NULL_TREE;
     }
 
   /* Use a label already defined or ref'd with this name, but not if
@@ -3152,9 +3552,8 @@ lookup_label_for_goto (location_t loc, tree name)
      list for possible later warnings.  */
   if (label_vars->label_bindings.scope == NULL)
     {
-      struct c_goto_bindings *g;
+      c_goto_bindings *g = ggc_alloc<c_goto_bindings> ();
 
-      g = ggc_alloc_c_goto_bindings ();
       g->loc = loc;
       set_spot_bindings (&g->goto_bindings, true);
       vec_safe_push (label_vars->gotos, g);
@@ -3323,7 +3722,7 @@ define_label (location_t location, tree name)
       bind_label (name, label, current_function_scope, label_vars);
     }
 
-  if (!in_system_header && lookup_name (name))
+  if (!in_system_header_at (input_location) && lookup_name (name))
     warning_at (location, OPT_Wtraditional,
                "traditional C lacks a separate namespace "
                "for labels, identifier %qE conflicts", name);
@@ -3418,14 +3817,14 @@ c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings,
    If the wrong kind of type is found, an error is reported.  */
 
 static tree
-lookup_tag (enum tree_code code, tree name, int thislevel_only,
+lookup_tag (enum tree_code code, tree name, bool thislevel_only,
            location_t *ploc)
 {
   struct c_binding *b = I_TAG_BINDING (name);
-  int thislevel = 0;
+  bool thislevel = false;
 
   if (!b || !b->decl)
-    return 0;
+    return NULL_TREE;
 
   /* We only care about whether it's in this level if
      thislevel_only was set or it might be a type clash.  */
@@ -3437,11 +3836,11 @@ lookup_tag (enum tree_code code, tree name, int thislevel_only,
         file scope is created.)  */
       if (B_IN_CURRENT_SCOPE (b)
          || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b)))
-       thislevel = 1;
+       thislevel = true;
     }
 
   if (thislevel_only && !thislevel)
-    return 0;
+    return NULL_TREE;
 
   if (TREE_CODE (b->decl) != code)
     {
@@ -3463,6 +3862,18 @@ lookup_tag (enum tree_code code, tree name, int thislevel_only,
   return b->decl;
 }
 
+/* Return true if a definition exists for NAME with code CODE.  */
+
+bool
+tag_exists_p (enum tree_code code, tree name)
+{
+  struct c_binding *b = I_TAG_BINDING (name);
+
+  if (b == NULL || b->decl == NULL_TREE)
+    return false;
+  return TREE_CODE (b->decl) == code;
+}
+
 /* Print an error message now
    for a recent invalid struct, union or enum cross reference.
    We don't print them immediately because they are not invalid
@@ -3492,7 +3903,7 @@ lookup_name (tree name)
       maybe_record_typedef_use (b->decl);
       return b->decl;
     }
-  return 0;
+  return NULL_TREE;
 }
 
 /* Similar to `lookup_name' but look only at the indicated scope.  */
@@ -3505,7 +3916,7 @@ lookup_name_in_scope (tree name, struct c_scope *scope)
   for (b = I_SYMBOL_BINDING (name); b; b = b->shadowed)
     if (B_IN_SCOPE (b, scope))
       return b->decl;
-  return 0;
+  return NULL_TREE;
 }
 \f
 /* Create the predefined scalar types of C,
@@ -3547,8 +3958,6 @@ c_init_decl_processing (void)
 
   input_location = save_loc;
 
-  pedantic_lvalues = true;
-
   make_fname_decl = c_make_fname_decl;
   start_fname_decls ();
 }
@@ -3641,8 +4050,9 @@ c_builtin_function_ext_scope (tree decl)
   const char *name = IDENTIFIER_POINTER (id);
   C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type);
 
-  bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false,
-       UNKNOWN_LOCATION);
+  if (external_scope)
+    bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false,
+         UNKNOWN_LOCATION);
 
   /* Builtins in the implementation namespace are made visible without
      needing to be explicitly declared.  See push_file_scope.  */
@@ -3746,9 +4156,9 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
          else
            {
              pending_invalid_xref = 0;
-             t = lookup_tag (code, name, 1, NULL);
+             t = lookup_tag (code, name, true, NULL);
 
-             if (t == 0)
+             if (t == NULL_TREE)
                {
                  t = make_node (code);
                  pushtag (input_location, name, t);
@@ -3757,7 +4167,7 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
        }
       else
        {
-         if (warned != 1 && !in_system_header)
+         if (warned != 1 && !in_system_header_at (input_location))
            {
              pedwarn (input_location, 0,
                       "useless type name in empty declaration");
@@ -3765,7 +4175,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
            }
        }
     }
-  else if (warned != 1 && !in_system_header && declspecs->typedef_p)
+  else if (warned != 1 && !in_system_header_at (input_location)
+          && declspecs->typedef_p)
     {
       pedwarn (input_location, 0, "useless type name in empty declaration");
       warned = 1;
@@ -3797,30 +4208,34 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
       warned = 1;
     }
 
-  if (!warned && !in_system_header && declspecs->storage_class != csc_none)
+  if (!warned && !in_system_header_at (input_location)
+      && declspecs->storage_class != csc_none)
     {
       warning (0, "useless storage class specifier in empty declaration");
       warned = 2;
     }
 
-  if (!warned && !in_system_header && declspecs->thread_p)
+  if (!warned && !in_system_header_at (input_location) && declspecs->thread_p)
     {
       warning (0, "useless %qs in empty declaration",
               declspecs->thread_gnu_p ? "__thread" : "_Thread_local");
       warned = 2;
     }
 
-  if (!warned && !in_system_header && (declspecs->const_p
-                                      || declspecs->volatile_p
-                                      || declspecs->atomic_p
-                                      || declspecs->restrict_p
-                                      || declspecs->address_space))
+  if (!warned
+      && !in_system_header_at (input_location)
+      && (declspecs->const_p
+         || declspecs->volatile_p
+         || declspecs->atomic_p
+         || declspecs->restrict_p
+         || declspecs->address_space))
     {
       warning (0, "useless type qualifier in empty declaration");
       warned = 2;
     }
 
-  if (!warned && !in_system_header && declspecs->alignas_p)
+  if (!warned && !in_system_header_at (input_location)
+      && declspecs->alignas_p)
     {
       warning (0, "useless %<_Alignas%> in empty declaration");
       warned = 2;
@@ -3898,16 +4313,13 @@ build_array_declarator (location_t loc,
     }
   declarator->u.array.static_p = static_p;
   declarator->u.array.vla_unspec_p = vla_unspec_p;
-  if (!flag_isoc99)
-    {
-      if (static_p || quals != NULL)
-       pedwarn (loc, OPT_Wpedantic,
+  if (static_p || quals != NULL)
+    pedwarn_c90 (loc, OPT_Wpedantic,
                 "ISO C90 does not support %<static%> or type "
                 "qualifiers in parameter array declarators");
-      if (vla_unspec_p)
-       pedwarn (loc, OPT_Wpedantic,
+  if (vla_unspec_p)
+    pedwarn_c90 (loc, OPT_Wpedantic,
                 "ISO C90 does not support %<[*]%> array declarators");
-    }
   if (vla_unspec_p)
     {
       if (!current_scope->parm_flag)
@@ -3995,17 +4407,11 @@ c_decl_attributes (tree *node, tree attributes, int flags)
 {
   /* Add implicit "omp declare target" attribute if requested.  */
   if (current_omp_declare_target_attribute
-      && ((TREE_CODE (*node) == VAR_DECL && TREE_STATIC (*node))
+      && ((VAR_P (*node) && is_global_var (*node))
          || TREE_CODE (*node) == FUNCTION_DECL))
     {
-      if (TREE_CODE (*node) == VAR_DECL
-         && ((DECL_CONTEXT (*node)
-              && TREE_CODE (DECL_CONTEXT (*node)) == FUNCTION_DECL)
-             || (current_function_decl && !DECL_EXTERNAL (*node))))
-       error ("%q+D in block scope inside of declare target directive",
-              *node);
-      else if (TREE_CODE (*node) == VAR_DECL
-              && !COMPLETE_TYPE_P (TREE_TYPE (*node)))
+      if (VAR_P (*node)
+         && !lang_hooks.types.omp_mappable_type (TREE_TYPE (*node)))
        error ("%q+D in declare target directive does not have mappable type",
               *node);
       else
@@ -4048,8 +4454,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
   decl = grokdeclarator (declarator, declspecs,
                         NORMAL, initialized, NULL, &attributes, &expr, NULL,
                         deprecated_state);
-  if (!decl)
-    return 0;
+  if (!decl || decl == error_mark_node)
+    return NULL_TREE;
 
   if (expr)
     add_stmt (fold_convert (void_type_node, expr));
@@ -4142,7 +4548,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
      body of code to break, and it allows more efficient variable references
      in the presence of dynamic linking.  */
 
-  if (TREE_CODE (decl) == VAR_DECL
+  if (VAR_P (decl)
       && !initialized
       && TREE_PUBLIC (decl)
       && !DECL_THREAD_LOCAL_P (decl)
@@ -4195,7 +4601,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
   /* C99 6.7.4p3: An inline definition of a function with external
      linkage shall not contain a definition of a modifiable object
      with static storage duration...  */
-  if (TREE_CODE (decl) == VAR_DECL
+  if (VAR_P (decl)
       && current_scope != file_scope
       && TREE_STATIC (decl)
       && !TREE_READONLY (decl)
@@ -4204,9 +4610,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
     record_inline_static (input_location, current_function_decl,
                          decl, csi_modifiable);
 
-  if (c_dialect_objc () 
-      && (TREE_CODE (decl) == VAR_DECL
-          || TREE_CODE (decl) == FUNCTION_DECL))
+  if (c_dialect_objc ()
+      && VAR_OR_FUNCTION_DECL_P (decl))
       objc_check_global_decl (decl);
 
   /* Add this decl to the current scope.
@@ -4261,20 +4666,20 @@ diagnose_uninitialized_cst_member (tree decl, tree type)
 
 void
 finish_decl (tree decl, location_t init_loc, tree init,
-            tree origtype, tree asmspec_tree)
+            tree origtype, tree asmspec_tree)
 {
   tree type;
   bool was_incomplete = (DECL_SIZE (decl) == 0);
   const char *asmspec = 0;
 
   /* If a name was specified, get the string.  */
-  if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL)
+  if (VAR_OR_FUNCTION_DECL_P (decl)
       && DECL_FILE_SCOPE_P (decl))
     asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
   if (asmspec_tree)
     asmspec = TREE_STRING_POINTER (asmspec_tree);
 
-  if (TREE_CODE (decl) == VAR_DECL
+  if (VAR_P (decl)
       && TREE_STATIC (decl)
       && global_bindings_p ())
     /* So decl is a global variable. Record the types it uses
@@ -4292,8 +4697,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
   if (init)
     store_init_value (init_loc, decl, init, origtype);
 
-  if (c_dialect_objc () && (TREE_CODE (decl) == VAR_DECL
-                           || TREE_CODE (decl) == FUNCTION_DECL
+  if (c_dialect_objc () && (VAR_OR_FUNCTION_DECL_P (decl)
                            || TREE_CODE (decl) == FIELD_DECL))
     objc_check_decl (decl);
 
@@ -4368,7 +4772,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
       relayout_decl (decl);
     }
 
-  if (TREE_CODE (decl) == VAR_DECL)
+  if (VAR_P (decl))
     {
       if (init && TREE_CODE (init) == CONSTRUCTOR)
        add_flexible_array_elts_to_size (decl, init);
@@ -4396,8 +4800,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
           TREE_TYPE (decl) = error_mark_node;
         }
 
-      if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
-         && DECL_SIZE (decl) != 0)
+      if (is_global_var (decl) && DECL_SIZE (decl) != 0)
        {
          if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
            constant_expression_warning (DECL_SIZE (decl));
@@ -4432,7 +4835,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
      unless the type is an undefined structure or union.
      If not, it will get done when the type is completed.  */
 
-  if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
+  if (VAR_OR_FUNCTION_DECL_P (decl))
     {
       /* Determine the ELF visibility.  */
       if (TREE_PUBLIC (decl))
@@ -4450,7 +4853,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
             GCC has accepted -- but ignored -- the ASMSPEC in
             this case.  */
          if (!DECL_FILE_SCOPE_P (decl)
-             && TREE_CODE (decl) == VAR_DECL
+             && VAR_P (decl)
              && !C_DECL_REGISTER (decl)
              && !TREE_STATIC (decl))
            warning (0, "ignoring asm-specifier for non-static local "
@@ -4513,8 +4916,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
        {
          /* Recompute the RTL of a local array now
             if it used to be an incomplete type.  */
-         if (was_incomplete
-             && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
+         if (was_incomplete && !is_global_var (decl))
            {
              /* If we used it already as memory, it must stay in memory.  */
              TREE_ADDRESSABLE (decl) = TREE_USED (decl);
@@ -4535,7 +4937,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
     }
 
   /* Install a cleanup (aka destructor) if one was given.  */
-  if (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl))
+  if (VAR_P (decl) && !TREE_STATIC (decl))
     {
       tree attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl));
       if (attr)
@@ -4549,8 +4951,8 @@ finish_decl (tree decl, location_t init_loc, tree init,
          cleanup = build_unary_op (input_location, ADDR_EXPR, decl, 0);
          vec_alloc (v, 1);
          v->quick_push (cleanup);
-         cleanup = build_function_call_vec (DECL_SOURCE_LOCATION (decl),
-                                            cleanup_decl, v, NULL);
+         cleanup = c_build_function_call_vec (DECL_SOURCE_LOCATION (decl),
+                                              vNULL, cleanup_decl, v, NULL);
          vec_free (v);
 
          /* Don't warn about decl unused; the cleanup uses it.  */
@@ -4563,7 +4965,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
     }
 
   if (warn_cxx_compat
-      && TREE_CODE (decl) == VAR_DECL
+      && VAR_P (decl)
       && !DECL_EXTERNAL (decl)
       && DECL_INITIAL (decl) == NULL_TREE)
     {
@@ -4674,7 +5076,9 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const)
     {
       int failure = complete_array_type (&TREE_TYPE (decl),
                                         DECL_INITIAL (decl), true);
-      gcc_assert (!failure);
+      /* If complete_array_type returns 3, it means that the
+         initial value of the compound literal is empty.  Allow it.  */
+      gcc_assert (failure == 0 || failure == 3);
 
       type = TREE_TYPE (decl);
       TREE_TYPE (DECL_INITIAL (decl)) = type;
@@ -4761,8 +5165,10 @@ flexible_array_type_p (tree type)
 \f
 /* Performs sanity checks on the TYPE and WIDTH of the bit-field NAME,
    replacing with appropriate values if they are invalid.  */
+
 static void
-check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
+check_bitfield_type_and_width (location_t loc, tree *type, tree *width,
+                              tree orig_name)
 {
   tree type_mv;
   unsigned int max_width;
@@ -4775,7 +5181,7 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
      field widths.  */
   if (!INTEGRAL_TYPE_P (TREE_TYPE (*width)))
     {
-      error ("bit-field %qs width not an integer constant", name);
+      error_at (loc, "bit-field %qs width not an integer constant", name);
       *width = integer_one_node;
     }
   else
@@ -4784,24 +5190,24 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
        {
          *width = c_fully_fold (*width, false, NULL);
          if (TREE_CODE (*width) == INTEGER_CST)
-           pedwarn (input_location, OPT_Wpedantic,
+           pedwarn (loc, OPT_Wpedantic,
                     "bit-field %qs width not an integer constant expression",
                     name);
        }
       if (TREE_CODE (*width) != INTEGER_CST)
        {
-         error ("bit-field %qs width not an integer constant", name);
+         error_at (loc, "bit-field %qs width not an integer constant", name);
          *width = integer_one_node;
        }
       constant_expression_warning (*width);
       if (tree_int_cst_sgn (*width) < 0)
        {
-         error ("negative width in bit-field %qs", name);
+         error_at (loc, "negative width in bit-field %qs", name);
          *width = integer_one_node;
        }
       else if (integer_zerop (*width) && orig_name)
        {
-         error ("zero width for bit-field %qs", name);
+         error_at (loc, "zero width for bit-field %qs", name);
          *width = integer_one_node;
        }
     }
@@ -4811,36 +5217,36 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
       && TREE_CODE (*type) != BOOLEAN_TYPE
       && TREE_CODE (*type) != ENUMERAL_TYPE)
     {
-      error ("bit-field %qs has invalid type", name);
+      error_at (loc, "bit-field %qs has invalid type", name);
       *type = unsigned_type_node;
     }
 
   type_mv = TYPE_MAIN_VARIANT (*type);
-  if (!in_system_header
+  if (!in_system_header_at (input_location)
       && type_mv != integer_type_node
       && type_mv != unsigned_type_node
       && type_mv != boolean_type_node)
-    pedwarn (input_location, OPT_Wpedantic,
-            "type of bit-field %qs is a GCC extension", name);
+    pedwarn_c90 (loc, OPT_Wpedantic,
+                "type of bit-field %qs is a GCC extension", name);
 
   max_width = TYPE_PRECISION (*type);
 
   if (0 < compare_tree_int (*width, max_width))
     {
-      error ("width of %qs exceeds its type", name);
+      error_at (loc, "width of %qs exceeds its type", name);
       w = max_width;
       *width = build_int_cst (integer_type_node, w);
     }
   else
-    w = tree_low_cst (*width, 1);
+    w = tree_to_uhwi (*width);
 
   if (TREE_CODE (*type) == ENUMERAL_TYPE)
     {
       struct lang_type *lt = TYPE_LANG_SPECIFIC (*type);
       if (!lt
-         || w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
-         || w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
-       warning (0, "%qs is narrower than values of its type", name);
+         || w < tree_int_cst_min_precision (lt->enum_min, TYPE_SIGN (*type))
+         || w < tree_int_cst_min_precision (lt->enum_max, TYPE_SIGN (*type)))
+       warning_at (loc, 0, "%qs is narrower than values of its type", name);
     }
 }
 
@@ -4851,56 +5257,44 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
 static void
 warn_variable_length_array (tree name, tree size)
 {
-  int const_size = TREE_CONSTANT (size);
-
-  if (!flag_isoc99 && pedantic && warn_vla != 0)
+  if (TREE_CONSTANT (size))
     {
-      if (const_size)
-       {
-         if (name)
-           pedwarn (input_location, OPT_Wvla,
+      if (name)
+       pedwarn_c90 (input_location, OPT_Wvla,
                     "ISO C90 forbids array %qE whose size "
-                    "can%'t be evaluated",
-                    name);
-         else
-           pedwarn (input_location, OPT_Wvla, "ISO C90 forbids array whose size "
-                    "can%'t be evaluated");
-       }
+                    "can%'t be evaluated", name);
       else
-       {
-         if (name)
-           pedwarn (input_location, OPT_Wvla,
-                    "ISO C90 forbids variable length array %qE",
-                    name);
-         else
-           pedwarn (input_location, OPT_Wvla, "ISO C90 forbids variable length array");
-       }
+       pedwarn_c90 (input_location, OPT_Wvla, "ISO C90 forbids array "
+                    "whose size can%'t be evaluated");
     }
-  else if (warn_vla > 0)
+  else
     {
-      if (const_size)
-        {
-         if (name)
-           warning (OPT_Wvla,
-                    "the size of array %qE can"
-                    "%'t be evaluated", name);
-         else
-           warning (OPT_Wvla,
-                    "the size of array can %'t be evaluated");
-       }
+      if (name)
+       pedwarn_c90 (input_location, OPT_Wvla,
+                    "ISO C90 forbids variable length array %qE", name);
       else
-       {
-         if (name)
-           warning (OPT_Wvla,
-                    "variable length array %qE is used",
-                    name);
-         else
-           warning (OPT_Wvla,
-                    "variable length array is used");
-       }
+       pedwarn_c90 (input_location, OPT_Wvla, "ISO C90 forbids variable "
+                    "length array");
     }
 }
 
+/* Print warning about defaulting to int if necessary.  */
+
+static void
+warn_defaults_to (location_t location, int opt, const char *gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+  rich_location richloc (location);
+
+  va_start (ap, gmsgid);
+  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
+                       flag_isoc99 ? DK_PEDWARN : DK_WARNING);
+  diagnostic.option_index = opt;
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+}
+
 /* Given declspecs and a declarator,
    determine the name and type of the object declared
    and construct a ..._DECL node for it.
@@ -5066,7 +5460,7 @@ grokdeclarator (const struct c_declarator *declarator,
 
   /* Diagnose defaulting to "int".  */
 
-  if (declspecs->default_int_p && !in_system_header)
+  if (declspecs->default_int_p && !in_system_header_at (input_location))
     {
       /* Issue a warning if this is an ISO C 99 program or if
         -Wreturn-type and this is a function, or if -Wimplicit;
@@ -5077,12 +5471,12 @@ grokdeclarator (const struct c_declarator *declarator,
       else
        {
          if (name)
-           pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wimplicit_int,
-                        "type defaults to %<int%> in declaration of %qE",
-                        name);
+           warn_defaults_to (loc, OPT_Wimplicit_int,
+                             "type defaults to %<int%> in declaration "
+                             "of %qE", name);
          else
-           pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int,
-                        "type defaults to %<int%> in type name");
+           warn_defaults_to (loc, OPT_Wimplicit_int,
+                             "type defaults to %<int%> in type name");
        }
     }
 
@@ -5113,18 +5507,14 @@ grokdeclarator (const struct c_declarator *declarator,
   as2 = TYPE_ADDR_SPACE (element_type);
   address_space = ADDR_SPACE_GENERIC_P (as1)? as2 : as1;
 
-  if (pedantic && !flag_isoc99)
-    {
-      if (constp > 1)
-       pedwarn (loc, OPT_Wpedantic, "duplicate %<const%>");
-      if (restrictp > 1)
-       pedwarn (loc, OPT_Wpedantic, "duplicate %<restrict%>");
-      if (volatilep > 1)
-       pedwarn (loc, OPT_Wpedantic, "duplicate %<volatile%>");
-      if (atomicp > 1)
-       pedwarn (loc, OPT_Wpedantic, "duplicate %<_Atomic%>");
-
-    }
+  if (constp > 1)
+    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<const%>");
+  if (restrictp > 1)
+    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<restrict%>");
+  if (volatilep > 1)
+    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<volatile%>");
+  if (atomicp > 1)
+    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %<_Atomic%>");
 
   if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2)
     error_at (loc, "conflicting named address spaces (%s vs %s)",
@@ -5346,7 +5736,8 @@ grokdeclarator (const struct c_declarator *declarator,
                type = error_mark_node;
              }
 
-           if (pedantic && !in_system_header && flexible_array_type_p (type))
+           if (pedantic && !in_system_header_at (input_location)
+               && flexible_array_type_p (type))
              pedwarn (loc, OPT_Wpedantic,
                       "invalid use of structure with flexible array member");
 
@@ -5438,7 +5829,8 @@ grokdeclarator (const struct c_declarator *declarator,
                    this_size_varies = size_varies = true;
                    warn_variable_length_array (name, size);
                    if (flag_sanitize & SANITIZE_VLA
-                       && decl_context == NORMAL)
+                       && decl_context == NORMAL
+                       && do_ubsan_in_current_function ())
                      {
                        /* Evaluate the array size only once.  */
                        size = c_save_expr (size);
@@ -5524,9 +5916,9 @@ grokdeclarator (const struct c_declarator *declarator,
                    flexible_array_member = (t->kind == cdk_id);
                  }
                if (flexible_array_member
-                   && pedantic && !flag_isoc99 && !in_system_header)
-                 pedwarn (loc, OPT_Wpedantic,
-                          "ISO C90 does not support flexible array members");
+                   && !in_system_header_at (input_location))
+                 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not "
+                              "support flexible array members");
 
                /* ISO C99 Flexible array members are effectively
                   identical to GCC's zero-length array extension.  */
@@ -5560,7 +5952,8 @@ grokdeclarator (const struct c_declarator *declarator,
            /* Complain about arrays of incomplete types.  */
            if (!COMPLETE_TYPE_P (type))
              {
-               error_at (loc, "array type has incomplete element type");
+               error_at (loc, "array type has incomplete element type %qT",
+                         type);
                type = error_mark_node;
              }
            else
@@ -5846,16 +6239,16 @@ grokdeclarator (const struct c_declarator *declarator,
   /* Check the type and width of a bit-field.  */
   if (bitfield)
     {
-      check_bitfield_type_and_width (&type, width, name);
+      check_bitfield_type_and_width (loc, &type, width, name);
       /* C11 makes it implementation-defined (6.7.2.1#5) whether
         atomic types are permitted for bit-fields; we have no code to
         make bit-field accesses atomic, so disallow them.  */
       if (type_quals & TYPE_QUAL_ATOMIC)
        {
          if (name)
-           error ("bit-field %qE has atomic type", name);
+           error_at (loc, "bit-field %qE has atomic type", name);
          else
-           error ("bit-field has atomic type");
+           error_at (loc, "bit-field has atomic type");
          type_quals &= ~TYPE_QUAL_ATOMIC;
        }
     }
@@ -5887,7 +6280,7 @@ grokdeclarator (const struct c_declarator *declarator,
       else if (declspecs->align_log != -1)
        {
          alignas_align = 1U << declspecs->align_log;
-         if (alignas_align < TYPE_ALIGN_UNIT (type))
+         if (alignas_align < min_align_of_type (type))
            {
              if (name)
                error_at (loc, "%<_Alignas%> specifiers cannot reduce "
@@ -5912,7 +6305,7 @@ grokdeclarator (const struct c_declarator *declarator,
       else
        error_at (loc, "size of unnamed array is too large");
       /* If we proceed with the array type as it is, we'll eventually
-        crash in tree_low_cst().  */
+        crash in tree_to_[su]hwi().  */
       type = error_mark_node;
     }
 
@@ -6024,6 +6417,7 @@ grokdeclarator (const struct c_declarator *declarator,
     if (decl_context == PARM)
       {
        tree promoted_type;
+       bool array_parameter_p = false;
 
        /* A parameter declared as an array of T is really a pointer to T.
           One declared as a function is really a pointer to a function.  */
@@ -6045,6 +6439,7 @@ grokdeclarator (const struct c_declarator *declarator,
                          "attributes in parameter array declarator ignored");
 
            size_varies = false;
+           array_parameter_p = true;
          }
        else if (TREE_CODE (type) == FUNCTION_TYPE)
          {
@@ -6069,6 +6464,7 @@ grokdeclarator (const struct c_declarator *declarator,
                           PARM_DECL, declarator->u.id, type);
        if (size_varies)
          C_DECL_VARIABLE_SIZE (decl) = 1;
+       C_ARRAY_PARAMETER (decl) = array_parameter_p;
 
        /* Compute the type actually passed in the parmlist,
           for the case where there is no prototype.
@@ -6109,6 +6505,19 @@ grokdeclarator (const struct c_declarator *declarator,
              error_at (loc, "unnamed field has incomplete type");
            type = error_mark_node;
          }
+       else if (TREE_CODE (type) == ARRAY_TYPE
+                && TYPE_DOMAIN (type) == NULL_TREE)
+         {
+           /* We have a flexible array member through a typedef.
+              Set suitable range.  Whether this is a correct position
+              for a flexible array member will be determined elsewhere.  */
+           if (!in_system_header_at (input_location))
+             pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not "
+                          "support flexible array members");
+           type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
+           TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node,
+                                                  NULL_TREE);
+         }
        type = c_build_qualified_type (type, type_quals);
        decl = build_decl (declarator->id_loc,
                           FIELD_DECL, declarator->u.id, type);
@@ -6205,15 +6614,12 @@ grokdeclarator (const struct c_declarator *declarator,
              DECL_DECLARED_INLINE_P (decl) = 1;
            if (declspecs->noreturn_p)
              {
-               if (!flag_isoc11)
-                 {
-                   if (flag_isoc99)
-                     pedwarn (loc, OPT_Wpedantic,
+               if (flag_isoc99)
+                 pedwarn_c99 (loc, OPT_Wpedantic,
                               "ISO C99 does not support %<_Noreturn%>");
-                   else
-                     pedwarn (loc, OPT_Wpedantic,
+               else
+                 pedwarn_c99 (loc, OPT_Wpedantic,
                               "ISO C90 does not support %<_Noreturn%>");
-                 }
                TREE_THIS_VOLATILE (decl) = 1;
              }
          }
@@ -6239,7 +6645,7 @@ grokdeclarator (const struct c_declarator *declarator,
 
            if (global_decl
                && global_decl != visible_decl
-               && TREE_CODE (global_decl) == VAR_DECL
+               && VAR_P (global_decl)
                && !TREE_PUBLIC (global_decl))
              error_at (loc, "variable previously declared %<static%> "
                        "redeclared %<extern%>");
@@ -6277,7 +6683,7 @@ grokdeclarator (const struct c_declarator *declarator,
          }
 
        if (threadp)
-         DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+         set_decl_tls_model (decl, decl_default_tls_model (decl));
       }
 
     if ((storage_class == csc_extern
@@ -6318,7 +6724,7 @@ grokdeclarator (const struct c_declarator *declarator,
        will be ignored, and would even crash the compiler.
        Of course, this only makes sense on  VAR,PARM, and RESULT decl's.   */
     if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl))
-       && (TREE_CODE (decl) == VAR_DECL ||  TREE_CODE (decl) == PARM_DECL
+       && (VAR_P (decl) ||  TREE_CODE (decl) == PARM_DECL
          || TREE_CODE (decl) == RESULT_DECL))
       {
        /* It is not an error for a structure with volatile fields to
@@ -6336,7 +6742,7 @@ grokdeclarator (const struct c_declarator *declarator,
     gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl));
 
     if (warn_cxx_compat
-       && TREE_CODE (decl) == VAR_DECL
+       && VAR_P (decl)
        && TREE_PUBLIC (decl)
        && TREE_STATIC (decl)
        && (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
@@ -6378,7 +6784,8 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
       error ("%<[*]%> not allowed in other than function prototype scope");
     }
 
-  if (arg_types == 0 && !funcdef_flag && !in_system_header)
+  if (arg_types == 0 && !funcdef_flag
+      && !in_system_header_at (input_location))
     warning (OPT_Wstrict_prototypes,
             "function declaration isn%'t a prototype");
 
@@ -6505,7 +6912,6 @@ get_parm_info (bool ellipsis, tree expr)
   tree types    = 0;
   tree others   = 0;
 
-  static bool explained_incomplete_types = false;
   bool gave_void_only_once_err = false;
 
   arg_info->had_vla_unspec = current_scope->had_vla_unspec;
@@ -6608,19 +7014,16 @@ get_parm_info (bool ellipsis, tree expr)
            {
              if (b->id)
                /* The %s will be one of 'struct', 'union', or 'enum'.  */
-               warning (0, "%<%s %E%> declared inside parameter list",
-                        keyword, b->id);
+               warning_at (input_location, 0,
+                           "%<%s %E%> declared inside parameter list"
+                           " will not be visible outside of this definition or"
+                           " declaration", keyword, b->id);
              else
                /* The %s will be one of 'struct', 'union', or 'enum'.  */
-               warning (0, "anonymous %s declared inside parameter list",
-                        keyword);
-
-             if (!explained_incomplete_types)
-               {
-                 warning (0, "its scope is only this definition or declaration,"
-                          " which is probably not what you want");
-                 explained_incomplete_types = true;
-               }
+               warning_at (input_location, 0,
+                           "anonymous %s declared inside parameter list"
+                           " will not be visible outside of this definition or"
+                           " declaration", keyword);
            }
 
          tag.id = b->id;
@@ -6692,7 +7095,7 @@ parser_xref_tag (location_t loc, enum tree_code code, tree name)
   /* If a cross reference is requested, look up the type
      already defined for this tag and return it.  */
 
-  ref = lookup_tag (code, name, 0, &refloc);
+  ref = lookup_tag (code, name, false, &refloc);
   /* If this is the right type of tag, return what we found.
      (This reference will be shadowed by shadow_tag later if appropriate.)
      If this is the wrong type of tag, do not return it.  If it was the
@@ -6796,7 +7199,7 @@ start_struct (location_t loc, enum tree_code code, tree name,
   location_t refloc = UNKNOWN_LOCATION;
 
   if (name != NULL_TREE)
-    ref = lookup_tag (code, name, 1, &refloc);
+    ref = lookup_tag (code, name, true, &refloc);
   if (ref && TREE_CODE (ref) == code)
     {
       if (TYPE_SIZE (ref))
@@ -6919,15 +7322,12 @@ grokfield (location_t loc,
          pedwarn (loc, 0, "declaration does not declare anything");
          return NULL_TREE;
        }
-      if (!flag_isoc11)
-       {
-         if (flag_isoc99)
-           pedwarn (loc, OPT_Wpedantic,
+      if (flag_isoc99)
+       pedwarn_c99 (loc, OPT_Wpedantic,
                     "ISO C99 doesn%'t support unnamed structs/unions");
-         else
-           pedwarn (loc, OPT_Wpedantic,
+      else
+       pedwarn_c99 (loc, OPT_Wpedantic,
                     "ISO C90 doesn%'t support unnamed structs/unions");
-       }
     }
 
   value = grokdeclarator (declarator, declspecs, FIELD, false,
@@ -7007,7 +7407,7 @@ is_duplicate_field (tree x, tree y)
 
 static void
 detect_field_duplicates_hash (tree fieldlist,
-                             hash_table <pointer_hash <tree_node> > htab)
+                             hash_table<nofree_ptr_hash <tree_node> > *htab)
 {
   tree x, y;
   tree_node **slot;
@@ -7015,7 +7415,7 @@ detect_field_duplicates_hash (tree fieldlist,
   for (x = fieldlist; x ; x = DECL_CHAIN (x))
     if ((y = DECL_NAME (x)) != 0)
       {
-       slot = htab.find_slot (y, INSERT);
+       slot = htab->find_slot (y, INSERT);
        if (*slot)
          {
            error ("duplicate member %q+D", x);
@@ -7035,7 +7435,7 @@ detect_field_duplicates_hash (tree fieldlist,
            && TREE_CODE (TYPE_NAME (TREE_TYPE (x))) == TYPE_DECL)
          {
            tree xn = DECL_NAME (TYPE_NAME (TREE_TYPE (x)));
-           slot = htab.find_slot (xn, INSERT);
+           slot = htab->find_slot (xn, INSERT);
            if (*slot)
              error ("duplicate member %q+D", TYPE_NAME (TREE_TYPE (x)));
            *slot = xn;
@@ -7107,23 +7507,31 @@ detect_field_duplicates (tree fieldlist)
     }
   else
     {
-      hash_table <pointer_hash <tree_node> > htab;
-      htab.create (37);
-
-      detect_field_duplicates_hash (fieldlist, htab);
-      htab.dispose ();
+      hash_table<nofree_ptr_hash <tree_node> > htab (37);
+      detect_field_duplicates_hash (fieldlist, &htab);
     }
 }
 
 /* Finish up struct info used by -Wc++-compat.  */
 
 static void
-warn_cxx_compat_finish_struct (tree fieldlist)
+warn_cxx_compat_finish_struct (tree fieldlist, enum tree_code code,
+                              location_t record_loc)
 {
   unsigned int ix;
   tree x;
   struct c_binding *b;
 
+  if (fieldlist == NULL_TREE)
+    {
+      if (code == RECORD_TYPE)
+       warning_at (record_loc, OPT_Wc___compat,
+                   "empty struct has size 0 in C, size 1 in C++");
+      else
+       warning_at (record_loc, OPT_Wc___compat,
+                   "empty union has size 0 in C, size 1 in C++");
+    }
+
   /* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
      the current struct.  We do this now at the end of the struct
      because the flag is used to issue visibility warnings, and we
@@ -7141,17 +7549,17 @@ warn_cxx_compat_finish_struct (tree fieldlist)
   if (!struct_parse_info->typedefs_seen.is_empty ()
       && fieldlist != NULL_TREE)
     {
-      /* Use a pointer_set using the name of the typedef.  We can use
-        a pointer_set because identifiers are interned.  */
-      struct pointer_set_t *tset = pointer_set_create ();
+      /* Use a hash_set<tree> using the name of the typedef.  We can use
+        a hash_set<tree> because identifiers are interned.  */
+      hash_set<tree> tset;
 
       FOR_EACH_VEC_ELT (struct_parse_info->typedefs_seen, ix, x)
-       pointer_set_insert (tset, DECL_NAME (x));
+       tset.add (DECL_NAME (x));
 
       for (x = fieldlist; x != NULL_TREE; x = DECL_CHAIN (x))
        {
          if (DECL_NAME (x) != NULL_TREE
-             && pointer_set_contains (tset, DECL_NAME (x)))
+             && tset.contains (DECL_NAME (x)))
            {
              warning_at (DECL_SOURCE_LOCATION (x), OPT_Wc___compat,
                          ("using %qD as both field and typedef name is "
@@ -7161,8 +7569,6 @@ warn_cxx_compat_finish_struct (tree fieldlist)
                 the typedef name is used.  */
            }
        }
-
-      pointer_set_destroy (tset);
     }
 
   /* For each field which has a binding and which was not defined in
@@ -7263,7 +7669,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
 
       if (DECL_INITIAL (x))
        {
-         unsigned HOST_WIDE_INT width = tree_low_cst (DECL_INITIAL (x), 1);
+         unsigned HOST_WIDE_INT width = tree_to_uhwi (DECL_INITIAL (x));
          DECL_SIZE (x) = bitsize_int (width);
          DECL_BIT_FIELD (x) = 1;
          SET_DECL_C_BIT_FIELD (x);
@@ -7334,7 +7740,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
          && TREE_TYPE (*fieldlistp) != error_mark_node)
        {
          unsigned HOST_WIDE_INT width
-           = tree_low_cst (DECL_INITIAL (*fieldlistp), 1);
+           = tree_to_uhwi (DECL_INITIAL (*fieldlistp));
          tree type = TREE_TYPE (*fieldlistp);
          if (width != TYPE_PRECISION (type))
            {
@@ -7378,8 +7784,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
          ensure that this lives as long as the rest of the struct decl.
          All decls in an inline function need to be saved.  */
 
-       space = ggc_alloc_cleared_lang_type (sizeof (struct lang_type));
-       space2 = ggc_alloc_sorted_fields_type
+       space = ggc_cleared_alloc<struct lang_type> ();
+       space2 = (sorted_fields_type *) ggc_internal_alloc
          (sizeof (struct sorted_fields_type) + len * sizeof (tree));
 
        len = 0;
@@ -7424,10 +7830,18 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
     }
 
   /* If this structure or union completes the type of any previous
-     variable declaration, lay it out and output its rtl.  */
-  for (x = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
-       x;
-       x = TREE_CHAIN (x))
+     variable declaration, lay it out and output its rtl.
+
+     Note: C_TYPE_INCOMPLETE_VARS overloads TYPE_VFIELD which is used
+     in dwarf2out via rest_of_decl_compilation below and means
+     something totally different.  Since we will be clearing
+     C_TYPE_INCOMPLETE_VARS shortly after we iterate through them,
+     clear it ahead of time and avoid problems in dwarf2out.  Ideally,
+     C_TYPE_INCOMPLETE_VARS should use some language specific
+     node.  */
+  tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
+  C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0;
+  for (x = incomplete_vars; x; x = TREE_CHAIN (x))
     {
       tree decl = TREE_VALUE (x);
       if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
@@ -7440,7 +7854,6 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
          rest_of_decl_compilation (decl, toplevel, 0);
        }
     }
-  C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0;
 
   /* Update type location to the one of the definition, instead of e.g.
      a forward declaration.  */
@@ -7458,7 +7871,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
                          DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
 
   if (warn_cxx_compat)
-    warn_cxx_compat_finish_struct (fieldlist);
+    warn_cxx_compat_finish_struct (fieldlist, TREE_CODE (t), loc);
 
   struct_parse_info->struct_types.release ();
   struct_parse_info->fields.release ();
@@ -7505,9 +7918,9 @@ start_enum (location_t loc, struct c_enum_contents *the_enum, tree name)
      forward reference.  */
 
   if (name != NULL_TREE)
-    enumtype = lookup_tag (ENUMERAL_TYPE, name, 1, &enumloc);
+    enumtype = lookup_tag (ENUMERAL_TYPE, name, true, &enumloc);
 
-  if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE)
+  if (enumtype == NULL_TREE || TREE_CODE (enumtype) != ENUMERAL_TYPE)
     {
       enumtype = make_node (ENUMERAL_TYPE);
       pushtag (loc, name, enumtype);
@@ -7534,7 +7947,8 @@ start_enum (location_t loc, struct c_enum_contents *the_enum, tree name)
   the_enum->enum_overflow = 0;
 
   if (flag_short_enums)
-    TYPE_PACKED (enumtype) = 1;
+    for (tree v = TYPE_MAIN_VARIANT (enumtype); v; v = TYPE_NEXT_VARIANT (v))
+      TYPE_PACKED (v) = 1;
 
   /* FIXME: This will issue a warning for a use of a type defined
      within sizeof in a statement expr.  This is not terribly serious
@@ -7560,7 +7974,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
 {
   tree pair, tem;
   tree minnode = 0, maxnode = 0;
-  int precision, unsign;
+  int precision;
+  signop sign;
   bool toplevel = (file_scope == current_scope);
   struct lang_type *lt;
 
@@ -7587,13 +8002,13 @@ finish_enum (tree enumtype, tree values, tree attributes)
      as one of the integral types - the narrowest one that fits, except
      that normally we only go as narrow as int - and signed iff any of
      the values are negative.  */
-  unsign = (tree_int_cst_sgn (minnode) >= 0);
-  precision = MAX (tree_int_cst_min_precision (minnode, unsign),
-                  tree_int_cst_min_precision (maxnode, unsign));
+  sign = (tree_int_cst_sgn (minnode) >= 0) ? UNSIGNED : SIGNED;
+  precision = MAX (tree_int_cst_min_precision (minnode, sign),
+                  tree_int_cst_min_precision (maxnode, sign));
 
   if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
     {
-      tem = c_common_type_for_size (precision, unsign);
+      tem = c_common_type_for_size (precision, sign == UNSIGNED ? 1 : 0);
       if (tem == NULL)
        {
          warning (0, "enumeration values exceed range of largest integer");
@@ -7601,16 +8016,18 @@ finish_enum (tree enumtype, tree values, tree attributes)
        }
     }
   else
-    tem = unsign ? unsigned_type_node : integer_type_node;
+    tem = sign == UNSIGNED ? unsigned_type_node : integer_type_node;
 
   TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
   TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
   TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem);
+  TYPE_ALIGN (enumtype) = TYPE_ALIGN (tem);
   TYPE_SIZE (enumtype) = 0;
 
-  /* If the precision of the type was specific with an attribute and it
+  /* If the precision of the type was specified with an attribute and it
      was too small, give an error.  Otherwise, use it.  */
-  if (TYPE_PRECISION (enumtype))
+  if (TYPE_PRECISION (enumtype)
+      && lookup_attribute ("mode", attributes))
     {
       if (precision > TYPE_PRECISION (enumtype))
        error ("specified mode too small for enumeral values");
@@ -7659,7 +8076,7 @@ finish_enum (tree enumtype, tree values, tree attributes)
 
   /* Record the min/max values so that we can warn about bit-field
      enumerations that are too small for the values.  */
-  lt = ggc_alloc_cleared_lang_type (sizeof (struct lang_type));
+  lt = ggc_cleared_alloc<struct lang_type> ();
   lt->enum_min = minnode;
   lt->enum_max = maxnode;
   TYPE_LANG_SPECIFIC (enumtype) = lt;
@@ -7777,7 +8194,7 @@ build_enumerator (location_t decl_loc, location_t loc,
 
   /* Set basis for default for next value.  */
   the_enum->enum_next_value
-    = build_binary_op (EXPR_LOC_OR_HERE (value),
+    = build_binary_op (EXPR_LOC_OR_LOC (value, input_location),
                       PLUS_EXPR, value, integer_one_node, 0);
   the_enum->enum_overflow = tree_int_cst_lt (the_enum->enum_next_value, value);
 
@@ -7831,6 +8248,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
 
   decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL,
                          &attributes, NULL, NULL, DEPRECATED_NORMAL);
+  invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
 
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
@@ -7872,9 +8290,10 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
     }
 
   if (warn_about_return_type)
-    pedwarn_c99 (loc, flag_isoc99 ? 0
-                : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int),
-                "return type defaults to %<int%>");
+    warn_defaults_to (loc, flag_isoc99 ? OPT_Wimplicit_int
+                          : (warn_return_type ? OPT_Wreturn_type
+                             : OPT_Wimplicit_int),
+                     "return type defaults to %<int%>");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
      error_mark_node is replaced below (in pop_scope) with the BLOCK.  */
@@ -7898,6 +8317,12 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
          && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
                        TREE_TYPE (TREE_TYPE (old_decl))))
        {
+         if (stdarg_p (TREE_TYPE (old_decl)))
+           {
+             warning_at (loc, 0, "%q+D defined as variadic function "
+                         "without prototype", decl1);
+             locate_old_decl (old_decl);
+           }
          TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl),
                                              TREE_TYPE (decl1));
          current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl);
@@ -7950,7 +8375,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
           && old_decl != error_mark_node
           && TREE_PUBLIC (decl1)
           && !MAIN_NAME_P (DECL_NAME (decl1))
-          && C_DECL_ISNT_PROTOTYPE (old_decl))
+          && C_DECL_ISNT_PROTOTYPE (old_decl)
+          && !DECL_DECLARED_INLINE_P (decl1))
     warning_at (loc, OPT_Wmissing_prototypes,
                "no previous prototype for %qD", decl1);
   /* Optionally warn of any def with no previous prototype
@@ -7966,7 +8392,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   else if (warn_missing_declarations
           && TREE_PUBLIC (decl1)
           && old_decl == 0
-          && !MAIN_NAME_P (DECL_NAME (decl1)))
+          && !MAIN_NAME_P (DECL_NAME (decl1))
+          && !DECL_DECLARED_INLINE_P (decl1))
     warning_at (loc, OPT_Wmissing_declarations,
                "no previous declaration for %qD",
                decl1);
@@ -7998,6 +8425,9 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
       if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
          != integer_type_node)
        pedwarn (loc, OPT_Wmain, "return type of %qD is not %<int%>", decl1);
+      else if (TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (decl1))))
+       pedwarn (loc, OPT_Wmain, "%<_Atomic%>-qualified return type of %qD",
+                decl1);
 
       check_main_parameter_types (decl1);
 
@@ -8051,7 +8481,8 @@ store_parm_decls_newstyle (tree fndecl, const struct c_arg_info *arg_info)
      warning if we got here because ARG_INFO_TYPES was error_mark_node
      (this happens when a function definition has just an ellipsis in
      its parameter list).  */
-  else if (!in_system_header && !current_function_scope
+  else if (!in_system_header_at (input_location)
+          && !current_function_scope
           && arg_info->types != error_mark_node)
     warning_at (DECL_SOURCE_LOCATION (fndecl), OPT_Wtraditional,
                "traditional C rejects ISO C style function definitions");
@@ -8103,9 +8534,9 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
   struct c_binding *b;
   tree parm, decl, last;
   tree parmids = arg_info->parms;
-  struct pointer_set_t *seen_args = pointer_set_create ();
+  hash_set<tree> seen_args;
 
-  if (!in_system_header)
+  if (!in_system_header_at (input_location))
     warning_at (DECL_SOURCE_LOCATION (fndecl),
                OPT_Wold_style_definition, "old-style function definition");
 
@@ -8134,7 +8565,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
                      "%qD declared as a non-parameter", decl);
          /* If the declaration is already marked, we have a duplicate
             name.  Complain and ignore the duplicate.  */
-         else if (pointer_set_contains (seen_args, decl))
+         else if (seen_args.contains (decl))
            {
              error_at (DECL_SOURCE_LOCATION (decl),
                        "multiple parameters named %qD", decl);
@@ -8175,7 +8606,8 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
 
          if (flag_isoc99)
            pedwarn (DECL_SOURCE_LOCATION (decl),
-                    0, "type of %qD defaults to %<int%>", decl);
+                    OPT_Wimplicit_int, "type of %qD defaults to %<int%>",
+                    decl);
          else
            warning_at (DECL_SOURCE_LOCATION (decl),
                        OPT_Wmissing_parameter_type,
@@ -8183,7 +8615,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
        }
 
       TREE_PURPOSE (parm) = decl;
-      pointer_set_insert (seen_args, decl);
+      seen_args.add (decl);
     }
 
   /* Now examine the parms chain for incomplete declarations
@@ -8203,7 +8635,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
          TREE_TYPE (parm) = error_mark_node;
        }
 
-      if (!pointer_set_contains (seen_args, parm))
+      if (!seen_args.contains (parm))
        {
          error_at (DECL_SOURCE_LOCATION (parm),
                    "declaration for parameter %qD but no such parameter",
@@ -8238,8 +8670,6 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
       DECL_CHAIN (last) = 0;
     }
 
-  pointer_set_destroy (seen_args);
-
   /* If there was a previous prototype,
      set the DECL_ARG_TYPE of each argument according to
      the type previously specified, and report any mismatches.  */
@@ -8386,6 +8816,21 @@ store_parm_decls_from (struct c_arg_info *arg_info)
   store_parm_decls ();
 }
 
+/* Called by walk_tree to look for and update context-less labels.  */
+
+static tree
+set_labels_context_r (tree *tp, int *walk_subtrees, void *data)
+{
+  if (TREE_CODE (*tp) == LABEL_EXPR
+      && DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) == NULL_TREE)
+    {
+      DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) = static_cast<tree>(data);
+      *walk_subtrees = 0;
+    }
+
+  return NULL_TREE;
+}
+
 /* Store the parameter declarations into the current function declaration.
    This is called after parsing the parameter declarations, before
    digesting the body of the function.
@@ -8428,7 +8873,7 @@ store_parm_decls (void)
   allocate_struct_function (fndecl, false);
 
   if (warn_unused_local_typedefs)
-    cfun->language = ggc_alloc_cleared_language_function ();
+    cfun->language = ggc_cleared_alloc<language_function> ();
 
   /* Begin the statement tree for this function.  */
   DECL_SAVED_TREE (fndecl) = push_stmt_list ();
@@ -8440,7 +8885,21 @@ store_parm_decls (void)
      thus won't naturally see the SAVE_EXPR containing the increment.  All
      other pending sizes would be handled by gimplify_parameters.  */
   if (arg_info->pending_sizes)
-    add_stmt (arg_info->pending_sizes);
+    {
+      /* In very special circumstances, e.g. for code like
+          _Atomic int i = 5;
+          void f (int a[i += 2]) {}
+        we need to execute the atomic assignment on function entry.
+        But in this case, it is not just a straight store, it has the
+        op= form, which means that build_atomic_assign has generated
+        gotos, labels, etc.  Because at that time the function decl
+        for F has not been created yet, those labels do not have any
+        function context.  But we have the fndecl now, so update the
+        labels accordingly.  gimplify_expr would crash otherwise.  */
+      walk_tree_without_duplicates (&arg_info->pending_sizes,
+                                   set_labels_context_r, fndecl);
+      add_stmt (arg_info->pending_sizes);
+    }
 }
 
 /* Store PARM_DECLs in PARMS into scope temporarily.  Used for
@@ -8472,7 +8931,8 @@ temp_pop_parm_decls (void)
   current_scope->bindings = NULL;
   for (; b; b = free_binding_and_advance (b))
     {
-      gcc_assert (TREE_CODE (b->decl) == PARM_DECL);
+      gcc_assert (TREE_CODE (b->decl) == PARM_DECL
+                 || b->decl == error_mark_node);
       gcc_assert (I_SYMBOL_BINDING (b->id) == b);
       I_SYMBOL_BINDING (b->id) = b->shadowed;
       if (b->shadowed && b->shadowed->u.type)
@@ -8585,6 +9045,10 @@ finish_function (void)
      function.  */
   maybe_warn_unused_local_typedefs ();
 
+  /* Possibly warn about unused parameters.  */
+  if (warn_unused_parameter)
+    do_warn_unused_parameter (fndecl);
+
   /* Store the end of the function, so that we get good line number
      info for the epilogue.  */
   cfun->function_end_locus = input_location;
@@ -8611,19 +9075,19 @@ finish_function (void)
 
          /* ??? Objc emits functions after finalizing the compilation unit.
             This should be cleaned up later and this conditional removed.  */
-         if (cgraph_global_info_ready)
+         if (symtab->global_info_ready)
            {
-             cgraph_add_new_function (fndecl, false);
+             cgraph_node::add_new_function (fndecl, false);
              return;
            }
-         cgraph_finalize_function (fndecl, false);
+         cgraph_node::finalize_function (fndecl, false);
        }
       else
        {
          /* Register this function with cgraph just far enough to get it
            added to our parent's nested function list.  Handy, since the
            C front end doesn't have such a list.  */
-         (void) cgraph_get_create_node (fndecl);
+         (void) cgraph_node::get_create (fndecl);
        }
     }
 
@@ -8640,6 +9104,7 @@ finish_function (void)
      It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
      tree_rest_of_compilation.  */
   set_cfun (NULL);
+  invoke_plugin_callbacks (PLUGIN_FINISH_PARSE_FUNCTION, current_function_decl);
   current_function_decl = NULL;
 }
 \f
@@ -8752,7 +9217,7 @@ c_push_function_context (void)
   /* cfun->language might have been already allocated by the use of
      -Wunused-local-typedefs.  In that case, just re-use it.  */
   if (p == NULL)
-    cfun->language = p = ggc_alloc_cleared_language_function ();
+    cfun->language = p = ggc_cleared_alloc<language_function> ();
 
   p->base.x_stmt_tree = c_stmt_tree;
   c_stmt_tree.x_cur_stmt_list = vec_safe_copy (c_stmt_tree.x_cur_stmt_list);
@@ -9054,8 +9519,8 @@ declspecs_add_qual (source_location loc,
     default:
       gcc_unreachable ();
     }
-  if (dupe && !flag_isoc99)
-    pedwarn (loc, OPT_Wpedantic, "duplicate %qE", qual);
+  if (dupe)
+    pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %qE", qual);
   return specs;
 }
 
@@ -9115,14 +9580,19 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                error_at (loc,
                          ("both %<long%> and %<short%> in "
                           "declaration specifiers"));
+             else if (specs->typespec_word == cts_auto_type)
+               error_at (loc,
+                         ("both %<long%> and %<__auto_type%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_void)
                error_at (loc,
                          ("both %<long%> and %<void%> in "
                           "declaration specifiers"));
-             else if (specs->typespec_word == cts_int128)
+             else if (specs->typespec_word == cts_int_n)
                  error_at (loc,
-                           ("both %<long%> and %<__int128%> in "
-                            "declaration specifiers"));
+                           ("both %<long%> and %<__int%d%> in "
+                            "declaration specifiers"),
+                           int_n_data[specs->int_n_idx].bitsize);
              else if (specs->typespec_word == cts_bool)
                error_at (loc,
                          ("both %<long%> and %<_Bool%> in "
@@ -9159,14 +9629,19 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                error_at (loc,
                          ("both %<long%> and %<short%> in "
                           "declaration specifiers"));
+             else if (specs->typespec_word == cts_auto_type)
+               error_at (loc,
+                         ("both %<short%> and %<__auto_type%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_void)
                error_at (loc,
                          ("both %<short%> and %<void%> in "
                           "declaration specifiers"));
-             else if (specs->typespec_word == cts_int128)
+             else if (specs->typespec_word == cts_int_n)
                error_at (loc,
-                         ("both %<short%> and %<__int128%> in "
-                          "declaration specifiers"));
+                         ("both %<short%> and %<__int%d%> in "
+                          "declaration specifiers"),
+                         int_n_data[specs->int_n_idx].bitsize);
              else if (specs->typespec_word == cts_bool)
                error_at (loc,
                          ("both %<short%> and %<_Bool%> in "
@@ -9207,6 +9682,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                error_at (loc,
                          ("both %<signed%> and %<unsigned%> in "
                           "declaration specifiers"));
+             else if (specs->typespec_word == cts_auto_type)
+               error_at (loc,
+                         ("both %<signed%> and %<__auto_type%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_void)
                error_at (loc,
                          ("both %<signed%> and %<void%> in "
@@ -9247,6 +9726,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                error_at (loc,
                          ("both %<signed%> and %<unsigned%> in "
                           "declaration specifiers"));
+             else if (specs->typespec_word == cts_auto_type)
+               error_at (loc,
+                         ("both %<unsigned%> and %<__auto_type%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_void)
                error_at (loc,
                          ("both %<unsigned%> and %<void%> in "
@@ -9283,10 +9766,14 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
              break;
            case RID_COMPLEX:
              dupe = specs->complex_p;
-             if (!flag_isoc99 && !in_system_header_at (loc))
-               pedwarn (loc, OPT_Wpedantic,
-                        "ISO C90 does not support complex types");
-             if (specs->typespec_word == cts_void)
+             if (!in_system_header_at (loc))
+               pedwarn_c90 (loc, OPT_Wpedantic,
+                            "ISO C90 does not support complex types");
+             if (specs->typespec_word == cts_auto_type)
+               error_at (loc,
+                         ("both %<complex%> and %<__auto_type%> in "
+                          "declaration specifiers"));
+             else if (specs->typespec_word == cts_void)
                error_at (loc,
                          ("both %<complex%> and %<void%> in "
                           "declaration specifiers"));
@@ -9328,12 +9815,17 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
              dupe = specs->saturating_p;
              pedwarn (loc, OPT_Wpedantic,
                       "ISO C does not support saturating types");
-             if (specs->typespec_word == cts_int128)
+             if (specs->typespec_word == cts_int_n)
                {
                  error_at (loc,
-                           ("both %<_Sat%> and %<__int128%> in "
-                            "declaration specifiers"));
+                           ("both %<_Sat%> and %<__int%d%> in "
+                            "declaration specifiers"),
+                           int_n_data[specs->int_n_idx].bitsize);
                }
+             else if (specs->typespec_word == cts_auto_type)
+               error_at (loc,
+                         ("both %<_Sat%> and %<__auto_type%> in "
+                          "declaration specifiers"));
              else if (specs->typespec_word == cts_void)
                error_at (loc,
                          ("both %<_Sat%> and %<void%> in "
@@ -9392,7 +9884,8 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
       else
        {
          /* "void", "_Bool", "char", "int", "float", "double", "_Decimal32",
-            "__int128", "_Decimal64", "_Decimal128", "_Fract" or "_Accum".  */
+            "__intN", "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
+            "__auto_type".  */
          if (specs->typespec_word != cts_none)
            {
              error_at (loc,
@@ -9401,31 +9894,69 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
            }
          switch (i)
            {
-           case RID_INT128:
-             if (int128_integer_type_node == NULL_TREE)
+           case RID_AUTO_TYPE:
+             if (specs->long_p)
+               error_at (loc,
+                         ("both %<long%> and %<__auto_type%> in "
+                          "declaration specifiers"));
+             else if (specs->short_p)
+               error_at (loc,
+                         ("both %<short%> and %<__auto_type%> in "
+                          "declaration specifiers"));
+             else if (specs->signed_p)
+               error_at (loc,
+                         ("both %<signed%> and %<__auto_type%> in "
+                          "declaration specifiers"));
+             else if (specs->unsigned_p)
+               error_at (loc,
+                         ("both %<unsigned%> and %<__auto_type%> in "
+                          "declaration specifiers"));
+             else if (specs->complex_p)
+               error_at (loc,
+                         ("both %<complex%> and %<__auto_type%> in "
+                          "declaration specifiers"));
+             else if (specs->saturating_p)
+               error_at (loc,
+                         ("both %<_Sat%> and %<__auto_type%> in "
+                          "declaration specifiers"));
+             else
                {
-                 error_at (loc, "%<__int128%> is not supported for this target");
-                 return specs;
+                 specs->typespec_word = cts_auto_type;
+                 specs->locations[cdw_typespec] = loc;
                }
-             if (!in_system_header)
+             return specs;
+           case RID_INT_N_0:
+           case RID_INT_N_1:
+           case RID_INT_N_2:
+           case RID_INT_N_3:
+             specs->int_n_idx = i - RID_INT_N_0;
+             if (!in_system_header_at (input_location))
                pedwarn (loc, OPT_Wpedantic,
-                        "ISO C does not support %<__int128%> type");
+                        "ISO C does not support %<__int%d%> types",
+                        int_n_data[specs->int_n_idx].bitsize);
 
              if (specs->long_p)
                error_at (loc,
-                         ("both %<__int128%> and %<long%> in "
-                          "declaration specifiers"));
+                         ("both %<__int%d%> and %<long%> in "
+                          "declaration specifiers"),
+                         int_n_data[specs->int_n_idx].bitsize);
              else if (specs->saturating_p)
                error_at (loc,
-                         ("both %<_Sat%> and %<__int128%> in "
-                          "declaration specifiers"));
+                         ("both %<_Sat%> and %<__int%d%> in "
+                          "declaration specifiers"),
+                         int_n_data[specs->int_n_idx].bitsize);
              else if (specs->short_p)
                error_at (loc,
-                         ("both %<__int128%> and %<short%> in "
-                          "declaration specifiers"));
+                         ("both %<__int%d%> and %<short%> in "
+                          "declaration specifiers"),
+                         int_n_data[specs->int_n_idx].bitsize);
+             else if (! int_n_enabled_p [specs->int_n_idx])
+               error_at (loc,
+                         "%<__int%d%> is not supported on this target",
+                         int_n_data[specs->int_n_idx].bitsize);
              else
                {
-                 specs->typespec_word = cts_int128;
+                 specs->typespec_word = cts_int_n;
                  specs->locations[cdw_typespec] = loc;
                }
              return specs;
@@ -9461,6 +9992,9 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                }
              return specs;
            case RID_BOOL:
+             if (!in_system_header_at (loc))
+               pedwarn_c90 (loc, OPT_Wpedantic,
+                            "ISO C90 does not support boolean types");
              if (specs->long_p)
                error_at (loc,
                          ("both %<long%> and %<_Bool%> in "
@@ -9790,14 +10324,14 @@ declspecs_add_scspec (source_location loc,
             identifier in the implementation namespace; only diagnose
             it for the C11 spelling because of existing code using
             the other spelling.  */
-         if (!flag_isoc11 && !specs->thread_gnu_p)
+         if (!specs->thread_gnu_p)
            {
              if (flag_isoc99)
-               pedwarn (loc, OPT_Wpedantic,
-                        "ISO C99 does not support %qE", scspec);
+               pedwarn_c99 (loc, OPT_Wpedantic,
+                            "ISO C99 does not support %qE", scspec);
              else
-               pedwarn (loc, OPT_Wpedantic,
-                        "ISO C90 does not support %qE", scspec);
+               pedwarn_c99 (loc, OPT_Wpedantic,
+                            "ISO C90 does not support %qE", scspec);
            }
          specs->locations[cdw_thread] = loc;
        }
@@ -9956,6 +10490,12 @@ finish_declspecs (struct c_declspecs *specs)
   /* Now compute the actual type.  */
   switch (specs->typespec_word)
     {
+    case cts_auto_type:
+      gcc_assert (!specs->long_p && !specs->short_p
+                 && !specs->signed_p && !specs->unsigned_p
+                 && !specs->complex_p);
+      /* Type to be filled in later.  */
+      break;
     case cts_void:
       gcc_assert (!specs->long_p && !specs->short_p
                  && !specs->signed_p && !specs->unsigned_p
@@ -9984,12 +10524,12 @@ finish_declspecs (struct c_declspecs *specs)
          specs->type = build_complex_type (specs->type);
        }
       break;
-    case cts_int128:
+    case cts_int_n:
       gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p);
       gcc_assert (!(specs->signed_p && specs->unsigned_p));
       specs->type = (specs->unsigned_p
-                    ? int128_unsigned_type_node
-                    : int128_integer_type_node);
+                    ? int_n_trees[specs->int_n_idx].unsigned_type
+                    : int_n_trees[specs->int_n_idx].signed_type);
       if (specs->complex_p)
        {
          pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
@@ -10151,9 +10691,8 @@ finish_declspecs (struct c_declspecs *specs)
   return specs;
 }
 
-/* A subroutine of c_write_global_declarations.  Perform final processing
-   on one file scope's declarations (or the external scope's declarations),
-   GLOBALS.  */
+/* Perform final processing on one file scope's declarations (or the
+   external scope's declarations), GLOBALS.  */
 
 static void
 c_write_global_declarations_1 (tree globals)
@@ -10166,7 +10705,7 @@ c_write_global_declarations_1 (tree globals)
     {
       /* Check for used but undefined static functions using the C
         standard's definition of "used", and set TREE_NO_WARNING so
-        that check_global_declarations doesn't repeat the check.  */
+        that check_global_declaration doesn't repeat the check.  */
       if (TREE_CODE (decl) == FUNCTION_DECL
          && DECL_INITIAL (decl) == 0
          && DECL_EXTERNAL (decl)
@@ -10187,21 +10726,6 @@ c_write_global_declarations_1 (tree globals)
        reconsider |= wrapup_global_declaration_2 (decl);
     }
   while (reconsider);
-
-  for (decl = globals; decl; decl = DECL_CHAIN (decl))
-    check_global_declaration_1 (decl);
-}
-
-/* A subroutine of c_write_global_declarations Emit debug information for each
-   of the declarations in GLOBALS.  */
-
-static void
-c_write_global_declarations_2 (tree globals)
-{
-  tree decl;
-
-  for (decl = globals; decl ; decl = DECL_CHAIN (decl))
-    debug_hooks->global_decl (decl);
 }
 
 /* Callback to collect a source_ref from a DECL.  */
@@ -10251,8 +10775,11 @@ for_each_global_decl (void (*callback) (tree decl))
     callback (decl);
 }
 
+/* Perform any final parser cleanups and generate initial debugging
+   information.  */
+
 void
-c_write_global_declarations (void)
+c_parse_final_cleanups (void)
 {
   tree t;
   unsigned i;
@@ -10261,6 +10788,7 @@ c_write_global_declarations (void)
   if (pch_file)
     return;
 
+  timevar_stop (TV_PHASE_PARSING);
   timevar_start (TV_PHASE_DEFERRED);
 
   /* Do the Objective-C stuff.  This is where all the Objective-C
@@ -10299,34 +10827,15 @@ c_write_global_declarations (void)
     }
 
   /* Process all file scopes in this compilation, and the external_scope,
-     through wrapup_global_declarations and check_global_declarations.  */
+     through wrapup_global_declarations.  */
   FOR_EACH_VEC_ELT (*all_translation_units, i, t)
     c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
   c_write_global_declarations_1 (BLOCK_VARS (ext_block));
 
   timevar_stop (TV_PHASE_DEFERRED);
-  timevar_start (TV_PHASE_OPT_GEN);
-
-  /* We're done parsing; proceed to optimize and emit assembly.
-     FIXME: shouldn't be the front end's responsibility to call this.  */
-  finalize_compilation_unit ();
-
-  timevar_stop (TV_PHASE_OPT_GEN);
-  timevar_start (TV_PHASE_DBGINFO);
-
-  /* After cgraph has had a chance to emit everything that's going to
-     be emitted, output debug information for globals.  */
-  if (!seen_error ())
-    {
-      timevar_push (TV_SYMOUT);
-      FOR_EACH_VEC_ELT (*all_translation_units, i, t)
-       c_write_global_declarations_2 (BLOCK_VARS (DECL_INITIAL (t)));
-      c_write_global_declarations_2 (BLOCK_VARS (ext_block));
-      timevar_pop (TV_SYMOUT);
-    }
+  timevar_start (TV_PHASE_PARSING);
 
   ext_block = NULL;
-  timevar_stop (TV_PHASE_DBGINFO);
 }
 
 /* Register reserved keyword WORD as qualifier for address space AS.  */