i386.c (legitimize_tls_address): Generate tls_initial_exec_64_sun only when !TARGET_X32.
[gcc.git] / gcc / c-decl.c
index d824e12b5bbc51a30b1ca380cd1bc130e87bfaa7..0c7e80e13c5e39000deb2af64127e0d3dae2a831 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -50,7 +50,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-pragma.h"
 #include "c-lang.h"
 #include "langhooks.h"
-#include "tree-mudflap.h"
 #include "tree-iterator.h"
 #include "diagnostic-core.h"
 #include "tree-dump.h"
@@ -147,6 +146,10 @@ 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;
+
 \f
 /* Each c_binding structure describes one binding of an identifier to
    a decl.  All the decls in a scope - irrespective of namespace - are
@@ -558,6 +561,23 @@ add_stmt (tree t)
 
   return t;
 }
+\f
+/* Build a pointer type using the default pointer mode.  */
+
+static tree
+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;
+
+  if (as != ADDR_SPACE_GENERIC || c_default_pointer_mode == VOIDmode)
+    pointer_mode = targetm.addr_space.pointer_mode (as);
+  else
+    pointer_mode = c_default_pointer_mode;
+  return build_pointer_type_for_mode (to_type, pointer_mode, false);
+}
+
 \f
 /* Return true if we will want to say something if a goto statement
    crosses DECL.  */
@@ -719,7 +739,7 @@ c_finish_incomplete_decl (tree decl)
 
          complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
 
-         layout_decl (decl, 0);
+         relayout_decl (decl);
        }
     }
 }
@@ -1196,7 +1216,7 @@ pop_scope (void)
              DECL_CHAIN (p) = BLOCK_VARS (block);
              BLOCK_VARS (block) = p;
            }
-         else if (VAR_OR_FUNCTION_DECL_P (p))
+         else if (VAR_OR_FUNCTION_DECL_P (p) && scope != file_scope)
            {
              /* For block local externs add a special
                 DECL_EXTERNAL decl for debug info generation.  */
@@ -1786,7 +1806,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
   /* Redeclaration of a type is a constraint violation (6.7.2.3p1),
      but silently ignore the redeclaration if either is in a system
      header.  (Conflicting redeclarations were handled above.)  This
-     is allowed for C1X if the types are the same, not just
+     is allowed for C11 if the types are the same, not just
      compatible.  */
   if (TREE_CODE (newdecl) == TYPE_DECL)
     {
@@ -1815,9 +1835,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
                 newdecl);
          locate_old_decl (olddecl);
        }
-      else if (pedantic && !flag_isoc1x)
+      else if (pedantic && !flag_isoc11)
        {
-         pedwarn (input_location, OPT_pedantic,
+         pedwarn (input_location, OPT_Wpedantic,
                   "redefinition of typedef %q+D", newdecl);
          locate_old_decl (olddecl);
        }
@@ -2152,7 +2172,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
                           && prototype_p (TREE_TYPE (newdecl)));
   bool old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL
                           && prototype_p (TREE_TYPE (olddecl)));
-  bool extern_changed = false;
 
   /* For real parm decl following a forward decl, rechain the old decl
      in its new location and clear TREE_ASM_WRITTEN (it's not a
@@ -2369,7 +2388,25 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
          DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
          C_DECL_DECLARED_BUILTIN (newdecl) = 1;
          if (new_is_prototype)
-           C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0;
+           {
+             C_DECL_BUILTIN_PROTOTYPE (newdecl) = 0;
+             if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
+               {
+                 enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
+                 switch (fncode)
+                   {
+                     /* If a compatible prototype of these builtin functions
+                        is seen, assume the runtime implements it with the
+                        expected semantics.  */
+                   case BUILT_IN_STPCPY:
+                     if (builtin_decl_explicit_p (fncode))
+                       set_builtin_decl_implicit_p (fncode, true);
+                     break;
+                   default:
+                     break;
+                   }
+               }
+           }
          else
            C_DECL_BUILTIN_PROTOTYPE (newdecl)
              = C_DECL_BUILTIN_PROTOTYPE (olddecl);
@@ -2405,8 +2442,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
        }
     }
 
-  extern_changed = DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl);
-
   /* Merge the USED information.  */
   if (TREE_USED (olddecl))
     TREE_USED (newdecl) = 1;
@@ -2432,6 +2467,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
     memcpy ((char *) olddecl + sizeof (struct tree_common),
            (char *) newdecl + sizeof (struct tree_common),
            sizeof (struct tree_decl_common) - sizeof (struct tree_common));
+    DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl);
     switch (TREE_CODE (olddecl))
       {
       case FUNCTION_DECL:
@@ -2467,13 +2503,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
          || (TREE_CODE (olddecl) == VAR_DECL
              && TREE_STATIC (olddecl))))
     make_decl_rtl (olddecl);
-
-  /* If we changed a function from DECL_EXTERNAL to !DECL_EXTERNAL,
-     and the definition is coming from the old version, cgraph needs
-     to be called again.  */
-  if (extern_changed && !new_is_definition
-      && TREE_CODE (olddecl) == FUNCTION_DECL && DECL_INITIAL (olddecl))
-    cgraph_mark_if_needed (olddecl);
 }
 
 /* Handle when a new declaration NEWDECL has the same name as an old
@@ -2516,7 +2545,10 @@ warn_if_shadowing (tree new_decl)
 
   /* Is anything being shadowed?  Invisible decls do not count.  */
   for (b = I_SYMBOL_BINDING (DECL_NAME (new_decl)); b; b = b->shadowed)
