* c-common.c (c_common_nodes_and_builtins): The first parameter to
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Mar 2000 00:03:14 +0000 (00:03 +0000)
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Mar 2000 00:03:14 +0000 (00:03 +0000)
__builtin_va_start and __builtin_va_copy is now either a 'va_list'
or a reference to a va_list.
* builtins.c (stabilize_va_list): Simplify now we don't have to
work around C array address decay.
* c-typeck.c (convert_for_assignment): Handle assignment to
a reference parameter by taking the address of the RHS.
* ginclude/stdarg.h (va_start): Don't take address of first parameter.
(va_copy): Likewise.
(__va_copy): Likewise.
* ginclude/varargs.h (va_start): Likewise.
(__va_copy): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32821 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/c-common.c
gcc/c-typeck.c
gcc/ginclude/stdarg.h
gcc/ginclude/varargs.h

index fa6a801..8db409e 100644 (file)
@@ -1,3 +1,18 @@
+2000-03-29  Geoff Keating  <geoffk@cygnus.com>
+
+       * c-common.c (c_common_nodes_and_builtins): The first parameter to
+       __builtin_va_start and __builtin_va_copy is now either a 'va_list'
+       or a reference to a va_list.
+       * builtins.c (stabilize_va_list): Simplify now we don't have to
+       work around C array address decay.
+       * c-typeck.c (convert_for_assignment): Handle assignment to
+       a reference parameter by taking the address of the RHS.
+       * ginclude/stdarg.h (va_start): Don't take address of first parameter.
+       (va_copy): Likewise.
+       (__va_copy): Likewise.
+       * ginclude/varargs.h (va_start): Likewise.
+       (__va_copy): Likewise.
+
 Wed Mar 29 15:44:53 2000  Jeffrey A Law  (law@cygnus.com)
 
        * stmt.c (stmt_loop_nest_empty): Fix thinko in last change.
index 0271d12..94997fb 100644 (file)
@@ -1901,66 +1901,43 @@ expand_builtin_next_arg (arglist)
    from multiple evaluations.  */
 
 static tree
-stabilize_va_list (valist, was_ptr)
+stabilize_va_list (valist, needs_lvalue)
      tree valist;
-     int was_ptr;
+     int needs_lvalue;
 {
   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
     {
-      /* If stdarg.h took the address of an array-type valist that was passed
-         as a parameter, we'll have taken the address of the parameter itself
-         rather than the array as we'd intended.  Undo this mistake.  */
-
-      if (was_ptr)
-       {
-         STRIP_NOPS (valist);
-
-         /* Two cases: either &array, which decomposed to 
-               <ptr <array <record> valist>>
-            or &ptr, which turned into
-               <ptr <ptr <record>>>
-            In the first case we'll need to put the ADDR_EXPR back
-            after frobbing the types as if &array[0].  */
-
-         if (TREE_CODE (valist) != ADDR_EXPR)
-           abort ();
-         valist = TREE_OPERAND (valist, 0);
-       }
+      if (TREE_SIDE_EFFECTS (valist))
+       valist = save_expr (valist);
 
-      if (TYPE_MAIN_VARIANT (TREE_TYPE (valist))
-         == TYPE_MAIN_VARIANT (va_list_type_node))
-       {
-         tree pt = build_pointer_type (TREE_TYPE (va_list_type_node));
-         valist = build1 (ADDR_EXPR, pt, valist);
-         TREE_SIDE_EFFECTS (valist)
-           = TREE_SIDE_EFFECTS (TREE_OPERAND (valist, 0));
-       }
-      else
+      /* For this case, the backends will be expecting a pointer to
+        TREE_TYPE (va_list_type_node), but it's possible we've
+        actually been given an array (an actual va_list_type_node).
+        So fix it.  */
+      if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
        {
-         if (! POINTER_TYPE_P (TREE_TYPE (valist))
-             || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (valist)))
-                 != TYPE_MAIN_VARIANT (TREE_TYPE (va_list_type_node))))
-           abort ();
+         tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
+         tree p2 = build_pointer_type (va_list_type_node);
+         valist = build1 (ADDR_EXPR, p2, valist);
+         valist = fold (build1 (NOP_EXPR, p1, valist));
        }
-
-      if (TREE_SIDE_EFFECTS (valist))
-       valist = save_expr (valist);
     }
   else
     {
-      if (! was_ptr)
-       {
-         tree pt;
+      tree pt;
 
+      if (! needs_lvalue)
+       {
          if (! TREE_SIDE_EFFECTS (valist))
            return valist;
-
+         
          pt = build_pointer_type (va_list_type_node);
-          valist = fold (build1 (ADDR_EXPR, pt, valist));
+         valist = fold (build1 (ADDR_EXPR, pt, valist));
          TREE_SIDE_EFFECTS (valist) = 1;
        }
+
       if (TREE_SIDE_EFFECTS (valist))
-        valist = save_expr (valist);
+       valist = save_expr (valist);
       valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
                             valist));
     }
index 0589c03..97aba25 100644 (file)
@@ -3478,7 +3478,7 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
   tree traditional_cptr_type_node;
   tree traditional_len_type_node;
   tree traditional_len_endlink;
