]> gcc.gnu.org Git - gcc.git/commitdiff
PR c++/8461, c++/8625
authorJason Merrill <jason@redhat.com>
Wed, 4 Dec 2002 20:13:01 +0000 (15:13 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 4 Dec 2002 20:13:01 +0000 (15:13 -0500)
        PR c++/8461, c++/8625
        * integrate.c (copy_decl_for_inlining): Handle explicit invisible
        references.
        * tree-inline.c (initialize_inlined_parameters): Likewise.

2002-12-03  Jason Merrill  <jason@redhat.com>

        PR c++/8461, c++/8625
        * call.c (convert_for_arg_passing): Don't mess with error_mark_node.
        (cp_convert_parm_for_inlining): Remove.
        * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
        Remove.
        * cp-tree.h (ADDR_IS_INVISIREF): Remove.
        * except.c (stabilize_throw_expr): Remove ADDR_IS_INVISIREF code.

From-SVN: r59827

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-lang.c
gcc/cp/cp-tree.h
gcc/cp/except.c
gcc/integrate.c
gcc/testsuite/g++.dg/init/elide2.C [new file with mode: 0644]
gcc/tree-inline.c
gcc/tree.c

index 579d88449876048219fcb7d5a34cd7b1d3b21e1a..76609c3ce427595751fb4eaf541d6f1437be4baa 100644 (file)
@@ -1,3 +1,12 @@
+2002-12-04  Jason Merrill  <jason@redhat.com>
+
+       PR c++/8461, c++/8625
+       * integrate.c (copy_decl_for_inlining): Handle explicit invisible
+       references.
+       * tree-inline.c (initialize_inlined_parameters): Likewise.
+
+       * tree.c (variably_modified_type_p): Just return an error_mark_node.
+
 2002-12-04  Chris Demetriou  <cgd@broadcom.com>
 
        * config/mips/mips.md (get_fnaddr): Avoid placing an "la"
index 5da6ebc7e8d7bb4c26d842ef0eed7e154ff6a9f2..60789ee32d46dd0e8e6dfe2ccfacec917eb1177c 100644 (file)
@@ -6,6 +6,18 @@
 
 2002-12-03  Jason Merrill  <jason@redhat.com>
 
+       PR c++/8674
+       * call.c (build_over_call): Check specifically for TARGET_EXPR
+       when eliding.
+
+       PR c++/8461, c++/8625
+       * call.c (convert_for_arg_passing): Don't mess with error_mark_node.
+       (cp_convert_parm_for_inlining): Remove.
+       * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING): 
+       Remove.
+       * cp-tree.h (ADDR_IS_INVISIREF): Remove.
+       * except.c (stabilize_throw_expr): Remove ADDR_IS_INVISIREF code.
+
        * call.c (build_user_type_conversion_1): Don't set ICS_BAD_FLAG on
        an ambiguous conversion.
 