-    if (b->decl && b->decl != new_decl && !b->invisible)
+    if (b->decl && b->decl != new_decl && !b->invisible
+       && (b->decl == error_mark_node
+           || diagnostic_report_warnings_p (global_dc,
+                                            DECL_SOURCE_LOCATION (b->decl))))
       {
        tree old_decl = b->decl;
 
@@ -2769,7 +2801,15 @@ pushdecl (tree x)
 
  skip_external_and_shadow_checks:
   if (TREE_CODE (x) == TYPE_DECL)
-    set_underlying_type (x);
+    {
+      /* So this is a typedef, set its underlying type.  */
+      set_underlying_type (x);
+
+      /* If X is a typedef defined in the current function, record it
+        for the purpose of implementing the -Wunused-local-typedefs
+        warning.  */
+      record_locally_defined_typedef (x);
+    }
 
   bind (name, x, scope, /*invisible=*/false, nested, locus);
 
@@ -3435,7 +3475,10 @@ lookup_name (tree name)
 {
   struct c_binding *b = I_SYMBOL_BINDING (name);
   if (b && !b->invisible)
-    return b->decl;
+    {
+      maybe_record_typedef_use (b->decl);
+      return b->decl;
+    }
   return 0;
 }
 
@@ -3678,6 +3721,17 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
              warned = 1;
              pending_xref_error ();
            }
+         else if (declspecs->typespec_kind != ctsk_tagdef
+                   && declspecs->typespec_kind != ctsk_tagfirstref
+                  && declspecs->alignas_p)
+           {
+             if (warned != 1)
+               pedwarn (input_location, 0,
+                        "empty declaration with %<_Alignas%> "
+                         "does not redeclare tag");
+             warned = 1;
+             pending_xref_error ();
+           }
          else
            {
              pending_invalid_xref = 0;
@@ -3753,6 +3807,12 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
       warned = 2;
     }
 