-  tree va_list_ptr_type_node;
+  tree va_list_ref_type_node;
   tree va_list_arg_type_node;
 
   pushdecl (build_decl (TYPE_DECL, get_identifier ("__builtin_va_list"),
@@ -3490,13 +3490,17 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
   pushdecl (build_decl (TYPE_DECL, get_identifier ("__builtin_size_t"),
                        sizetype));
 
-  va_list_ptr_type_node = build_pointer_type (va_list_type_node);
-
   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
-    va_list_arg_type_node = build_pointer_type (TREE_TYPE (va_list_type_node));
+    {
+      va_list_arg_type_node = va_list_ref_type_node =
+       build_pointer_type (TREE_TYPE (va_list_type_node));
+    }
   else
-    va_list_arg_type_node = va_list_type_node;
-
+    {
+      va_list_arg_type_node = va_list_type_node;
+      va_list_ref_type_node = build_reference_type (va_list_type_node);
+    }
   endlink = void_list_node;
   int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
   double_endlink = tree_cons (NULL_TREE, double_type_node, endlink);
@@ -3725,28 +3729,28 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
   builtin_function ("__builtin_varargs_start",
                    build_function_type (void_type_node,
                                         tree_cons (NULL_TREE,
-                                                   va_list_ptr_type_node,
+                                                   va_list_ref_type_node,
                                                    endlink)),
                    BUILT_IN_VARARGS_START, BUILT_IN_NORMAL, NULL_PTR);
 
   builtin_function ("__builtin_stdarg_start",
                    build_function_type (void_type_node,
                                         tree_cons (NULL_TREE,
-                                                   va_list_ptr_type_node,
+                                                   va_list_ref_type_node,
                                                    NULL_TREE)),
                    BUILT_IN_STDARG_START, BUILT_IN_NORMAL, NULL_PTR);
 
   builtin_function ("__builtin_va_end",
                    build_function_type (void_type_node,
                                         tree_cons (NULL_TREE,
-                                                   va_list_arg_type_node,
+                                                   va_list_ref_type_node,
                                                    endlink)),
                    BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL_PTR);
 
   builtin_function ("__builtin_va_copy",
                    build_function_type (void_type_node,
                                         tree_cons (NULL_TREE,
-                                                   va_list_ptr_type_node,
+                                                   va_list_ref_type_node,
                                                    tree_cons (NULL_TREE,
                                                      va_list_arg_type_node,
                                                      endlink))),
index 21a9557..f66d1b9 100644 (file)
@@ -3960,11 +3960,32 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
       error ("void value not ignored as it ought to be");
       return error_mark_node;
     }
+  /* A type converts to a reference to it.  
+     This code doesn't fully support references, it's just for the
+     special case of va_start and va_copy.  */
+  if (codel == REFERENCE_TYPE
+      && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
+    {
+      if (mark_addressable (rhs) == 0)
+       return error_mark_node;
+      rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
+
+      /* We already know that these two types are compatible, but they
+        may not be exactly identical.  In fact, `TREE_TYPE (type)' is
+        likely to be __builtin_va_list and `TREE_TYPE (rhs)' is
+        likely to be va_list, a typedef to __builtin_va_list, which
+        is different enough that it will cause problems later.  */
+      if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type))
+       rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs);
+
+      rhs = build1 (NOP_EXPR, type, rhs);
+      return rhs;
+    }
   /* Arithmetic types all interconvert, and enum is treated like int.  */
-  if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE
-       || codel == COMPLEX_TYPE)
-      && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE
-         || coder == COMPLEX_TYPE))
+  else if ((codel == INTEGER_TYPE || codel == REAL_TYPE 
+           || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE)
+          && (coder == INTEGER_TYPE || coder == REAL_TYPE 
+              || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE))
     return convert_and_check (type, rhs);
 
   /* Conversion to a transparent union from its member types.
index 3337065..9f6215d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -51,13 +51,13 @@ typedef __builtin_va_list __gnuc_va_list;
    actual type **after default promotions**.
    Thus, va_arg (..., short) is not valid.  */
 
-#define va_start(v,l)  __builtin_stdarg_start(&(v),l)
+#define va_start(v,l)  __builtin_stdarg_start((v),l)
 #define va_end         __builtin_va_end
 #define va_arg         __builtin_va_arg
 #if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L
-#define va_copy(d,s)   __builtin_va_copy(&(d),(s))
+#define va_copy(d,s)   __builtin_va_copy((d),(s))
 #endif
-#define __va_copy(d,s) __builtin_va_copy(&(d),(s))
+#define __va_copy(d,s) __builtin_va_copy((d),(s))
 
 
 /* Define va_list, if desired, from __gnuc_va_list. */
index 210b967..098094c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -63,10 +63,10 @@ typedef int __builtin_va_alist_t __attribute__((__mode__(__word__)));
 typedef __builtin_va_list __gnuc_va_list;
 #endif
 
-#define va_start(v)    __builtin_varargs_start(&(v))
+#define va_start(v)    __builtin_varargs_start((v))
 #define va_end         __builtin_va_end
 #define va_arg         __builtin_va_arg
-#define __va_copy(d,s) __builtin_va_copy(&(d),(s))
+#define __va_copy(d,s) __builtin_va_copy((d),(s))
 
 /* Define va_list from __gnuc_va_list.  */