OSDN Git Service

* toplev.c (rest_of_compilation): Avoid cfg_cleanup calls when not
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index 251a255..1a20b47 100644 (file)
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "real.h"
 #include "flags.h"
@@ -29,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "c-pragma.h"
 #include "rtl.h"
 #include "ggc.h"
+#include "varray.h"
 #include "expr.h"
 #include "c-common.h"
 #include "diagnostic.h"
@@ -188,11 +191,20 @@ enum c_language_kind c_language;
 
 tree c_global_trees[CTI_MAX];
 
+/* Nonzero if we can read a PCH file now.  */
+
+int allow_pch = 1;
+\f
 /* Switches common to the C front ends.  */
 
 /* Nonzero if prepreprocessing only.  */
 int flag_preprocess_only;
 
+/* The file name to which we should write a precompiled header, or
+   NULL if no header will be written in this compile.  */
+
+const char *pch_file;
+
 /* Nonzero if an ISO standard was selected.  It rejects macros in the
    user's namespace.  */
 int flag_iso;
@@ -749,6 +761,8 @@ static tree handle_alias_attribute  PARAMS ((tree *, tree, tree, int,
                                                 bool *));
 static tree handle_visibility_attribute        PARAMS ((tree *, tree, tree, int,
                                                 bool *));
+static tree handle_tls_model_attribute PARAMS ((tree *, tree, tree, int,
+                                                bool *));
 static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
                                                             tree, int,
                                                             bool *));
@@ -783,7 +797,6 @@ static void builtin_define_with_hex_fp_value PARAMS ((const char *, tree,
                                                      int, const char *,
                                                      const char *));
 static void builtin_define_type_max PARAMS ((const char *, tree, int));
-static void cpp_define_data_format PARAMS ((cpp_reader *));
 static void builtin_define_type_precision PARAMS ((const char *, tree));
 static void builtin_define_float_constants PARAMS ((const char *,
                                                    const char *, tree));
@@ -848,6 +861,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_vector_size_attribute },
   { "visibility",            1, 1, true,  false, false,
                              handle_visibility_attribute },
+  { "tls_model",             1, 1, true,  false, false,
+                             handle_tls_model_attribute },
   { "nonnull",                0, -1, false, true, true,
                              handle_nonnull_attribute },
   { "nothrow",                0, 0, true,  false, false,
@@ -857,7 +872,7 @@ const struct attribute_spec c_common_attribute_table[] =
 };
 
 /* Give the specifications for the format attributes, used by C and all
-   descendents.  */
+   descendants.  */
 
 const struct attribute_spec c_common_format_attribute_table[] =
 {
@@ -1045,13 +1060,18 @@ finish_fname_decls ()
   
   if (body)
     {
-      /* They were called into existence, so add to statement tree.  */
-      body = chainon (body,
-                     TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)));
-      body = build_stmt (COMPOUND_STMT, body);
-      
-      COMPOUND_STMT_NO_SCOPE (body) = 1;
-      TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)) = body;
+      /* They were called into existence, so add to statement tree.  Add
+        the DECL_STMTs inside the outermost scope.  */
+      tree *p = &DECL_SAVED_TREE (current_function_decl);
+      /* Skip the dummy EXPR_STMT and any EH_SPEC_BLOCK.  */
+      while (TREE_CODE (*p) != COMPOUND_STMT)
+       p = &TREE_CHAIN (*p);
+      p = &COMPOUND_BODY (*p);
+      if (TREE_CODE (*p) == SCOPE_STMT)
+       p = &TREE_CHAIN (*p);
+
+      body = chainon (body, *p);
+      *p = body;
     }
   
   for (ix = 0; fname_vars[ix].decl; ix++)
@@ -1074,7 +1094,7 @@ finish_fname_decls ()
   saved_function_name_decls = stack;
 }
 
-/* Return the text name of the current function, suitable prettified
+/* Return the text name of the current function, suitably prettified
    by PRETTY_P.  */
 
 const char *
@@ -1158,7 +1178,7 @@ fname_decl (rid, id)
     }
   if (!ix && !current_function_decl)
     pedwarn_with_decl (decl, "`%s' is not defined outside of function scope");
-  
+
   return decl;
 }
 
@@ -2040,6 +2060,8 @@ c_common_type_for_mode (mode, unsignedp)
       return unsignedp ? unsigned_V2DI_type_node : V2DI_type_node;
     case V2SImode:
       return unsignedp ? unsigned_V2SI_type_node : V2SI_type_node;
+    case V2HImode:
+      return unsignedp ? unsigned_V2HI_type_node : V2HI_type_node;
     case V4HImode:
       return unsignedp ? unsigned_V4HI_type_node : V4HI_type_node;
     case V8QImode:
