]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/c-decl.c
ada-tree.h (union lang_tree_node): Check for TS_COMMON before calling TREE_CHAIN.
[thirdparty/gcc.git] / gcc / c-decl.c
index 7d27dfe8f0f0078f928381a2adebd3a11556bdb5..34362788826c263115aded51fe7f0670b97db40d 100644 (file)
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #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-lang.h"
 #include "langhooks.h"
@@ -241,7 +242,7 @@ extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
 /* The resulting tree type.  */
 
 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
-       chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))")))  lang_tree_node
+       chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))  lang_tree_node
  {
   union tree_node GTY ((tag ("0"),
                        desc ("tree_node_structure (&%h)")))
@@ -403,6 +404,13 @@ struct GTY((chain_next ("%h.outer"))) c_scope {
      up searching for labels when popping scopes, particularly since
      labels are normally only found at function scope.  */
   BOOL_BITFIELD has_label_bindings : 1;
+
+  /* True if we should issue a warning if a goto statement crosses any
+     of the bindings.  We still need to check the list of bindings to
+     find the specific ones we need to warn about.  This is true if
+     decl_jump_unsafe would return true for any of the bindings.  This
+     is used to avoid looping over all the bindings unnecessarily.  */
+  BOOL_BITFIELD has_jump_unsafe_decl : 1;
 };
 
 /* The scope currently in effect.  */
@@ -553,6 +561,31 @@ add_stmt (tree t)
   return t;
 }
 \f
+/* Return true if we will want to say something if a goto statement
+   crosses DECL.  */
+
+static bool
+decl_jump_unsafe (tree decl)
+{
+  if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
+    return false;
+
+  /* Always warn about crossing variably modified types.  */
+  if ((TREE_CODE (decl) == VAR_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
+      && !TREE_STATIC (decl)
+      && DECL_INITIAL (decl) != NULL_TREE)
+    return true;
+
+  return false;
+}
+\f
 
 void
 c_print_identifier (FILE *file, tree node, int indent)
@@ -601,6 +634,9 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible,
   b->prev = scope->bindings;
   scope->bindings = b;
 
+  if (decl_jump_unsafe (decl))
+    scope->has_jump_unsafe_decl = 1;
+
   if (!name)
     return;
 
@@ -757,31 +793,6 @@ set_spot_bindings (struct c_spot_bindings *p, bool defining)
   p->left_stmt_expr = false;
 }
 