+  if (!warned && !in_system_header && declspecs->alignas_p)
+    {
+      warning (0, "useless %<_Alignas%> in empty declaration");
+      warned = 2;
+    }
+
   if (warned != 1)
     {
       if (!found_tag)
@@ -3827,11 +3887,11 @@ build_array_declarator (location_t loc,
   if (!flag_isoc99)
     {
       if (static_p || quals != NULL)
-       pedwarn (loc, OPT_pedantic,
+       pedwarn (loc, OPT_Wpedantic,
                 "ISO C90 does not support %<static%> or type "
                 "qualifiers in parameter array declarators");
       if (vla_unspec_p)
-       pedwarn (loc, OPT_pedantic,
+       pedwarn (loc, OPT_Wpedantic,
                 "ISO C90 does not support %<[*]%> array declarators");
     }
   if (vla_unspec_p)
@@ -4262,7 +4322,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
       if (DECL_INITIAL (decl))
        TREE_TYPE (DECL_INITIAL (decl)) = type;
 
-      layout_decl (decl, 0);
+      relayout_decl (decl);
     }
 
   if (TREE_CODE (decl) == VAR_DECL)
@@ -4313,7 +4373,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
     }
 
   /* If this is a function and an assembler name is specified, reset DECL_RTL
-     so we can give it its new name.  Also, update built_in_decls if it
+     so we can give it its new name.  Also, update builtin_decl if it
      was a normal built-in.  */
   if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
     {
@@ -4524,7 +4584,7 @@ mark_forward_parm_decls (void)
 
   if (pedantic && !current_scope->warned_forward_parm_decls)
     {
-      pedwarn (input_location, OPT_pedantic,
+      pedwarn (input_location, OPT_Wpedantic,
               "ISO C forbids forward parameter declarations");
       current_scope->warned_forward_parm_decls = true;
     }
@@ -4562,7 +4622,9 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const)
   TREE_USED (decl) = 1;
   DECL_READ_P (decl) = 1;
   TREE_TYPE (decl) = type;
-  TREE_READONLY (decl) = TYPE_READONLY (type);
+  TREE_READONLY (decl) = (TYPE_READONLY (type)
+                         || (TREE_CODE (type) == ARRAY_TYPE
+                             && TYPE_READONLY (TREE_TYPE (type))));
   store_init_value (loc, decl, init, NULL_TREE);
 
   if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
@@ -4676,7 +4738,7 @@ 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_pedantic,
+           pedwarn (input_location, OPT_Wpedantic,
                     "bit-field %qs width not an integer constant expression",
                     name);
        }
@@ -4712,7 +4774,7 @@ check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
       && type_mv != integer_type_node
       && type_mv != unsigned_type_node
       && type_mv != boolean_type_node)
-    pedwarn (input_location, OPT_pedantic,
+    pedwarn (input_location, OPT_Wpedantic,
             "type of bit-field %qs is a GCC extension", name);
 
   max_width = TYPE_PRECISION (*type);
@@ -4865,6 +4927,7 @@ grokdeclarator (const struct c_declarator *declarator,
   tree expr_dummy;
   bool expr_const_operands_dummy;
   enum c_declarator_kind first_non_attr_kind;
+  unsigned int alignas_align = 0;
 
   if (TREE_CODE (type) == ERROR_MARK)
     return error_mark_node;
@@ -5005,11 +5068,11 @@ grokdeclarator (const struct c_declarator *declarator,
   if (pedantic && !flag_isoc99)
     {
       if (constp > 1)
-       pedwarn (loc, OPT_pedantic, "duplicate %<const%>");
+       pedwarn (loc, OPT_Wpedantic, "duplicate %<const%>");
       if (restrictp > 1)
-       pedwarn (loc, OPT_pedantic, "duplicate %<restrict%>");
+       pedwarn (loc, OPT_Wpedantic, "duplicate %<restrict%>");
       if (volatilep > 1)
-       pedwarn (loc, OPT_pedantic, "duplicate %<volatile%>");
+       pedwarn (loc, OPT_Wpedantic, "duplicate %<volatile%>");
     }
 
   if (!ADDR_SPACE_GENERIC_P (as1) && !ADDR_SPACE_GENERIC_P (as2) && as1 != as2)
@@ -5036,7 +5099,7 @@ grokdeclarator (const struct c_declarator *declarator,
     {
       if (storage_class == csc_auto)
        pedwarn (loc,
-                (current_scope == file_scope) ? 0 : OPT_pedantic,
+                (current_scope == file_scope) ? 0 : OPT_Wpedantic,
                 "function definition declared %<auto%>");
       if (storage_class == csc_register)
        error_at (loc, "function definition declared %<register%>");
@@ -5102,7 +5165,7 @@ grokdeclarator (const struct c_declarator *declarator,
        error_at (loc, "file-scope declaration of %qE specifies %<auto%>",
                  name);
       if (pedantic && storage_class == csc_register)
-       pedwarn (input_location, OPT_pedantic,
+       pedwarn (input_location, OPT_Wpedantic,
                 "file-scope declaration of %qE specifies %<register%>", name);
     }
   else
@@ -5224,7 +5287,7 @@ grokdeclarator (const struct c_declarator *declarator,
              }
 
            if (pedantic && !in_system_header && flexible_array_type_p (type))
-             pedwarn (loc, OPT_pedantic,
+             pedwarn (loc, OPT_Wpedantic,
                       "invalid use of structure with flexible array member");
 
            if (size == error_mark_node)
@@ -5264,10 +5327,10 @@ grokdeclarator (const struct c_declarator *declarator,
                if (pedantic && size_maybe_const && integer_zerop (size))
                  {
                    if (name)
-                     pedwarn (loc, OPT_pedantic,
+                     pedwarn (loc, OPT_Wpedantic,
                               "ISO C forbids zero-size array %qE", name);
                    else
-                     pedwarn (loc, OPT_pedantic,
+                     pedwarn (loc, OPT_Wpedantic,
                               "ISO C forbids zero-size array");
                  }
 
@@ -5392,7 +5455,7 @@ grokdeclarator (const struct c_declarator *declarator,
                  }
                if (flexible_array_member
                    && pedantic && !flag_isoc99 && !in_system_header)
-                 pedwarn (loc, OPT_pedantic,
+                 pedwarn (loc, OPT_Wpedantic,
                           "ISO C90 does not support flexible array members");
 
                /* ISO C99 Flexible array members are effectively
@@ -5593,7 +5656,7 @@ grokdeclarator (const struct c_declarator *declarator,
 
            if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
                && type_quals)
-             pedwarn (loc, OPT_pedantic,
+             pedwarn (loc, OPT_Wpedantic,
                       "ISO C forbids qualified function types");
            if (type_quals)
              type = c_build_qualified_type (type, type_quals);
@@ -5633,7 +5696,7 @@ grokdeclarator (const struct c_declarator *declarator,
                TYPE_NAME (type) = decl;
              }
 
-           type = build_pointer_type (type);
+           type = c_build_pointer_type (type);
 
            /* Process type qualifiers (such as const or volatile)
               that were given inside the `*'.  */
@@ -5708,12 +5771,52 @@ grokdeclarator (const struct c_declarator *declarator,
   if (bitfield)
     check_bitfield_type_and_width (&type, width, name);
 
-  /* Did array size calculations overflow?  */
+  /* Reject invalid uses of _Alignas.  */
+  if (declspecs->alignas_p)
+    {
+      if (storage_class == csc_typedef)
+       error_at (loc, "alignment specified for typedef %qE", name);
+      else if (storage_class == csc_register)
+       error_at (loc, "alignment specified for %<register%> object %qE",
+                 name);
+      else if (decl_context == PARM)
+       {
+         if (name)
+           error_at (loc, "alignment specified for parameter %qE", name);
+         else
+           error_at (loc, "alignment specified for unnamed parameter");
+       }
+      else if (bitfield)
+       {
+         if (name)
+           error_at (loc, "alignment specified for bit-field %qE", name);
+         else
+           error_at (loc, "alignment specified for unnamed bit-field");
+       }
+      else if (TREE_CODE (type) == FUNCTION_TYPE)
+       error_at (loc, "alignment specified for function %qE", name);
+      else if (declspecs->align_log != -1)
+       {
+         alignas_align = 1U << declspecs->align_log;
+         if (alignas_align < TYPE_ALIGN_UNIT (type))
+           {
+             if (name)
+               error_at (loc, "%<_Alignas%> specifiers cannot reduce "
+                         "alignment of %qE", name);
+             else
+               error_at (loc, "%<_Alignas%> specifiers cannot reduce "
+                         "alignment of unnamed field");
+             alignas_align = 0;
+           }
+       }
+    }
 
+  /* Did array size calculations overflow or does the array cover more
+     than half of the address-space?  */
   if (TREE_CODE (type) == ARRAY_TYPE
       && COMPLETE_TYPE_P (type)
       && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
-      && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
+      && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
     {
       if (name)
        error_at (loc, "size of array %qE is too large", name);
@@ -5731,7 +5834,7 @@ grokdeclarator (const struct c_declarator *declarator,
       tree decl;
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
          && type_quals)
-       pedwarn (loc, OPT_pedantic,
+       pedwarn (loc, OPT_Wpedantic,
                 "ISO C forbids qualified function types");
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
@@ -5777,7 +5880,7 @@ grokdeclarator (const struct c_declarator *declarator,
                  && !declspecs->inline_p && !declspecs->noreturn_p);
       if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
          && type_quals)
-       pedwarn (loc, OPT_pedantic,
+       pedwarn (loc, OPT_Wpedantic,
                 "ISO C forbids const or volatile function types");
       if (type_quals)
        type = c_build_qualified_type (type, type_quals);
@@ -5788,7 +5891,7 @@ grokdeclarator (const struct c_declarator *declarator,
       && variably_modified_type_p (type, NULL_TREE))
     {
       /* C99 6.7.2.1p8 */
-      pedwarn (loc, OPT_pedantic, "a member of a structure or union cannot "
+      pedwarn (loc, OPT_Wpedantic, "a member of a structure or union cannot "
               "have a variably modified type");
     }
 
@@ -5828,7 +5931,7 @@ grokdeclarator (const struct c_declarator *declarator,
            type = TREE_TYPE (type);
            if (type_quals)
              type = c_build_qualified_type (type, type_quals);
-           type = build_pointer_type (type);
+           type = c_build_pointer_type (type);
            type_quals = array_ptr_quals;
            if (type_quals)
              type = c_build_qualified_type (type, type_quals);
@@ -5843,11 +5946,11 @@ grokdeclarator (const struct c_declarator *declarator,
        else if (TREE_CODE (type) == FUNCTION_TYPE)
          {
            if (type_quals)
-             pedwarn (loc, OPT_pedantic,
+             pedwarn (loc, OPT_Wpedantic,
                       "ISO C forbids qualified function types");
            if (type_quals)
              type = c_build_qualified_type (type, type_quals);
-           type = build_pointer_type (type);
+           type = c_build_pointer_type (type);
            type_quals = TYPE_UNQUALIFIED;
          }
        else if (type_quals)
@@ -5921,7 +6024,7 @@ grokdeclarator (const struct c_declarator *declarator,
               GCC allows 'auto', perhaps with 'inline', to support
               nested functions.  */
            if (storage_class == csc_auto)
-               pedwarn (loc, OPT_pedantic,
+               pedwarn (loc, OPT_Wpedantic,
                         "invalid storage class for function %qE", name);
            else if (storage_class == csc_static)
              {
@@ -5938,7 +6041,7 @@ grokdeclarator (const struct c_declarator *declarator,
        decl = build_decl_attribute_variant (decl, decl_attr);
 
        if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
-         pedwarn (loc, OPT_pedantic,
+         pedwarn (loc, OPT_Wpedantic,
                   "ISO C forbids qualified function types");
 
        /* Every function declaration is an external reference
@@ -5986,7 +6089,18 @@ grokdeclarator (const struct c_declarator *declarator,
              /* Record that the function is declared `inline'.  */
              DECL_DECLARED_INLINE_P (decl) = 1;
            if (declspecs->noreturn_p)
-             TREE_THIS_VOLATILE (decl) = 1;
+             {
+               if (!flag_isoc11)
+                 {
+                   if (flag_isoc99)
+                     pedwarn (loc, OPT_Wpedantic,
+                              "ISO C99 does not support %<_Noreturn%>");
+                   else
+                     pedwarn (loc, OPT_Wpedantic,
+                              "ISO C90 does not support %<_Noreturn%>");
+                 }
+               TREE_THIS_VOLATILE (decl) = 1;
+             }
          }
       }
     else
@@ -6077,6 +6191,13 @@ grokdeclarator (const struct c_declarator *declarator,
     /* Record constancy and volatility.  */
     c_apply_type_quals_to_decl (type_quals, decl);
 
+    /* Apply _Alignas specifiers.  */
+    if (alignas_align)
+      {
+       DECL_ALIGN (decl) = alignas_align * BITS_PER_UNIT;
+       DECL_USER_ALIGN (decl) = 1;
+      }
+
     /* If a type has volatile components, it should be stored in memory.
        Otherwise, the fact that those components are volatile
        will be ignored, and would even crash the compiler.
@@ -6653,7 +6774,7 @@ grokfield (location_t loc,
 
         If this is something of the form "foo;" and foo is a TYPE_DECL, then
           If foo names a structure or union without a tag, then this
-            is an anonymous struct (this is permitted by C1X).
+            is an anonymous struct (this is permitted by C11).
           If MS or Plan 9 extensions are enabled and foo names a
             structure, then again this is an anonymous struct.
           Otherwise this is an error.
@@ -6684,13 +6805,13 @@ grokfield (location_t loc,
          pedwarn (loc, 0, "declaration does not declare anything");
          return NULL_TREE;
        }
-      if (!flag_isoc1x)
+      if (!flag_isoc11)
        {
          if (flag_isoc99)
-           pedwarn (loc, OPT_pedantic,
+           pedwarn (loc, OPT_Wpedantic,
                     "ISO C99 doesn%'t support unnamed structs/unions");
          else
-           pedwarn (loc, OPT_pedantic,
+           pedwarn (loc, OPT_Wpedantic,
                     "ISO C90 doesn%'t support unnamed structs/unions");
        }
     }
@@ -6964,7 +7085,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
        {
          if (DECL_NAME (x) != 0)
            break;
-         if (flag_isoc1x
+         if (flag_isoc11
              && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
                  || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE))
            break;
@@ -6975,16 +7096,16 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
          if (TREE_CODE (t) == UNION_TYPE)
            {
              if (fieldlist)
-               pedwarn (loc, OPT_pedantic, "union has no named members");
+               pedwarn (loc, OPT_Wpedantic, "union has no named members");
              else
-               pedwarn (loc, OPT_pedantic, "union has no members");
+               pedwarn (loc, OPT_Wpedantic, "union has no members");
            }
          else
            {
              if (fieldlist)
-               pedwarn (loc, OPT_pedantic, "struct has no named members");
+               pedwarn (loc, OPT_Wpedantic, "struct has no named members");
              else
-               pedwarn (loc, OPT_pedantic, "struct has no members");
+               pedwarn (loc, OPT_Wpedantic, "struct has no members");
            }
        }
     }
@@ -7066,7 +7187,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
 
       if (pedantic && TREE_CODE (t) == RECORD_TYPE
          && flexible_array_type_p (TREE_TYPE (x)))
-       pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic,
+       pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
                 "invalid use of structure with flexible array member");
 
       if (DECL_NAME (x)
@@ -7196,8 +7317,6 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
          if (c_dialect_objc ())
            objc_check_decl (decl);
          rest_of_decl_compilation (decl, toplevel, 0);
-         if (!toplevel)
-           expand_decl (decl);
        }
     }
   C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0;
@@ -7488,7 +7607,7 @@ build_enumerator (location_t decl_loc, location_t loc,
            {
              value = c_fully_fold (value, false, NULL);
              if (TREE_CODE (value) == INTEGER_CST)
-               pedwarn (loc, OPT_pedantic,
+               pedwarn (loc, OPT_Wpedantic,
                         "enumerator value for %qE is not an integer "
                         "constant expression", name);
            }
@@ -7520,7 +7639,7 @@ build_enumerator (location_t decl_loc, location_t loc,
      (6.4.4.3/2 in the C99 Standard).  GCC allows any integer type as
      an extension.  */
   else if (!int_fits_type_p (value, integer_type_node))
-    pedwarn (loc, OPT_pedantic,
+    pedwarn (loc, OPT_Wpedantic,
             "ISO C restricts enumerator values to range of %<int%>");
 
   /* The ISO C Standard mandates enumerators to have type int, even
@@ -7594,7 +7713,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
 
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
-  if (decl1 == 0)
+  if (decl1 == 0
+      || TREE_CODE (decl1) != FUNCTION_DECL)
     return 0;
 
   loc = DECL_SOURCE_LOCATION (decl1);
@@ -8065,14 +8185,14 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
                     old-style definition and discarded?  */
                  if (current_function_prototype_built_in)
                    warning_at (DECL_SOURCE_LOCATION (parm),
-                               OPT_pedantic, "promoted argument %qD "
+                               OPT_Wpedantic, "promoted argument %qD "
                                "doesn%'t match built-in prototype", parm);
                  else
                    {
                      pedwarn (DECL_SOURCE_LOCATION (parm),
-                              OPT_pedantic, "promoted argument %qD "
+                              OPT_Wpedantic, "promoted argument %qD "
                               "doesn%'t match prototype", parm);
-                     pedwarn (current_function_prototype_locus, OPT_pedantic,
+                     pedwarn (current_function_prototype_locus, OPT_Wpedantic,
                               "prototype declaration");
                    }
                }
@@ -8181,6 +8301,9 @@ store_parm_decls (void)
   /* Initialize the RTL code for the function.  */
   allocate_struct_function (fndecl, false);
 
+  if (warn_unused_local_typedefs)
+    cfun->language = ggc_alloc_cleared_language_function ();
+
   /* Begin the statement tree for this function.  */
   DECL_SAVED_TREE (fndecl) = push_stmt_list ();
 
@@ -8288,6 +8411,10 @@ finish_function (void)
                      "parameter %qD set but not used", decl);
     }
 
+  /* Complain about locally defined typedefs that are not used in this
+     function.  */
+  maybe_warn_unused_local_typedefs ();
+
   /* Store the end of the function, so that we get good line number
      info for the epilogue.  */
   cfun->function_end_locus = input_location;
@@ -8333,6 +8460,12 @@ finish_function (void)
   if (!decl_function_context (fndecl))
     undef_nested_function = false;
 
+  if (cfun->language != NULL)
+    {
+      ggc_free (cfun->language);
+      cfun->language = NULL;
+    }
+
   /* We're leaving the context of this function, so zap cfun.
      It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
      tree_rest_of_compilation.  */
@@ -8646,10 +8779,12 @@ struct c_declspecs *
 build_null_declspecs (void)
 {
   struct c_declspecs *ret = XOBNEW (&parser_obstack, struct c_declspecs);
+  memset (&ret->locations, 0, cdw_number_of_elements);
   ret->type = 0;
   ret->expr = 0;
   ret->decl_attr = 0;
   ret->attrs = 0;
+  ret->align_log = -1;
   ret->typespec_word = cts_none;
   ret->storage_class = csc_none;
   ret->expr_const_operands = true;
@@ -8673,6 +8808,7 @@ build_null_declspecs (void)
   ret->volatile_p = false;
   ret->restrict_p = false;
   ret->saturating_p = false;
+  ret->alignas_p = false;
   ret->address_space = ADDR_SPACE_GENERIC;
   return ret;
 }
@@ -8681,7 +8817,8 @@ build_null_declspecs (void)
    SPECS, returning SPECS.  */
 
 struct c_declspecs *
-declspecs_add_addrspace (struct c_declspecs *specs, addr_space_t as)
+declspecs_add_addrspace (source_location location,
+                        struct c_declspecs *specs, addr_space_t as)
 {
   specs->non_sc_seen_p = true;
   specs->declspecs_seen_p = true;
@@ -8692,7 +8829,10 @@ declspecs_add_addrspace (struct c_declspecs *specs, addr_space_t as)
           c_addr_space_name (as),
           c_addr_space_name (specs->address_space));
   else
-    specs->address_space = as;
+    {
+      specs->address_space = as;
+      specs->locations[cdw_address_space] = location;
+    }
   return specs;
 }
 
@@ -8700,7 +8840,8 @@ declspecs_add_addrspace (struct c_declspecs *specs, addr_space_t as)
    returning SPECS.  */
 
 struct c_declspecs *
-declspecs_add_qual (struct c_declspecs *specs, tree qual)
+declspecs_add_qual (source_location loc,
+                   struct c_declspecs *specs, tree qual)
 {
   enum rid i;
   bool dupe = false;
@@ -8714,20 +8855,23 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual)
     case RID_CONST:
       dupe = specs->const_p;
       specs->const_p = true;
+      specs->locations[cdw_const] = loc;
       break;
     case RID_VOLATILE:
       dupe = specs->volatile_p;
       specs->volatile_p = true;
+      specs->locations[cdw_volatile] = loc;
       break;
     case RID_RESTRICT:
       dupe = specs->restrict_p;
       specs->restrict_p = true;
+      specs->locations[cdw_restrict] = loc;
       break;
     default:
       gcc_unreachable ();
     }
   if (dupe && !flag_isoc99)
-    pedwarn (input_location, OPT_pedantic, "duplicate %qE", qual);
+    pedwarn (loc, OPT_Wpedantic, "duplicate %qE", qual);
   return specs;
 }
 
@@ -8780,6 +8924,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                  pedwarn_c90 (loc, OPT_Wlong_long,
                               "ISO C90 does not support %<long long%>");
                  specs->long_long_p = 1;
+                 specs->locations[cdw_long_long] = loc;
                  break;
                }
              if (specs->short_p)
@@ -8819,7 +8964,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<long%> and %<_Decimal128%> in "
                           "declaration specifiers"));
              else
-               specs->long_p = true;
+               {
+                 specs->long_p = true;
+                 specs->locations[cdw_long] = loc;
+               }
              break;
            case RID_SHORT:
              dupe = specs->short_p;
@@ -8864,7 +9012,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<short%> and %<_Decimal128%> in "
                           "declaration specifiers"));
              else
-               specs->short_p = true;
+               {
+                 specs->short_p = true;
+                 specs->locations[cdw_short] = loc;
+               }
              break;
            case RID_SIGNED:
              dupe = specs->signed_p;
@@ -8901,7 +9052,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<signed%> and %<_Decimal128%> in "
                           "declaration specifiers"));
              else
-               specs->signed_p = true;
+               {
+                 specs->signed_p = true;
+                 specs->locations[cdw_signed] = loc;
+               }
              break;
            case RID_UNSIGNED:
              dupe = specs->unsigned_p;
@@ -8938,12 +9092,15 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<unsigned%> and %<_Decimal128%> in "
                           "declaration specifiers"));
              else
-               specs->unsigned_p = true;
+               {
+                 specs->unsigned_p = true;
+                 specs->locations[cdw_unsigned] = loc;
+               }
              break;
            case RID_COMPLEX:
              dupe = specs->complex_p;
-             if (!flag_isoc99 && !in_system_header)
-               pedwarn (loc, OPT_pedantic,
+             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)
                error_at (loc,
@@ -8978,11 +9135,14 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<complex%> and %<_Sat%> in "
                           "declaration specifiers"));
              else
-               specs->complex_p = true;
+               {
+                 specs->complex_p = true;
+                 specs->locations[cdw_complex] = loc;
+               }
              break;
            case RID_SAT:
              dupe = specs->saturating_p;
-             pedwarn (loc, OPT_pedantic,
+             pedwarn (loc, OPT_Wpedantic,
                       "ISO C does not support saturating types");
              if (specs->typespec_word == cts_int128)
                {
@@ -9031,7 +9191,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<_Sat%> and %<complex%> in "
                           "declaration specifiers"));
              else
-               specs->saturating_p = true;
+               {
+                 specs->saturating_p = true;
+                 specs->locations[cdw_saturating] = loc;
+               }
              break;
            default:
              gcc_unreachable ();
@@ -9061,7 +9224,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                  return specs;
                }
              if (!in_system_header)
-               pedwarn (loc, OPT_pedantic,
+               pedwarn (loc, OPT_Wpedantic,
                         "ISO C does not support %<__int128%> type");
 
              if (specs->long_p)
@@ -9077,7 +9240,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<__int128%> and %<short%> in "
                           "declaration specifiers"));
              else
-               specs->typespec_word = cts_int128;
+               {
+                 specs->typespec_word = cts_int128;
+                 specs->locations[cdw_typespec] = loc;
+               }
              return specs;
            case RID_VOID:
              if (specs->long_p)
@@ -9105,7 +9271,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<_Sat%> and %<void%> in "
                           "declaration specifiers"));
              else
-               specs->typespec_word = cts_void;
+               {
+                 specs->typespec_word = cts_void;
+                 specs->locations[cdw_typespec] = loc;
+               }
              return specs;
            case RID_BOOL:
              if (specs->long_p)
@@ -9133,7 +9302,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<_Sat%> and %<_Bool%> in "
                           "declaration specifiers"));
              else
-               specs->typespec_word = cts_bool;
+               {
+                 specs->typespec_word = cts_bool;
+                 specs->locations[cdw_typespec] = loc;
+               }
              return specs;
            case RID_CHAR:
              if (specs->long_p)
@@ -9149,7 +9321,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<_Sat%> and %<char%> in "
                           "declaration specifiers"));
              else
-               specs->typespec_word = cts_char;
+               {
+                 specs->typespec_word = cts_char;
+                 specs->locations[cdw_typespec] = loc;
+               }
              return specs;
            case RID_INT:
              if (specs->saturating_p)
@@ -9157,7 +9332,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<_Sat%> and %<int%> in "
                           "declaration specifiers"));
              else