index 1678ed25337d2cb1170234e8157d4af24958ee85..072fbe6451528bc15191603d94fa02e4d8255e41 100644 (file)
@@ -4276,12 +4276,11 @@ tree
 convert_for_arg_passing (type, val)
      tree type, val;
 {
+  if (val == error_mark_node)
+    ;
   /* Pass classes with copy ctors by invisible reference.  */
-  if (TREE_ADDRESSABLE (type))
-    {
-      val = build1 (ADDR_EXPR, build_reference_type (type), val);
-      ADDR_IS_INVISIREF (val) = 1;
-    }
+  else if (TREE_ADDRESSABLE (type))
+    val = build1 (ADDR_EXPR, build_reference_type (type), val);
   else if (PROMOTE_PROTOTYPES
           && INTEGRAL_TYPE_P (type)
           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
@@ -4289,24 +4288,6 @@ convert_for_arg_passing (type, val)
   return val;
 }
 
-/* Convert VALUE for assignment into inlined parameter PARM.  */
-
-tree
-cp_convert_parm_for_inlining (parm, value, fn)
-     tree parm, value;
-     tree fn ATTRIBUTE_UNUSED;
-{
-  /* When inlining, we don't need to mess with invisible references, so
-     undo the ADDR_EXPR.  */
-  if (TREE_ADDRESSABLE (TREE_TYPE (parm)))
-    {
-      value = TREE_OPERAND (value, 0);
-      if (TREE_CODE (value) != TARGET_EXPR)
-       abort ();
-    }
-  return value;
-}
-
 /* 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
@@ -4477,12 +4458,12 @@ build_over_call (cand, args, flags)
          temp or an INIT_EXPR otherwise.  */
       if (integer_zerop (TREE_VALUE (args)))
        {
-         if (! real_lvalue_p (arg))
+         if (TREE_CODE (arg) == TARGET_EXPR)
            return arg;
          else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
            return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
        }
-      else if (!real_lvalue_p (arg)
+      else if (TREE_CODE (arg) == TARGET_EXPR
               || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
        {
          tree address;
index d89fb635d0ae748b988fb5197968141fbab183ec..a7f2d85966ed1c9ef3ed436cf4f7a9786183c9c7 100644 (file)
@@ -122,9 +122,6 @@ static bool cp_var_mod_type_p PARAMS ((tree));
 #undef LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING
 #define LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING \
   cp_copy_res_decl_for_inlining
-#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
-#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
-  cp_convert_parm_for_inlining
 #undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
 #define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p
 #undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P
index 0c8c37a7e20eb17a5ff9e587c15d76ba35cd51ab..4c0efd20e049812df5407d85d31a8d60a97a3a1a 100644 (file)
@@ -65,7 +65,6 @@ struct diagnostic_context;
       BINDING_HAS_LEVEL_P (in CPLUS_BINDING)
       BINFO_LOST_PRIMARY_P (in BINFO)
       TREE_PARMLIST (in TREE_LIST)
-      ADDR_IS_INVISIREF (in ADDR_EXPR)
    3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
       BINFO_VTABLE_PATH_MARKED.
       BINFO_PUSHDECLS_MARKED.
@@ -1687,10 +1686,6 @@ struct lang_type GTY(())
 /* Nonzero for a parmlist means that this parmlist ended in ...  */
 #define PARMLIST_ELLIPSIS_P(NODE) TREE_LANG_FLAG_0 (NODE)
 
-/* Nonzero if this ADDR_EXPR is used to implement the pass by invisible
-   reference calling convention.  */
-#define ADDR_IS_INVISIREF(NODE) TREE_LANG_FLAG_2 (NODE)
-
 /* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that
    this type can raise.  Each TREE_VALUE is a _TYPE.  The TREE_VALUE
    will be NULL_TREE to indicate a throw specification of `()', or
index 848ef512f7693124d61d109bbdcff9115efb18e6..747cc1aaef692feb3387c2324cf9f1a01833feaa 100644 (file)
@@ -601,28 +601,12 @@ stabilize_throw_expr (exp, initp)
        {
          tree arg = TREE_VALUE (args);
          tree arg_init_expr;
-         if (TREE_CODE (arg) == ADDR_EXPR
-             && ADDR_IS_INVISIREF (arg))
-           {
-             /* A sub-TARGET_EXPR.  Recurse; we can't wrap the actual call
-                without introducing an extra copy.  */
-             tree sub = TREE_OPERAND (arg, 0);
-             if (TREE_CODE (sub) != TARGET_EXPR)
-               abort ();
-             sub = stabilize_throw_expr (sub, &arg_init_expr);
-             TREE_OPERAND (arg, 0) = sub;
-             if (TREE_SIDE_EFFECTS (arg_init_expr))
-               init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
-                                  arg_init_expr);
-           }
-         else
-           {
-             arg = stabilize_expr (arg, &arg_init_expr);
 
-             if (TREE_SIDE_EFFECTS (arg_init_expr))
-               init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
-                                  arg_init_expr);
-           }
+         arg = stabilize_expr (arg, &arg_init_expr);
+
+         if (TREE_SIDE_EFFECTS (arg_init_expr))
+           init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
+                              arg_init_expr);
          *p = tree_cons (NULL_TREE, arg, NULL_TREE);
          p = &TREE_CHAIN (*p);
        }
