re PR target/11689 (g++3.3 emits un-assembleable code for k6 architecture)
[platform/upstream/gcc.git] / gcc / c-decl.c
index 20b9b67..f4896f3 100644 (file)
@@ -1761,7 +1761,8 @@ pushdecl (tree x)
          if ((TREE_CODE (element) == RECORD_TYPE
               || TREE_CODE (element) == UNION_TYPE)
              && (TREE_CODE (x) != TYPE_DECL
-                 || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE))
+                 || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
+             && !COMPLETE_TYPE_P (element))
            C_TYPE_INCOMPLETE_VARS (element)
              = tree_cons (NULL_TREE, x, C_TYPE_INCOMPLETE_VARS (element));
        }
@@ -2672,6 +2673,26 @@ start_decl (tree declarator, tree declspecs, int initialized, tree attributes)
   decl_attributes (&decl, attributes, 0);
 
   if (TREE_CODE (decl) == FUNCTION_DECL
+      && targetm.calls.promote_prototypes (TREE_TYPE (decl)))
+    {
+      tree ce = declarator;
+
+      if (TREE_CODE (ce) == INDIRECT_REF)
+       ce = TREE_OPERAND (declarator, 0);
+      if (TREE_CODE (ce) == CALL_EXPR)
+       {
+         tree args = TREE_PURPOSE (TREE_OPERAND (ce, 1));
+         for (; args; args = TREE_CHAIN (args))
+           {
+             tree type = TREE_TYPE (args);
+             if (INTEGRAL_TYPE_P (type)
+                 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+               DECL_ARG_TYPE (args) = integer_type_node;
+           }
+       }
+    }
+
+  if (TREE_CODE (decl) == FUNCTION_DECL
       && DECL_DECLARED_INLINE_P (decl)
       && DECL_UNINLINABLE (decl)
       && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
@@ -4573,10 +4594,6 @@ get_parm_info (int void_at_end)
         declared types.  The back end may override this.  */
       type = TREE_TYPE (decl);
       DECL_ARG_TYPE (decl) = type;
-      if (PROMOTE_PROTOTYPES
-         && INTEGRAL_TYPE_P (type)
-         && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
-       DECL_ARG_TYPE (decl) = integer_type_node;
 
       /* Check for (..., void, ...) and issue an error.  */
       if (VOID_TYPE_P (type) && !DECL_NAME (decl) && !gave_void_only_once_err)
@@ -5898,7 +5915,7 @@ store_parm_decls_oldstyle (void)
                     useful for argument types like uid_t.  */
                  DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
 
-                 if (PROMOTE_PROTOTYPES
+                 if (targetm.calls.promote_prototypes (TREE_TYPE (current_function_decl))
                      && INTEGRAL_TYPE_P (TREE_TYPE (parm))
                      && TYPE_PRECISION (TREE_TYPE (parm))
                      < TYPE_PRECISION (integer_type_node))
@@ -6027,13 +6044,10 @@ store_parm_decls (void)
    all the way to assembler language output.  The free the storage
    for the function definition.
 
-   This is called after parsing the body of the function definition.
-
-   NESTED is nonzero if the function being finished is nested in another.
-   CAN_DEFER_P is nonzero if the function may be deferred.  */
+   This is called after parsing the body of the function definition.  */
 
 void
-finish_function (int nested, int can_defer_p)
+finish_function ()
 {
   tree fndecl = current_function_decl;
 
@@ -6053,6 +6067,19 @@ finish_function (int nested, int can_defer_p)
       poplevel (0, 0, 0);
     }
 
+  if (TREE_CODE (fndecl) == FUNCTION_DECL
+      && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
+    {
+      tree args = DECL_ARGUMENTS (fndecl);
+      for (; args; args = TREE_CHAIN (args))
+       {
+         tree type = TREE_TYPE (args);
+         if (INTEGRAL_TYPE_P (type)
+             && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+           DECL_ARG_TYPE (args) = integer_type_node;
+       }
+    }
+
   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
 
   /* Must mark the RESULT_DECL as being in this function.  */
@@ -6102,78 +6129,24 @@ finish_function (int nested, int can_defer_p)
       && DECL_INLINE (fndecl))
     warning ("no return statement in function returning non-void");
 
+  /* With just -Wextra, complain only if function returns both with
+     and without a value.  */
+  if (extra_warnings
+      && current_function_returns_value
+      && current_function_returns_null)
+    warning ("this function may return with or without a value");
+
   /* We're leaving the context of this function, so zap cfun.  It's still in
      DECL_SAVED_INSNS, and we'll restore it in tree_rest_of_compilation.  */
   cfun = NULL;
 
-  if (flag_unit_at_a_time && can_defer_p)
-    {
-      cgraph_finalize_function (fndecl, DECL_SAVED_TREE (fndecl));
-      current_function_decl = NULL;
-      return;
-    }
-
-  if (! nested)
-    {
-      /* Function is parsed.
-        Generate RTL for the body of this function or defer
-        it for later expansion.  */
-      bool uninlinable = true;
-
-      /* There's no reason to do any of the work here if we're only doing
-        semantic analysis; this code just generates RTL.  */
-      if (flag_syntax_only)
-       {
-         current_function_decl = NULL;
-         DECL_SAVED_TREE (fndecl) = NULL_TREE;
-         return;
-       }
-
-      if (flag_inline_trees)
-       {
-         /* First, cache whether the current function is inlinable.  Some
-            predicates depend on cfun and current_function_decl to
-            function completely.  */
-         timevar_push (TV_INTEGRATION);
-         uninlinable = !tree_inlinable_function_p (fndecl);
-
-         if (can_defer_p
-             /* We defer functions marked inline *even if* the function
-                itself is not inlinable.  This is because we don't yet
-                know if the function will actually be used; we may be
-                able to avoid emitting it entirely.  */
-             && (!uninlinable || DECL_DECLARED_INLINE_P (fndecl))
-             /* Save function tree for inlining.  Should return 0 if the
-                language does not support function deferring or the
-                function could not be deferred.  */
-             && defer_fn (fndecl))
-           {
-             /* Let the back-end know that this function exists.  */
-             (*debug_hooks->deferred_inline_function) (fndecl);
-             timevar_pop (TV_INTEGRATION);
-             current_function_decl = NULL;
-             return;
-           }
-
-         /* Then, inline any functions called in it.  */
-         optimize_inline_calls (fndecl);
-         timevar_pop (TV_INTEGRATION);
-       }
-
-      c_expand_body (fndecl);
-
-      /* Keep the function body if it's needed for inlining or dumping.  */
-      if (uninlinable && !dump_enabled_p (TDI_all))
-       {
-         /* Allow the body of the function to be garbage collected.  */
-         DECL_SAVED_TREE (fndecl) = NULL_TREE;
-       }
-
-      /* Let the error reporting routines know that we're outside a
-        function.  For a nested function, this value is used in
-        c_pop_function_context and then reset via pop_function_context.  */
-      current_function_decl = NULL;
-    }
+  /* ??? Objc emits functions after finalizing the compilation unit.
+     This should be cleaned up later and this conditional removed.  */
+  if (!cgraph_global_info_ready)
+    cgraph_finalize_function (fndecl, DECL_SAVED_TREE (fndecl));
+  else
+    c_expand_body (fndecl);
+  current_function_decl = NULL;
 }
 
 /* Generate the RTL for a deferred function FNDECL.  */
@@ -6198,8 +6171,7 @@ c_expand_deferred_function (tree fndecl)
 
 /* Generate the RTL for the body of FNDECL.  If NESTED_P is nonzero,
    then we are already in the process of generating RTL for another
-   function.  If can_defer_p is zero, we won't attempt to defer the
-   generation of RTL.  */
+   function.  */
 
 static void
 c_expand_body_1 (tree fndecl, int nested_p)
@@ -6213,13 +6185,6 @@ c_expand_body_1 (tree fndecl, int nested_p)
 
   tree_rest_of_compilation (fndecl);
 
-  /* With just -Wextra, complain only if function returns both with
-     and without a value.  */
-  if (extra_warnings
-      && current_function_returns_value
-      && current_function_returns_null)
-    warning ("this function may return with or without a value");
-
   if (DECL_STATIC_CONSTRUCTOR (fndecl))
     {
       if (targetm.have_ctors_dtors)