-               specs->typespec_word = cts_int;
+               {
+                 specs->typespec_word = cts_int;
+                 specs->locations[cdw_typespec] = loc;
+               }
              return specs;
            case RID_FLOAT:
              if (specs->long_p)
@@ -9181,7 +9359,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<_Sat%> and %<float%> in "
                           "declaration specifiers"));
              else
-               specs->typespec_word = cts_float;
+               {
+                 specs->typespec_word = cts_float;
+                 specs->locations[cdw_typespec] = loc;
+               }
              return specs;
            case RID_DOUBLE:
              if (specs->long_long_p)
@@ -9205,7 +9386,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<_Sat%> and %<double%> in "
                           "declaration specifiers"));
              else
-               specs->typespec_word = cts_double;
+               {
+                 specs->typespec_word = cts_double;
+                 specs->locations[cdw_typespec] = loc;
+               }
              return specs;
            case RID_DFLOAT32:
            case RID_DFLOAT64:
@@ -9259,12 +9443,13 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                  specs->typespec_word = cts_dfloat64;
                else
                  specs->typespec_word = cts_dfloat128;
+               specs->locations[cdw_typespec] = loc;
              }
              if (!targetm.decimal_float_supported_p ())
                error_at (loc,
                          ("decimal floating point not supported "
                           "for this target"));