-/* Return true if we will want to say something if a goto statement
-   crosses DECL.  */
-
-static bool
-decl_jump_unsafe (tree decl)
-{
-  if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
-    return false;
-
-  /* Always warn about crossing variably modified types.  */
-  if ((TREE_CODE (decl) == VAR_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
-      && !TREE_STATIC (decl)
-      && DECL_INITIAL (decl) != NULL_TREE)
-    return true;
-
-  return false;
-}
-
 /* Update spot bindings P as we pop out of SCOPE.  Return true if we
    should push decls for a label.  */
 
@@ -968,6 +979,7 @@ update_label_decls (struct c_scope *scope)
            {
              struct c_label_vars *label_vars;
              struct c_binding *b1;
+             bool hjud;
              unsigned int ix;
              struct c_goto_bindings *g;
 
@@ -976,18 +988,26 @@ update_label_decls (struct c_scope *scope)
              label_vars = b->u.label;
 
              b1 = label_vars->label_bindings.bindings_in_scope;
+             if (label_vars->label_bindings.scope == NULL)
+               hjud = false;
+             else
+               hjud = label_vars->label_bindings.scope->has_jump_unsafe_decl;
              if (update_spot_bindings (scope, &label_vars->label_bindings))
                {
                  /* This label is defined in this scope.  */
-                 for (; b1 != NULL;  b1 = b1->prev)
+                 if (hjud)
                    {
-                     /* A goto from later in the function to this
-                        label will never see the initialization of
-                        B1, if any.  Save it to issue a warning if
-                        needed.  */
-                     if (decl_jump_unsafe (b1->decl))
-                       VEC_safe_push (tree, gc, label_vars->decls_in_scope,
-                                      b1->decl);
+                     for (; b1 != NULL; b1 = b1->prev)
+                       {
+                         /* A goto from later in the function to this
+                            label will never see the initialization
+                            of B1, if any.  Save it to issue a
+                            warning if needed.  */
+                         if (decl_jump_unsafe (b1->decl))
+                           VEC_safe_push (tree, gc,
+                                          label_vars->decls_in_scope,
+                                          b1->decl);
+                       }
                    }
                }
 
@@ -1500,9 +1520,8 @@ diagnose_arglist_conflict (tree newdecl, tree olddecl,
 
   if (TREE_CODE (olddecl) != FUNCTION_DECL
       || !comptypes (TREE_TYPE (oldtype), TREE_TYPE (newtype))
-      || !((TYPE_ARG_TYPES (oldtype) == 0 && DECL_INITIAL (olddecl) == 0)
-          ||
-          (TYPE_ARG_TYPES (newtype) == 0 && DECL_INITIAL (newdecl) == 0)))
+      || !((!prototype_p (oldtype) && DECL_INITIAL (olddecl) == 0)
+          || (!prototype_p (newtype) && DECL_INITIAL (newdecl) == 0)))
     return;
 
   t = TYPE_ARG_TYPES (oldtype);
@@ -1794,20 +1813,16 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          || TREE_NO_WARNING (olddecl))
        return true;  /* Allow OLDDECL to continue in use.  */
 
-      if (pedantic && !flag_isoc1x)
+      if (variably_modified_type_p (newtype, NULL))
        {
-         pedwarn (input_location, OPT_pedantic,
-                  "redefinition of typedef %q+D", newdecl);
+         error ("redefinition of typedef %q+D with variably modified type",
+                newdecl);
          locate_old_decl (olddecl);
        }
-      else if (variably_modified_type_p (newtype, NULL))
+      else if (pedantic && !flag_isoc1x)
        {
-         /* Whether there is a constraint violation for the types not
-            being the same cannot be determined at compile time; a
-            warning that there may be one at runtime is considered
-            appropriate (WG14 reflector message 11743, 8 May 2009).  */
-         warning (0, "redefinition of typedef %q+D may be a constraint "
-                  "violation at runtime", newdecl);
+         pedwarn (input_location, OPT_pedantic,
+                  "redefinition of typedef %q+D", newdecl);
          locate_old_decl (olddecl);
        }
 
@@ -1832,7 +1847,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
          && !C_DECL_DECLARED_BUILTIN (olddecl)
          && (!TREE_PUBLIC (newdecl)
              || (DECL_INITIAL (newdecl)
-                 && !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
+                 && !prototype_p (TREE_TYPE (newdecl)))))
        {
          warning (OPT_Wshadow, "declaration of %q+D shadows "
                   "a built-in function", newdecl);
@@ -1869,7 +1884,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
       /* If we have a prototype after an old-style function definition,
         the argument types must be checked specially.  */
       else if (DECL_INITIAL (olddecl)
-              && !TYPE_ARG_TYPES (oldtype) && TYPE_ARG_TYPES (newtype)
+              && !prototype_p (oldtype) && prototype_p (newtype)
               && TYPE_ACTUAL_ARG_TYPES (oldtype)
               && !validate_proto_after_old_defn (newdecl, newtype, oldtype))
        {
@@ -2138,9 +2153,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
   bool new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
                            && DECL_INITIAL (newdecl) != 0);
   bool new_is_prototype = (TREE_CODE (newdecl) == FUNCTION_DECL
-                          && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0);
+                          && prototype_p (TREE_TYPE (newdecl)));
   bool old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL
-                          && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) != 0);
+                          && prototype_p (TREE_TYPE (olddecl)));
   bool extern_changed = false;
 
   /* For real parm decl following a forward decl, rechain the old decl
@@ -3013,7 +3028,7 @@ lookup_label (tree name)
   tree label;
   struct c_label_vars *label_vars;
 
-  if (current_function_decl == 0)
+  if (current_function_scope == 0)
     {
       error ("label %qE referenced outside of any function", name);
       return 0;
@@ -3165,12 +3180,15 @@ check_earlier_gotos (tree label, struct c_label_vars* label_vars)
       /* We have a goto to this label.  The goto is going forward.  In
         g->scope, the goto is going to skip any binding which was
         defined after g->bindings_in_scope.  */
