OSDN Git Service

PR c++/11971
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Dec 2003 04:08:50 +0000 (04:08 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Dec 2003 04:08:50 +0000 (04:08 +0000)
        * tree.c (build_local_temp): Split out from build_cplus_new.
        (force_target_expr): New fn.
        * call.c (call_builtin_trap): Call it.  Take a type parm.
        (convert_arg_to_ellipsis): Pass it.
        (build_x_va_arg): Use call_builtin_trap.

        PR c++/11929
        * call.c (magic_varargs_p): New fn.
        (build_over_call): Do no ellipsis conversions for arguments to
        functions with magic varargs.

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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/ptree.c
gcc/cp/tree.c

index 63c8ce7..4b3b74a 100644 (file)
@@ -1,5 +1,17 @@
 2003-12-08  Jason Merrill  <jason@redhat.com>
 
+       PR c++/11971
+       * tree.c (build_local_temp): Split out from build_cplus_new.
+       (force_target_expr): New fn.
+       * call.c (call_builtin_trap): Call it.  Take a type parm.
+       (convert_arg_to_ellipsis): Pass it.
+       (build_x_va_arg): Use call_builtin_trap.
+
+       PR c++/11929
+       * call.c (magic_varargs_p): New fn.
+       (build_over_call): Do no ellipsis conversions for arguments to 
+       functions with magic varargs.
+
        * name-lookup.c, init.c, except.c: Revert Giovanni's patch from
        yesterday.
 
index 354eb8b..16482dd 100644 (file)
@@ -104,11 +104,12 @@ static tree direct_reference_binding (tree, tree);
 static bool promoted_arithmetic_type_p (tree);
 static tree conditional_conversion (tree, tree);
 static char *name_as_c_string (tree, tree, bool *);
-static tree call_builtin_trap (void);
+static tree call_builtin_trap (tree);
 static tree prep_operand (tree);
 static void add_candidates (tree, tree, tree, bool, tree, tree,
                            int, struct z_candidate **);
 static tree merge_conversion_sequences (tree, tree);
+static bool magic_varargs_p (tree);
 
 tree
 build_vfield_ref (tree datum, tree type)
@@ -4191,16 +4192,18 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
                      LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
 }
 
-/* Build a call to __builtin_trap which can be used in an expression.  */
+/* Build a call to __builtin_trap which can be used as an expression of
+   type TYPE.  */
 
 static tree
-call_builtin_trap (void)
+call_builtin_trap (tree type)
 {
   tree fn = IDENTIFIER_GLOBAL_VALUE (get_identifier ("__builtin_trap"));
 
   my_friendly_assert (fn != NULL, 20030927);
   fn = build_call (fn, NULL_TREE);
-  fn = build (COMPOUND_EXPR, integer_type_node, fn, integer_zero_node);
+  fn = build (COMPOUND_EXPR, type, fn, error_mark_node);
+  fn = force_target_expr (type, fn);
   return fn;
 }
 
@@ -4239,7 +4242,7 @@ convert_arg_to_ellipsis (tree arg)
       warning ("cannot pass objects of non-POD type `%#T' through `...'; \
 call will abort at runtime",
               TREE_TYPE (arg));
-      arg = call_builtin_trap ();
+      arg = call_builtin_trap (TREE_TYPE (arg));
     }
 
   return arg;
@@ -4261,8 +4264,10 @@ build_x_va_arg (tree expr, tree type)
   if (! pod_type_p (type))
     {
       /* Undefined behavior [expr.call] 5.2.2/7.  */
-      warning ("cannot receive objects of non-POD type `%#T' through `...'",
-                 type);
+      warning ("cannot receive objects of non-POD type `%#T' through `...'; \
+call will abort at runtime",
+              type);
+      return call_builtin_trap (type);
     }
   
   return build_va_arg (expr, type);
@@ -4368,6 +4373,29 @@ convert_for_arg_passing (tree type, tree val)
   return val;
 }
 
+/* Returns true iff FN is a function with magic varargs, i.e. ones for
+   which no conversions at all should be done.  This is true for some
+   builtins which don't act like normal functions.  */
+
+static bool
+magic_varargs_p (tree fn)
+{
+  if (DECL_BUILT_IN (fn))
+    switch (DECL_FUNCTION_CODE (fn))
+      {
+      case BUILT_IN_CLASSIFY_TYPE:
+      case BUILT_IN_CONSTANT_P:
+      case BUILT_IN_NEXT_ARG:
+      case BUILT_IN_STDARG_START:
+      case BUILT_IN_VA_START:
+       return true;
+
+      default:;
+      }
+
+  return false;
+}
+
 /* Subroutine of the various build_*_call functions.  Overload resolution
    has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
    ARGS is a TREE_LIST of the unconverted arguments to the call.  FLAGS is a
@@ -4517,10 +4545,14 @@ build_over_call (struct z_candidate *cand, int flags)
 
   /* Ellipsis */
   for (; arg; arg = TREE_CHAIN (arg))