-             pedwarn (loc, OPT_pedantic,
+             pedwarn (loc, OPT_Wpedantic,
                       "ISO C does not support decimal floating point");
              return specs;
            case RID_FRACT:
@@ -9284,11 +9469,12 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                    specs->typespec_word = cts_fract;
                else
                    specs->typespec_word = cts_accum;
+               specs->locations[cdw_typespec] = loc;
              }
              if (!targetm.fixed_point_supported_p ())
                error_at (loc,
                          "fixed-point types not supported for this target");
-             pedwarn (loc, OPT_pedantic,
+             pedwarn (loc, OPT_Wpedantic,
                       "ISO C does not support fixed-point types");
              return specs;
            default:
@@ -9317,6 +9503,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
          specs->decl_attr = DECL_ATTRIBUTES (type);
          specs->typedef_p = true;
          specs->explicit_signed_p = C_TYPEDEF_EXPLICITLY_SIGNED (type);
+         specs->locations[cdw_typedef] = loc;
 
          /* If this typedef name is defined in a struct, then a C++
             lookup would return a different value.  */
@@ -9340,13 +9527,17 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
       else if (TREE_TYPE (t) == error_mark_node)
        ;
       else
-       specs->type = TREE_TYPE (t);
+       {
+         specs->type = TREE_TYPE (t);
+         specs->locations[cdw_typespec] = loc;
+       }
     }
   else
     {
       if (TREE_CODE (type) != ERROR_MARK && spec.kind == ctsk_typeof)
        {
          specs->typedef_p = true;
+         specs->locations[cdw_typedef] = loc;
          if (spec.expr)
            {
              if (specs->expr)
@@ -9367,7 +9558,9 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
    declaration specifiers SPECS, returning SPECS.  */
 
 struct c_declspecs *
-declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
+declspecs_add_scspec (source_location loc,
+                     struct c_declspecs *specs,
+                     tree scspec)
 {
   enum rid i;
   enum c_storage_class n = csc_none;
@@ -9388,11 +9581,13 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
         difference between gnu89 and C99 inline.  */
       dupe = false;
       specs->inline_p = true;
+      specs->locations[cdw_inline] = loc;
       break;
     case RID_NORETURN:
       /* Duplicate _Noreturn is permitted.  */
       dupe = false;
       specs->noreturn_p = true;
+      specs->locations[cdw_noreturn] = loc;
       break;
     case RID_THREAD:
       dupe = specs->thread_p;
@@ -9403,7 +9598,10 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
       else if (specs->storage_class == csc_typedef)
        error ("%<__thread%> used with %<typedef%>");
       else
-       specs->thread_p = true;
+       {
+         specs->thread_p = true;
+         specs->locations[cdw_thread] = loc;
+       }
       break;
     case RID_AUTO:
       n = csc_auto;
@@ -9442,6 +9640,7 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
       else
        {
          specs->storage_class = n;
+         specs->locations[cdw_storage_class] = loc;
          if (n != csc_extern && n != csc_static && specs->thread_p)
            {
              error ("%<__thread%> used with %qE", scspec);
@@ -9456,13 +9655,32 @@ declspecs_add_scspec (struct c_declspecs *specs, tree scspec)
    returning SPECS.  */
 
 struct c_declspecs *
-declspecs_add_attrs (struct c_declspecs *specs, tree attrs)
+declspecs_add_attrs (source_location loc, struct c_declspecs *specs, tree attrs)
 {
   specs->attrs = chainon (attrs, specs->attrs);
+  specs->locations[cdw_attributes] = loc;
   specs->declspecs_seen_p = true;
   return specs;
 }
 
+/* Add an _Alignas specifier (expression ALIGN, or type whose
+   alignment is ALIGN) to the declaration specifiers SPECS, returning
+   SPECS.  */
+struct c_declspecs *
+declspecs_add_alignas (source_location loc,
+                      struct c_declspecs *specs, tree align)
+{
+  int align_log;
+  specs->alignas_p = true;
+  specs->locations[cdw_alignas] = loc;
+  if (align == error_mark_node)
+    return specs;
+  align_log = check_user_alignment (align, true);
+  if (align_log > specs->align_log)
+    specs->align_log = align_log;
+  return specs;
+}
+
 /* Combine "long", "short", "signed", "unsigned" and "_Complex" type
    specifiers with any other type specifier to determine the resulting
    type.  This is where ISO C checks on complex types are made, since
@@ -9495,9 +9713,11 @@ finish_declspecs (struct c_declspecs *specs)
     {
       if (specs->saturating_p)
        {
-         error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
+         error_at (specs->locations[cdw_saturating],
+                   "%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
          if (!targetm.fixed_point_supported_p ())
-           error ("fixed-point types not supported for this target");
+           error_at (specs->locations[cdw_saturating],
+                     "fixed-point types not supported for this target");
          specs->typespec_word = cts_fract;
        }
       else if (specs->long_p || specs->short_p
@@ -9508,7 +9728,7 @@ finish_declspecs (struct c_declspecs *specs)
       else if (specs->complex_p)
        {
          specs->typespec_word = cts_double;
-         pedwarn (input_location, OPT_pedantic,
+         pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
                   "ISO C does not support plain %<complex%> meaning "
                   "%<double complex%>");
        }
@@ -9553,7 +9773,7 @@ finish_declspecs (struct c_declspecs *specs)
        specs->type = char_type_node;
       if (specs->complex_p)
        {
-         pedwarn (input_location, OPT_pedantic,
+         pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
                   "ISO C does not support complex integer types");
          specs->type = build_complex_type (specs->type);
        }
@@ -9566,7 +9786,7 @@ finish_declspecs (struct c_declspecs *specs)
                     : int128_integer_type_node);
       if (specs->complex_p)
        {
-         pedwarn (input_location, OPT_pedantic,
+         pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
                   "ISO C does not support complex integer types");
          specs->type = build_complex_type (specs->type);
        }
@@ -9592,7 +9812,7 @@ finish_declspecs (struct c_declspecs *specs)
                       : integer_type_node);
       if (specs->complex_p)
        {
-         pedwarn (input_location, OPT_pedantic,
+         pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
                   "ISO C does not support complex integer types");
          specs->type = build_complex_type (specs->type);
        }
@@ -9787,6 +10007,9 @@ collect_source_ref_cb (tree decl)
     collect_source_ref (LOCATION_FILE (decl_sloc (decl, false)));
 }
 
+/* Preserve the external declarations scope across a garbage collect.  */
+static GTY(()) tree ext_block;
+
 /* Collect all references relevant to SOURCE_FILE.  */
 
 static void
@@ -9797,6 +10020,8 @@ collect_all_refs (const char *source_file)
 
   FOR_EACH_VEC_ELT (tree, all_translation_units, i, t)
     collect_ada_nodes (BLOCK_VARS (DECL_INITIAL (t)), source_file);
+
+  collect_ada_nodes (BLOCK_VARS (ext_block), source_file);
 }
 
 /* Iterate over all global declarations and call CALLBACK.  */
@@ -9815,10 +10040,10 @@ for_each_global_decl (void (*callback) (tree decl))
       for (decl = BLOCK_VARS (decls); decl; decl = TREE_CHAIN (decl))
        callback (decl);
     }
-}
 
-/* Preserve the external declarations scope across a garbage collect.  */
-static GTY(()) tree ext_block;
+  for (decl = BLOCK_VARS (ext_block); decl; decl = TREE_CHAIN (decl))
+    callback (decl);
+}
 
 void
 c_write_global_declarations (void)
@@ -9878,7 +10103,7 @@ c_write_global_declarations (void)
 
   /* We're done parsing; proceed to optimize and emit assembly.
      FIXME: shouldn't be the front end's responsibility to call this.  */
-  cgraph_finalize_compilation_unit ();
+  finalize_compilation_unit ();
 
   timevar_stop (TV_PHASE_CGRAPH);
   timevar_start (TV_PHASE_DBGINFO);