@@ -2795,6 +2817,7 @@ c_common_truthvalue_conversion (expr)
     case ABS_EXPR:
     case FLOAT_EXPR:
     case FFS_EXPR:
+    case POPCOUNT_EXPR:
       /* These don't change whether an object is nonzero or zero.  */
       return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
 
@@ -2972,7 +2995,7 @@ c_common_get_alias_set (t)
   if (! TYPE_P (t))
     return -1;
 
-  /* The C standard guarantess that any object may be accessed via an
+  /* The C standard guarantees that any object may be accessed via an
      lvalue that has character type.  */
   if (t == char_type_node
       || t == signed_char_type_node
@@ -3085,7 +3108,7 @@ c_sizeof_or_alignof_type (type, op, complain)
      TYPE_IS_SIZETYPE means that certain things (like overflow) will
      never happen.  However, this node should really have type
      `size_t', which is just a typedef for an ordinary integer type.  */
-  value = fold (build1 (NOP_EXPR, c_size_type_node, value));
+  value = fold (build1 (NOP_EXPR, size_type_node, value));
   my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (value)), 20001021);
   
   return value;
@@ -3136,7 +3159,7 @@ c_alignof_expr (expr)
   else
     return c_alignof (TREE_TYPE (expr));
 
-  return fold (build1 (NOP_EXPR, c_size_type_node, t));
+  return fold (build1 (NOP_EXPR, size_type_node, t));
 }
 \f
 /* Handle C and C++ default attributes.  */
@@ -3180,6 +3203,7 @@ c_common_nodes_and_builtins ()
 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
+#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
 #include "builtin-types.def"
 #undef DEF_PRIMITIVE_TYPE
@@ -3191,6 +3215,7 @@ c_common_nodes_and_builtins ()
 #undef DEF_FUNCTION_TYPE_VAR_0
 #undef DEF_FUNCTION_TYPE_VAR_1
 #undef DEF_FUNCTION_TYPE_VAR_2
+#undef DEF_FUNCTION_TYPE_VAR_3
 #undef DEF_POINTER_TYPE
     BT_LAST
   };
@@ -3279,10 +3304,10 @@ c_common_nodes_and_builtins ()
   /* `unsigned long' is the standard type for sizeof.
      Note that stddef.h uses `unsigned long',
      and this must agree, even if long and int are the same size.  */
-  c_size_type_node =
+  size_type_node =
     TREE_TYPE (identifier_global_value (get_identifier (SIZE_TYPE)));
-  signed_size_type_node = c_common_signed_type (c_size_type_node);
-  set_sizetype (c_size_type_node);
+  signed_size_type_node = c_common_signed_type (size_type_node);
+  set_sizetype (size_type_node);
 
   build_common_tree_nodes_2 (flag_short_double);
 
@@ -3510,6 +3535,19 @@ c_common_nodes_and_builtins ()
                  tree_cons (NULL_TREE,                         \
                             builtin_types[(int) ARG2],         \
                             NULL_TREE)));
+
+#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3)                \
+   builtin_types[(int) ENUM]                                           \
+    = build_function_type                                              \
+      (builtin_types[(int) RETURN],                                    \
+       tree_cons (NULL_TREE,                                           \
+                 builtin_types[(int) ARG1],                            \
+                 tree_cons (NULL_TREE,                                 \
+                            builtin_types[(int) ARG2],                 \
+                            tree_cons (NULL_TREE,                      \
+                                       builtin_types[(int) ARG3],      \
+                                       NULL_TREE))));
+
 #define DEF_POINTER_TYPE(ENUM, TYPE)                   \
   builtin_types[(int) ENUM]                            \
     = build_pointer_type (builtin_types[(int) TYPE]);
@@ -3521,13 +3559,15 @@ c_common_nodes_and_builtins ()
 #undef DEF_FUNCTION_TYPE_4
 #undef DEF_FUNCTION_TYPE_VAR_0
 #undef DEF_FUNCTION_TYPE_VAR_1
+#undef DEF_FUNCTION_TYPE_VAR_2
+#undef DEF_FUNCTION_TYPE_VAR_3
 #undef DEF_POINTER_TYPE
 
   if (!c_attrs_initialized)
     c_init_attributes ();
 
 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE,                  \
-                   BOTH_P, FALLBACK_P, NONANSI_P, ATTRS)               \
+                   BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT)     \
   if (NAME)                                                            \
     {                                                                  \
       tree decl;                                                       \
@@ -3554,6 +3594,8 @@ c_common_nodes_and_builtins ()
                                   built_in_attributes[(int) ATTRS]);   \
                                                                        \
       built_in_decls[(int) ENUM] = decl;                               \
+      if (IMPLICIT)                                                    \
+        implicit_built_in_decls[(int) ENUM] = decl;                    \
     }                                                                  
 #include "builtins.def"
 #undef DEF_BUILTIN
@@ -4485,9 +4527,9 @@ c_expand_builtin_printf (arglist, target, tmode, modifier, ignore, unlocked)
      int unlocked;
 {
   tree fn_putchar = unlocked ?
-    built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : built_in_decls[BUILT_IN_PUTCHAR];
+    implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTCHAR];
   tree fn_puts = unlocked ?
-    built_in_decls[BUILT_IN_PUTS_UNLOCKED] : built_in_decls[BUILT_IN_PUTS];
+    implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTS];
   tree fn, format_arg, stripped_string;
 
   /* If the return value is used, or the replacement _DECL isn't
@@ -4589,9 +4631,9 @@ c_expand_builtin_fprintf (arglist, target, tmode, modifier, ignore, unlocked)
      int unlocked;
 {
   tree fn_fputc = unlocked ?
-    built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : built_in_decls[BUILT_IN_FPUTC];
+    implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTC];
   tree fn_fputs = unlocked ?
-    built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : built_in_decls[BUILT_IN_FPUTS];
+    implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTS];
   tree fn, format_arg, stripped_string;
 
   /* If the return value is used, or the replacement _DECL isn't
@@ -4701,44 +4743,6 @@ boolean_increment (code, arg)
   return val;
 }
 \f
-/* Define macros necessary to describe fundamental data type formats.  */
-static void
-cpp_define_data_format (pfile)
-    cpp_reader *pfile;
-{
-  const char *format;
-
-  /* Define supported floating-point format enumeration values.  */
-  cpp_define (pfile, "__UNKNOWN_FORMAT__=0");
-  cpp_define (pfile, "__IEEE_FORMAT__=1");
-  cpp_define (pfile, "__IBM_FORMAT__=2");
-  cpp_define (pfile, "__C4X_FORMAT__=3");
-  cpp_define (pfile, "__VAX_FORMAT__=4");
-  
-  switch (TARGET_FLOAT_FORMAT)
-    {
-    case UNKNOWN_FLOAT_FORMAT:
-      format = "__UNKNOWN_FORMAT__";
-      break;
-    case IEEE_FLOAT_FORMAT:
-      format = "__IEEE_FORMAT__";
-      break;
-    case VAX_FLOAT_FORMAT:
-      format = "__VAX_FORMAT__";
-      break;
-    case IBM_FLOAT_FORMAT:
-      format = "__IBM_FORMAT__";
-      break;
-    case C4X_FLOAT_FORMAT:
-      format = "__C4X_FORMAT__";
-      break;
-    default:
-      abort();
-    }
-
-  builtin_define_with_value ("__GCC_FLOAT_FORMAT__", format, 0);
-}
-
 /* Define NAME with value TYPE precision.  */
 static void
 builtin_define_type_precision (name, type)
@@ -4910,6 +4914,18 @@ builtin_define_float_constants (name_prefix, fp_suffix, type)
       sprintf (buf, "0.0%s", fp_suffix);
       builtin_define_with_value (name, buf, 0);
     }
+
+  /* For C++ std::numeric_limits<T>::has_infinity.  */
+  sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
+  builtin_define_with_int_value (name, 
+                                MODE_HAS_INFINITIES (TYPE_MODE (type)));
+  /* For C++ std::numeric_limits<T>::has_quiet_NaN.  We do not have a
+     predicate to distinguish a target that has both quiet and
+     signalling NaNs from a target that has only quiet NaNs or only
+     signalling NaNs, so we assume that a target that has any kind of
+     NaN has quiet NaNs.  */
+  sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix);
+  builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
 }
 
 /* Hook that registers front end and target-specific built-ins.  */
@@ -4953,17 +4969,9 @@ cb_register_builtins (pfile)
   builtin_define_type_max ("__INT_MAX__", integer_type_node, 0);
   builtin_define_type_max ("__LONG_MAX__", long_integer_type_node, 1);
   builtin_define_type_max ("__LONG_LONG_MAX__", long_long_integer_type_node, 2);
+  builtin_define_type_max ("__WCHAR_MAX__", wchar_type_node, 0);
 
   builtin_define_type_precision ("__CHAR_BIT__", char_type_node);
-  builtin_define_type_precision ("__WCHAR_BIT__", wchar_type_node);
-  builtin_define_type_precision ("__SHRT_BIT__", short_integer_type_node);
-  builtin_define_type_precision ("__INT_BIT__", integer_type_node);
-  builtin_define_type_precision ("__LONG_BIT__", long_integer_type_node);
-  builtin_define_type_precision ("__LONG_LONG_BIT__",
-                                 long_long_integer_type_node);
-  builtin_define_type_precision ("__FLOAT_BIT__", float_type_node);
-  builtin_define_type_precision ("__DOUBLE_BIT__", double_type_node);
-  builtin_define_type_precision ("__LONG_DOUBLE_BIT__", long_double_type_node);
 
   /* float.h needs to know these.  */
 
@@ -4995,7 +5003,7 @@ cb_register_builtins (pfile)
 
   if (fast_math_flags_set_p ())
     cpp_define (pfile, "__FAST_MATH__");
-  if (flag_no_inline)
+  if (flag_really_no_inline)
     cpp_define (pfile, "__NO_INLINE__");
   if (flag_signaling_nans)
     cpp_define (pfile, "__SUPPORT_SNAN__");
@@ -5013,8 +5021,6 @@ cb_register_builtins (pfile)
   if (c_language == clk_cplusplus && TREE_UNSIGNED (wchar_type_node))
     cpp_define (pfile, "__WCHAR_UNSIGNED__");
 
-  cpp_define_data_format (pfile);
-  
   /* Make the choice of ObjC runtime visible to source code.  */
   if (flag_objc && flag_next_runtime)
     cpp_define (pfile, "__NEXT_RUNTIME__");
@@ -5143,14 +5149,15 @@ builtin_define_with_hex_fp_value (macro, type, digits, hex_str, fp_suffix)
      then print it back out as decimal.  */
 
   real_from_string (&real, hex_str);
-  real_to_decimal (dec_str, &real, digits);
+  real_to_decimal (dec_str, &real, sizeof (dec_str), digits, 0);
 
   sprintf (buf, "%s=%s%s", macro, dec_str, fp_suffix);
   cpp_define (parse_in, buf);
 }
 
-/* Define MAX for TYPE based on the precision of the type, which is assumed
-   to be signed.  IS_LONG is 1 for type "long" and 2 for "long long".  */
+/* Define MAX for TYPE based on the precision of the type.  IS_LONG is
+   1 for type "long" and 2 for "long long".  We have to handle
+   unsigned types, since wchar_t might be unsigned.  */
 
 static void
 builtin_define_type_max (macro, type, is_long)
@@ -5158,41 +5165,37 @@ builtin_define_type_max (macro, type, is_long)
      tree type;
      int is_long;
 {
-  const char *value;
+  static const char *const values[]
+    = { "127", "255",
+       "32767", "65535",
+       "2147483647", "4294967295",
+       "9223372036854775807", "18446744073709551615",
+       "170141183460469231731687303715884105727",
+       "340282366920938463463374607431768211455" };
+  static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
+
+  const char *value, *suffix;
   char *buf;
-  size_t mlen, vlen, extra;
+  size_t idx;
 
   /* Pre-rendering the values mean we don't have to futz with printing a
      multi-word decimal value.  There are also a very limited number of
      precisions that we support, so it's really a waste of time.  */
   switch (TYPE_PRECISION (type))
     {
-    case 8:
-      value = "127";
-      break;
-    case 16:
-      value = "32767";
-      break;
-    case 32:
-      value = "2147483647";
-      break;
-    case 64:
-      value = "9223372036854775807";
-      break;
-    case 128:
-      value = "170141183460469231731687303715884105727";
-      break;
-    default:
-      abort ();
+    case 8:    idx = 0; break;
+    case 16:   idx = 2; break;
+    case 32:   idx = 4; break;
+    case 64:   idx = 6; break;
+    case 128:  idx = 8; break;
+    default:    abort ();
     }
 
-  mlen = strlen (macro);
-  vlen = strlen (value);
-  extra = 2 + is_long;
-  buf = alloca (mlen + vlen + extra);
+  value = values[idx + TREE_UNSIGNED (type)];
+  suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)];
 
-  sprintf (buf, "%s=%s%s", macro, value,
-          (is_long == 1 ? "L" : is_long == 2 ? "LL" : ""));
+  buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1);
+  sprintf (buf, "%s=%s%s", macro, value, suffix);
 
   cpp_define (parse_in, buf);
 }
@@ -5429,16 +5432,19 @@ handle_always_inline_attribute (node, name, args, flags, no_add_attrs)
    struct attribute_spec.handler.  */
 
 static tree
-handle_used_attribute (node, name, args, flags, no_add_attrs)
-     tree *node;
+handle_used_attribute (pnode, name, args, flags, no_add_attrs)
+     tree *pnode;
      tree name;
      tree args ATTRIBUTE_UNUSED;
      int flags ATTRIBUTE_UNUSED;
      bool *no_add_attrs;
 {
-  if (TREE_CODE (*node) == FUNCTION_DECL)
-    TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (*node))
-      = TREE_USED (*node) = 1;
+  tree node = *pnode;
+
+  if (TREE_CODE (node) == FUNCTION_DECL
+      || (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node)))
+    TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (node))
+      = TREE_USED (node) = 1;
   else
     {
       warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
@@ -5647,6 +5653,7 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
       int len = strlen (p);
       enum machine_mode mode = VOIDmode;
       tree typefm;
+      tree ptr_type;
 
       if (len > 4 && p[0] == '_' && p[1] == '_'
          && p[len - 1] == '_' && p[len - 2] == '_')
@@ -5676,6 +5683,10 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
       else if (0 == (typefm = (*lang_hooks.types.type_for_mode)
                     (mode, TREE_UNSIGNED (type))))
        error ("no data type for mode `%s'", p);
+      else if ((TREE_CODE (type) == POINTER_TYPE
+               || TREE_CODE (type) == REFERENCE_TYPE)
+              && !(*targetm.valid_pointer_mode) (mode))
+       error ("invalid pointer mode `%s'", p);
       else
        {
          /* If this is a vector, make sure we either have hardware
@@ -5688,6 +5699,19 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
              return NULL_TREE;
            }
 
+         if (TREE_CODE (type) == POINTER_TYPE)
+           {
+             ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
+                                                     mode);
+             *node = ptr_type;
+           }
+         else if (TREE_CODE (type) == REFERENCE_TYPE)
+           {
+             ptr_type = build_reference_type_for_mode (TREE_TYPE (type),
+                                                       mode);
+             *node = ptr_type;
+           }
+         else
          *node = typefm;
          /* No need to layout the type here.  The caller should do this.  */
        }
@@ -5934,9 +5958,53 @@ handle_visibility_attribute (node, name, args, flags, no_add_attrs)
        }
       if (strcmp (TREE_STRING_POINTER (id), "hidden")
          && strcmp (TREE_STRING_POINTER (id), "protected")
-         && strcmp (TREE_STRING_POINTER (id), "internal"))
+         && strcmp (TREE_STRING_POINTER (id), "internal")
+         && strcmp (TREE_STRING_POINTER (id), "default"))
+       {
+         error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
+         *no_add_attrs = true;
+         return NULL_TREE;
+       }
+    }
+
+  return NULL_TREE;
+}
+
+/* Handle an "tls_model" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_tls_model_attribute (node, name, args, flags, no_add_attrs)
+     tree *node;
+     tree name;
+     tree args;
+     int flags ATTRIBUTE_UNUSED;
+     bool *no_add_attrs;
+{
+  tree decl = *node;
+
+  if (! DECL_THREAD_LOCAL (decl))
+    {
+      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+  else
+    {
+      tree id;
+
+      id = TREE_VALUE (args);
+      if (TREE_CODE (id) != STRING_CST)
+       {
+         error ("tls_model arg not a string");
+         *no_add_attrs = true;
+         return NULL_TREE;
+       }
+      if (strcmp (TREE_STRING_POINTER (id), "local-exec")
+         && strcmp (TREE_STRING_POINTER (id), "initial-exec")
+         && strcmp (TREE_STRING_POINTER (id), "local-dynamic")
+         && strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
        {
-         error ("visibility arg must be one of \"hidden\", \"protected\" or \"internal\"");
+         error ("tls_model arg must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
          *no_add_attrs = true;
          return NULL_TREE;
        }
@@ -6123,7 +6191,7 @@ handle_deprecated_attribute (node, name, args, flags, no_add_attrs)
    The normal mechanism to prevent duplicates is to use type_hash_canon, but
    since we want to distinguish types that are essentially identical (except
    for their debug representation), we use a local list here.  */
-static tree vector_type_node_list = 0;
+static GTY(()) tree vector_type_node_list = 0;
 
 /* Handle a "vector_size" attribute; arguments as in
    struct attribute_spec.handler.  */
@@ -6322,7 +6390,7 @@ handle_nonnull_attribute (node, name, args, flags, no_add_attrs)
   unsigned HOST_WIDE_INT attr_arg_num;
 
   /* If no arguments are specified, all pointer arguments should be
-     non-null.  Veryify a full prototype is given so that the arguments
+     non-null.  Verify a full prototype is given so that the arguments
      will have the correct types when we actually check them later.  */
   if (! args)
     {