index 0e54e48b1cfcbe2ed87e6b3927c9b520a207c49e..7752d66fb51d81203fdcb1eedf73b5c2b3b6c652 100644 (file)
@@ -344,12 +344,36 @@ copy_decl_for_inlining (decl, from_fn, to_fn)
   /* Copy the declaration.  */
   if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL)
     {
+      tree type;
+      int invisiref = 0;
+
+      /* See if the frontend wants to pass this by invisible reference.  */
+      if (TREE_CODE (decl) == PARM_DECL
+         && DECL_ARG_TYPE (decl) != TREE_TYPE (decl)
+         && POINTER_TYPE_P (DECL_ARG_TYPE (decl))
+         && TREE_TYPE (DECL_ARG_TYPE (decl)) == TREE_TYPE (decl))
+       {
+         invisiref = 1;
+         type = DECL_ARG_TYPE (decl);
+       }
+      else
+       type = TREE_TYPE (decl);
+
       /* For a parameter, we must make an equivalent VAR_DECL, not a
         new PARM_DECL.  */
-      copy = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
-      TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
-      TREE_READONLY (copy) = TREE_READONLY (decl);
-      TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
+      copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
+      if (!invisiref)
+       {
+         TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
+         TREE_READONLY (copy) = TREE_READONLY (decl);
+         TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
+       }
+      else
+       {
+         TREE_ADDRESSABLE (copy) = 0;
+         TREE_READONLY (copy) = 1;
+         TREE_THIS_VOLATILE (copy) = 0;
+       }
     }
   else
     {
diff --git a/gcc/testsuite/g++.dg/init/elide2.C b/gcc/testsuite/g++.dg/init/elide2.C
new file mode 100644 (file)
index 0000000..e6d3300
--- /dev/null
@@ -0,0 +1,30 @@
+// PR c++/8674
+
+// Bug: Since B().a is an rvalue, we tried to treat it like a TARGET_EXPR
+// and elide the copy.  But that produces a bitwise copy, which causes us
+// to abort in cp_expr_size.
+
+// Test that we actually run the A copy constructor when calling f().
+
+// { dg-do run }
+
+int c;
+
+struct A
+{
+  A () { ++c; }
+  A (const A&) { ++c; }
+};
+
+struct B
+{
+  A a;
+};
+
+void f (A) { }
+
+int main ()
+{
+  f (B().a);
+  return c < 2;
+}
index 6dea3539cc01075cd6895c1bed58c0c2bb518211..0f5ab59158f3fb9e513321a72eb928bf3e7bef20 100644 (file)
@@ -632,6 +632,7 @@ initialize_inlined_parameters (id, args, fn, block)
 #endif /* not INLINER_FOR_JAVA */
       tree var;
       tree value;
+      tree var_sub;
 
       /* Find the initializer.  */
       value = (*lang_hooks.tree_inlining.convert_parm_for_inlining)
@@ -669,12 +670,23 @@ initialize_inlined_parameters (id, args, fn, block)
 
       /* Make an equivalent VAR_DECL.  */
       var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
+
+      /* See if the frontend wants to pass this by invisible reference.  If
+        so, our new VAR_DECL will have REFERENCE_TYPE, and we need to
+        replace uses of the PARM_DECL with dereferences.  */
+      if (TREE_TYPE (var) != TREE_TYPE (p)
+         && POINTER_TYPE_P (TREE_TYPE (var))
+         && TREE_TYPE (TREE_TYPE (var)) == TREE_TYPE (p))
+       var_sub = build1 (INDIRECT_REF, TREE_TYPE (p), var);
+      else
+       var_sub = var;
+
       /* Register the VAR_DECL as the equivalent for the PARM_DECL;
         that way, when the PARM_DECL is encountered, it will be
         automatically replaced by the VAR_DECL.  */
       splay_tree_insert (id->decl_map,
                         (splay_tree_key) p,
-                        (splay_tree_value) var);
+                        (splay_tree_value) var_sub);
 
       /* Declare this new variable.  */
 #ifndef INLINER_FOR_JAVA
index c926b31092380be050dd02fda98b43dfa28dac38..dfac289f137643e2af8f12cefc125b146dc0da32 100644 (file)
@@ -4118,6 +4118,9 @@ bool
 variably_modified_type_p (type)
      tree type;
 {
+  if (type == error_mark_node)
+    return false;
+
   /* If TYPE itself has variable size, it is variably modified.  
 
      We do not yet have a representation of the C99 '[*]' syntax.
This page took 0.10583 seconds and 5 git commands to generate.