-      for (b = g->goto_bindings.scope->bindings;
-          b != g->goto_bindings.bindings_in_scope;
-          b = b->prev)
+      if (g->goto_bindings.scope->has_jump_unsafe_decl)
        {
-         if (decl_jump_unsafe (b->decl))
-           warn_about_goto (g->loc, label, b->decl);
+         for (b = g->goto_bindings.scope->bindings;
+              b != g->goto_bindings.bindings_in_scope;
+              b = b->prev)
+           {
+             if (decl_jump_unsafe (b->decl))
+               warn_about_goto (g->loc, label, b->decl);
+           }
        }
 
       /* We also need to warn about decls defined in any scopes
@@ -3180,14 +3198,17 @@ check_earlier_gotos (tree label, struct c_label_vars* label_vars)
           scope = scope->outer)
        {
          gcc_assert (scope != NULL);
-         if (scope == label_vars->label_bindings.scope)
-           b = label_vars->label_bindings.bindings_in_scope;
-         else
-           b = scope->bindings;
-         for (; b != NULL; b = b->prev)
+         if (scope->has_jump_unsafe_decl)
            {
-             if (decl_jump_unsafe (b->decl))
-               warn_about_goto (g->loc, label, b->decl);
+             if (scope == label_vars->label_bindings.scope)
+               b = label_vars->label_bindings.bindings_in_scope;
+             else
+               b = scope->bindings;
+             for (; b != NULL; b = b->prev)
+               {
+                 if (decl_jump_unsafe (b->decl))
+                   warn_about_goto (g->loc, label, b->decl);
+               }
            }
        }
 
@@ -3303,6 +3324,10 @@ c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings,
       struct c_binding *b;
 
       gcc_assert (scope != NULL);
+
+      if (!scope->has_jump_unsafe_decl)
+       continue;
+
       for (b = scope->bindings; b != NULL; b = b->prev)
        {
          if (decl_jump_unsafe (b->decl))
@@ -3538,7 +3563,7 @@ c_builtin_function (tree decl)
   tree   id = DECL_NAME (decl);
 
   const char *name = IDENTIFIER_POINTER (id);
-  C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0);
+  C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type);
 
   /* Should never be called on a symbol with a preexisting meaning.  */
   gcc_assert (!I_SYMBOL_BINDING (id));
@@ -3564,7 +3589,7 @@ c_builtin_function_ext_scope (tree decl)
   tree   id = DECL_NAME (decl);
 
   const char *name = IDENTIFIER_POINTER (id);
-  C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0);
+  C_DECL_BUILTIN_PROTOTYPE (decl) = prototype_p (type);
 
   /* Should never be called on a symbol with a preexisting meaning.  */
   gcc_assert (!I_SYMBOL_BINDING (id));
@@ -3634,7 +3659,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
                  warned = 1;
                }
            }