-    converted_args 
-      = tree_cons (NULL_TREE,
-                  convert_arg_to_ellipsis (TREE_VALUE (arg)),
-                  converted_args);
+    {
+      tree a = TREE_VALUE (arg);
+      if (magic_varargs_p (fn))
+       /* Do no conversions for magic varargs.  */;
+      else
+       a = convert_arg_to_ellipsis (a);
+      converted_args = tree_cons (NULL_TREE, a, converted_args);
+    }
 
   converted_args = nreverse (converted_args);
 
index b1a434e..a16a485 100644 (file)
@@ -3692,6 +3692,7 @@ extern int walk_namespaces                      (walk_namespaces_fn,
 extern int wrapup_globals_for_namespace         (tree, void *);
 extern tree create_implicit_typedef             (tree, tree);
 extern tree maybe_push_decl                     (tree);
+extern tree force_target_expr                  (tree, tree);
 extern tree build_target_expr_with_type         (tree, tree);
 extern int local_variable_p                     (tree);
 extern int nonstatic_local_decl_p               (tree);
index 6dbf060..7979504 100644 (file)
@@ -150,8 +150,10 @@ cxx_print_binding (FILE *stream, cxx_binding *binding, const char *prefix)
 void
 cxx_print_identifier (FILE *file, tree node, int indent)
 {
+  indent_to (file, indent);
   cxx_print_binding (file, IDENTIFIER_NAMESPACE_BINDINGS (node), "bindings");
   print_node (file, "class", IDENTIFIER_CLASS_VALUE (node), indent + 4);
+  indent_to (file, indent);
   cxx_print_binding (file, IDENTIFIER_BINDING (node), "local bindings");
   print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
   print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4);
index c14289d..79d3736 100644 (file)
@@ -49,6 +49,7 @@ static tree build_target_expr (tree, tree);
 static tree count_trees_r (tree *, int *, void *);
 static tree verify_stmt_tree_r (tree *, int *, void *);
 static tree find_tree_r (tree *, int *, void *);
+static tree build_local_temp (tree);
 
 static tree handle_java_interface_attribute (tree *, tree, tree, int, bool *);
 static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *);
@@ -242,6 +243,19 @@ build_target_expr (tree decl, tree value)
   return t;
 }
 
+/* Return an undeclared local temporary of type TYPE for use in building a
+   TARGET_EXPR.  */
+
+static tree
+build_local_temp (tree type)
+{
+  tree slot = build_decl (VAR_DECL, NULL_TREE, type);
+  DECL_ARTIFICIAL (slot) = 1;
+  DECL_CONTEXT (slot) = current_function_decl;
+  layout_decl (slot, 0);
+  return slot;
+}
+
 /* INIT is a CALL_EXPR which needs info about its target.
    TYPE is the type that this initialization should appear to have.
 
@@ -269,10 +283,7 @@ build_cplus_new (tree type, tree init)
             && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
             && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
 
-  slot = build_decl (VAR_DECL, NULL_TREE, type);
-  DECL_ARTIFICIAL (slot) = 1;
-  DECL_CONTEXT (slot) = current_function_decl;
-  layout_decl (slot, 0);
+  slot = build_local_temp (type);
 
   /* We split the CALL_EXPR into its function and its arguments here.
      Then, in expand_expr, we put them back together.  The reason for
@@ -306,7 +317,6 @@ tree
 build_target_expr_with_type (tree init, tree type)
 {
   tree slot;
-  tree rval;
 
   if (TREE_CODE (init) == TARGET_EXPR)
     return init;
@@ -321,13 +331,19 @@ build_target_expr_with_type (tree init, tree type)
        aggregate; there's no additional work to be done.  */
     return force_rvalue (init);
 
-  slot = build_decl (VAR_DECL, NULL_TREE, type);
-  DECL_ARTIFICIAL (slot) = 1;
-  DECL_CONTEXT (slot) = current_function_decl;
-  layout_decl (slot, 0);
-  rval = build_target_expr (slot, init);
+  slot = build_local_temp (type);
+  return build_target_expr (slot, init);
+}
 
-  return rval;
+/* Like the above function, but without the checking.  This function should
+   only be used by code which is deliberately trying to subvert the type
+   system, such as call_builtin_trap.  */
+
+tree
+force_target_expr (tree type, tree init)
+{
+  tree slot = build_local_temp (type);
+  return build_target_expr (slot, init);
 }
 
 /* Like build_target_expr_with_type, but use the type of INIT.  */