cp-tree.h (build_x_va_arg): Prototype new function.
authorNathan Sidwell <nathan@acm.org>
Wed, 13 Oct 1999 08:49:54 +0000 (08:49 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 13 Oct 1999 08:49:54 +0000 (08:49 +0000)
* cp-tree.h (build_x_va_arg): Prototype new function.
* call.c (build_x_va_arg): Define it.
* parse.y (unary_expr): Call build_x_va_arg.

* cp-tree.h (convert_type_from_ellipsis): Prototype new function.
* call.c (convert_type_from_ellipsis): Define it.
* decl.c (init_decl_processing): Set lang_type_promotes_to.

* tree.c (lvalue_p_1): Accept VA_ARG_EXPR with aggregates.

From-SVN: r29942

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parse.y
gcc/cp/tree.c

index 59e0932ec1f5479005c04bdeb8ad6d96d41c6707..9bb81d02fb77960b026cfdf481adc144c1264c7b 100644 (file)
@@ -1,3 +1,15 @@
+1999-10-13  Nathan Sidwell  <nathan@acm.org>
+
+       * cp-tree.h (build_x_va_arg): Prototype new function.
+       * call.c (build_x_va_arg): Define it.
+       * parse.y (unary_expr): Call build_x_va_arg.
+       
+       * cp-tree.h (convert_type_from_ellipsis): Prototype new function.
+       * call.c (convert_type_from_ellipsis): Define it.
+       * decl.c (init_decl_processing): Set lang_type_promotes_to.
+
+       * tree.c (lvalue_p_1): Accept VA_ARG_EXPR with aggregates.
+
 1999-10-11  Jason Merrill  <jason@yorick.cygnus.com>
 
        * class.c (fixed_type_or_null): Always set *nonnull.
index 6eaf61e77fe7b6b7f21bf18c73b4a8088d0fca83..dd4e44246f86d4c611808025007f7c542b739ae6 100644 (file)
@@ -3813,6 +3813,48 @@ convert_arg_to_ellipsis (arg)
   return arg;
 }
 
+/* va_arg (EXPR, TYPE) is a builtin. Make sure it is not abused.  */
+
+tree
+build_x_va_arg (expr, type)
+     tree expr;
+     tree type;
+{
+  type = complete_type_or_else (type, NULL_TREE);
+
+  if (expr == error_mark_node || !type)
+    return error_mark_node;
+  
+  if (! pod_type_p (type))
+    {
+      /* Undefined behaviour [expr.call] 5.2.2/7.  */
+      cp_warning ("cannot receive objects of non-POD type `%#T' through `...'",
+                 type);
+    }
+  
+  return build_va_arg (expr, type);
+}
+
+/* TYPE has been given to va_arg. Apply the default conversions which would
+   have happened when passed via ellipsis. Return the promoted type, or
+   NULL_TREE, if there is no change.  */
+
+tree
+convert_type_from_ellipsis (type)
+     tree type;
+{
+  tree promote;
+  
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    promote = build_pointer_type (TREE_TYPE (type));
+  else if (TREE_CODE (type) == FUNCTION_TYPE)
+    promote = build_pointer_type (type);
+  else
+    promote = type_promotes_to (type);
+  
+  return same_type_p (type, promote) ? NULL_TREE : promote;
+}
+
 /* ARG is a default argument expression being passed to a parameter of
    the indicated TYPE, which is a parameter to FN.  Do any required
    conversions.  Return the converted value.  */
index 82ed8824a8bcc40a33d8289bfd2707bde595ab0f..3246e5af8752ddf4e86ff52e025d6d2873a317ba 100644 (file)
@@ -3270,6 +3270,8 @@ extern int can_convert_arg                        PROTO((tree, tree, tree));
 extern int enforce_access                       PROTO((tree, tree));
 extern tree convert_default_arg                 PROTO((tree, tree, tree));
 extern tree convert_arg_to_ellipsis             PROTO((tree));
+extern tree build_x_va_arg                      PROTO((tree, tree));
+extern tree convert_type_from_ellipsis          PROTO((tree));
 extern int is_properly_derived_from             PROTO((tree, tree));
 extern tree initialize_reference                PROTO((tree, tree));
 extern tree strip_top_quals                     PROTO((tree));
index 1554abc6df47a32ba086802439ef2c78dd8e743c..60dac525eb526111bd107c9a9045d3f7bb5ffa0a 100644 (file)
@@ -6221,6 +6221,7 @@ init_decl_processing ()
     = build_pointer_type (build_qualified_type (void_type_node,
                                                TYPE_QUAL_CONST));
   c_common_nodes_and_builtins (1, flag_no_builtin, flag_no_nonansi_builtin);
+  lang_type_promotes_to = convert_type_from_ellipsis;
 
   void_ftype_ptr
     = build_exception_variant (void_ftype_ptr, empty_except_spec);
index e9d8068e388f94be23ebdc1a8e61d89a2e0fa83c..335c022627a14d6bd16aaed51868d131e6a8ba11 100644 (file)
@@ -1173,7 +1173,7 @@ unary_expr:
        | IMAGPART cast_expr %prec UNARY
                { $$ = build_x_unary_op (IMAGPART_EXPR, $2); }
        | VA_ARG '(' expr_no_commas ',' type_id ')'
-               { $$ = build_va_arg ($3, groktypename ($5.t));
+               { $$ = build_x_va_arg ($3, groktypename ($5.t));
                  check_for_new_type ("__builtin_va_arg", $5); }
        ;
 
index b27f9c8fc9071b34df826dde6cc6431be5ea1a84..0b5f84365d5a5fa61d626e8818c804a53e5f31bb 100644 (file)
@@ -145,6 +145,7 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues)
       return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
 
     case CALL_EXPR:
+    case VA_ARG_EXPR:
       return ((treat_class_rvalues_as_lvalues
               && IS_AGGR_TYPE (TREE_TYPE (ref)))
              ? clk_class : clk_none);