-         else if (!declspecs->tag_defined_p
+         else if (declspecs->typespec_kind != ctsk_tagdef
+                   && declspecs->typespec_kind != ctsk_tagfirstref
                   && declspecs->storage_class != csc_none)
            {
              if (warned != 1)
@@ -3644,7 +3670,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
              warned = 1;
              pending_xref_error ();
            }
-         else if (!declspecs->tag_defined_p
+         else if (declspecs->typespec_kind != ctsk_tagdef
+                   && declspecs->typespec_kind != ctsk_tagfirstref
                   && (declspecs->const_p
                       || declspecs->volatile_p
                       || declspecs->restrict_p
@@ -3998,7 +4025,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
      prototypes file (if requested).  */
 
   if (TREE_CODE (decl) == FUNCTION_DECL)
-    gen_aux_info_record (decl, 0, 0, TYPE_ARG_TYPES (TREE_TYPE (decl)) != 0);
+    gen_aux_info_record (decl, 0, 0, prototype_p (TREE_TYPE (decl)));
 
   /* ANSI specifies that a tentative definition which is not merged with
      a non-tentative definition behaves exactly like a definition with an
@@ -4580,7 +4607,9 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const)
 void
 check_compound_literal_type (location_t loc, struct c_type_name *type_name)
 {
-  if (warn_cxx_compat && type_name->specs->tag_defined_p)
+  if (warn_cxx_compat
+      && (type_name->specs->typespec_kind == ctsk_tagdef
+          || type_name->specs->typespec_kind == ctsk_tagfirstref))
     warning_at (loc, OPT_Wc___compat,
                "defining a type in a compound literal is invalid in C++");
 }
@@ -4859,7 +4888,10 @@ grokdeclarator (const struct c_declarator *declarator,
   const char *errmsg;
   tree expr_dummy;
   bool expr_const_operands_dummy;
+  enum c_declarator_kind first_non_attr_kind;
 
+  if (TREE_CODE (type) == ERROR_MARK)
+    return error_mark_node;
   if (expr == NULL)
     expr = &expr_dummy;
   if (expr_const_operands == NULL)
@@ -4876,6 +4908,7 @@ grokdeclarator (const struct c_declarator *declarator,
   {
     const struct c_declarator *decl = declarator;
 
+    first_non_attr_kind = cdk_attrs;
     while (decl)
       switch (decl->kind)
        {
@@ -4887,6 +4920,8 @@ grokdeclarator (const struct c_declarator *declarator,
        case cdk_pointer:
          funcdef_syntax = (decl->kind == cdk_function);
          decl = decl->declarator;
+         if (first_non_attr_kind == cdk_attrs)
+           first_non_attr_kind = decl->kind;
          break;
 
        case cdk_attrs:
@@ -4897,6 +4932,8 @@ grokdeclarator (const struct c_declarator *declarator,
          loc = decl->id_loc;
          if (decl->u.id)
            name = decl->u.id;
+         if (first_non_attr_kind == cdk_attrs)
+           first_non_attr_kind = decl->kind;
          decl = 0;
          break;
 
@@ -5003,7 +5040,9 @@ grokdeclarator (const struct c_declarator *declarator,
     error_at (loc, "conflicting named address spaces (%s vs %s)",
              c_addr_space_name (as1), c_addr_space_name (as2));
 
-  if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
+  if ((TREE_CODE (type) == ARRAY_TYPE
+       || first_non_attr_kind == cdk_array)
+      && TYPE_QUALS (element_type))
     type = TYPE_MAIN_VARIANT (type);
   type_quals = ((constp ? TYPE_QUAL_CONST : 0)
                | (restrictp ? TYPE_QUAL_RESTRICT : 0)
@@ -5411,7 +5450,7 @@ grokdeclarator (const struct c_declarator *declarator,
                  }
              }
 
-            /* Complain about arrays of incomplete types.  */
+           /* Complain about arrays of incomplete types.  */
            if (!COMPLETE_TYPE_P (type))
              {
                error_at (loc, "array type has incomplete element type");
@@ -5897,7 +5936,7 @@ grokdeclarator (const struct c_declarator *declarator,
        if (storage_class == csc_register || threadp)
          {
            error_at (loc, "invalid storage class for function %qE", name);
-          }
+         }
        else if (current_scope != file_scope)
          {
            /* Function declaration not at file scope.  Storage
@@ -6127,9 +6166,13 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
   else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
     {
       if (!funcdef_flag)
-       pedwarn (input_location, 0, "parameter names (without types) in function declaration");
+       {
+         pedwarn (input_location, 0, "parameter names (without types) in function declaration");
+         arg_info->parms = NULL_TREE;
+       }
+      else
+       arg_info->parms = arg_info->types;
 
-      arg_info->parms = arg_info->types;
       arg_info->types = 0;
       return 0;
     }
@@ -6635,11 +6678,14 @@ grokfield (location_t loc,
                      || TREE_CODE (type) == UNION_TYPE);
       bool ok = false;
 
-      if (type_ok)
+      if (type_ok
+         && (flag_ms_extensions
+             || flag_plan9_extensions
+             || !declspecs->typedef_p))
        {
          if (flag_ms_extensions || flag_plan9_extensions)
            ok = true;
-         else if (TYPE_NAME (TYPE_MAIN_VARIANT (type)) == NULL)
+         else if (TYPE_NAME (type) == NULL)
            ok = true;
          else
            ok = false;
@@ -6795,11 +6841,9 @@ detect_field_duplicates (tree fieldlist)
 
   /* First, see if there are more than "a few" fields.
      This is trivially true if there are zero or one fields.  */
-  if (!fieldlist)
-    return;
-  x = DECL_CHAIN (fieldlist);
-  if (!x)
+  if (!fieldlist || !DECL_CHAIN (fieldlist))
     return;
+  x = fieldlist;
   do {
     timeout--;
     if (DECL_NAME (x) == NULL_TREE
@@ -7614,7 +7658,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   current_function_prototype_locus = UNKNOWN_LOCATION;
   current_function_prototype_built_in = false;
   current_function_prototype_arg_types = NULL_TREE;
-  if (TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
+  if (!prototype_p (TREE_TYPE (decl1)))
     {
       if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
          && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
@@ -7663,7 +7707,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   /* Optionally warn of old-fashioned def with no previous prototype.  */
   if (warn_strict_prototypes
       && old_decl != error_mark_node
-      && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
+      && !prototype_p (TREE_TYPE (decl1))
       && C_DECL_ISNT_PROTOTYPE (old_decl))
     warning_at (loc, OPT_Wstrict_prototypes,
                "function declaration isn%'t a prototype");
@@ -7681,7 +7725,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
           && old_decl != 0
           && old_decl != error_mark_node
           && TREE_USED (old_decl)
-          && TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
+          && !prototype_p (TREE_TYPE (old_decl)))
     warning_at (loc, OPT_Wmissing_prototypes,
                "%qD was used with no prototype before its definition", decl1);
   /* Optionally warn of any global def with no previous declaration.  */
@@ -7847,6 +7891,9 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
       if (b && B_IN_CURRENT_SCOPE (b))
        {
          decl = b->decl;
+         /* Skip erroneous parameters.  */
+         if (decl == error_mark_node)
+           continue;
          /* If we got something other than a PARM_DECL it is an error.  */
          if (TREE_CODE (decl) != PARM_DECL)
            error_at (DECL_SOURCE_LOCATION (decl),
@@ -8177,6 +8224,9 @@ void
 finish_function (void)
 {
   tree fndecl = current_function_decl;
+  
+  if (c_dialect_objc ())
+    objc_finish_function ();
 
   if (TREE_CODE (fndecl) == FUNCTION_DECL
       && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
@@ -8295,7 +8345,7 @@ finish_function (void)
          /* 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_node (fndecl);
+         (void) cgraph_get_create_node (fndecl);
        }
     }
 
@@ -8613,10 +8663,9 @@ build_null_declspecs (void)
   ret->storage_class = csc_none;
   ret->expr_const_operands = true;
   ret->declspecs_seen_p = false;
-  ret->type_seen_p = false;
+  ret->typespec_kind = ctsk_none;
   ret->non_sc_seen_p = false;
   ret->typedef_p = false;
-  ret->tag_defined_p = false;
   ret->explicit_signed_p = false;
   ret->deprecated_p = false;
   ret->default_int_p = false;
@@ -8700,7 +8749,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
   tree type = spec.spec;
   specs->non_sc_seen_p = true;
   specs->declspecs_seen_p = true;
-  specs->type_seen_p = true;
+  specs->typespec_kind = spec.kind;
   if (TREE_DEPRECATED (type))
     specs->deprecated_p = true;
 
@@ -9301,11 +9350,9 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
       else
        specs->type = TREE_TYPE (t);
     }
-  else if (TREE_CODE (type) != ERROR_MARK)
+  else
     {
-      if (spec.kind == ctsk_tagdef || spec.kind == ctsk_tagfirstref)
-       specs->tag_defined_p = true;
-      if (spec.kind == ctsk_typeof)
+      if (TREE_CODE (type) != ERROR_MARK && spec.kind == ctsk_typeof)
        {
          specs->typedef_p = true;
          if (spec.expr)
@@ -9435,6 +9482,10 @@ finish_declspecs (struct c_declspecs *specs)
       gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
                  && !specs->signed_p && !specs->unsigned_p
                  && !specs->complex_p);
+
+      /* Set a dummy type.  */
+      if (TREE_CODE (specs->type) == ERROR_MARK)
+        specs->type = integer_type_node;
       return specs;
     }