OSDN Git Service

PR c++/27371
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Sep 2006 01:12:00 +0000 (01:12 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Sep 2006 01:12:00 +0000 (01:12 +0000)
        * tree-inline.c (copy_result_decl_to_var): New fn.
        (declare_return_variable): Use it.  Call declare_inline_vars here.
        (expand_call_inline): Not here.
        * cp/cvt.c (convert_to_void): Strip useless TARGET_EXPR.
        * cp/cp-tree.h (TARGET_EXPR_IMPLICIT_P): New macro.
        * cp/tree.c (build_cplus_new): Set it.

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

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/warn/unused-result1.C [new file with mode: 0644]
gcc/tree-inline.c

index 833eb11..dd11014 100644 (file)
@@ -1,3 +1,10 @@
+2006-09-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/27371
+       * tree-inline.c (copy_result_decl_to_var): New fn.
+       (declare_return_variable): Use it.  Call declare_inline_vars here.
+       (expand_call_inline): Not here.
+
 2006-09-06  Diego Novillo  <dnovillo@redhat.com>
 
        * doc/contrib.texi: Update my entry.
index 60d2fb2..9e17cce 100644 (file)
 
 2006-09-06  Jason Merrill  <jason@redhat.com>
 
+       PR c++/27371
+       * cvt.c (convert_to_void): Strip useless TARGET_EXPR.
+       * cp-tree.h (TARGET_EXPR_IMPLICIT_P): New macro.
+       * tree.c (build_cplus_new): Set it.
+
        PR c++/26696
        * cvt.c (convert_to_void): Replace a subexpression with no side 
        effects with void_zero_node.
index 3c20afe..f864487 100644 (file)
@@ -55,6 +55,7 @@ struct diagnostic_context;
       OMP_ATOMIC_DEPENDENT_P (in OMP_ATOMIC)
       OMP_FOR_GIMPLIFYING_P (in OMP_FOR)
       BASELINK_QUALIFIED_P (in BASELINK)
+      TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR)
    1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
       TI_PENDING_TEMPLATE_FLAG.
       TEMPLATE_PARMS_FOR_INLINE.
@@ -3091,6 +3092,11 @@ extern void decl_shadowed_for_var_insert (tree, tree);
    expression statement.  */
 #define EXPR_STMT_EXPR(NODE)   TREE_OPERAND (EXPR_STMT_CHECK (NODE), 0)
 
+/* True if this TARGET_EXPR was created by build_cplus_new, and so we can
+   discard it if it isn't useful.  */
+#define TARGET_EXPR_IMPLICIT_P(NODE) \
+  TREE_LANG_FLAG_0 (TARGET_EXPR_CHECK (NODE))
+
 /* An enumeration of the kind of tags that C++ accepts.  */
 enum tag_types {
   none_type = 0, /* Not a tag type.  */
index 83b35d6..52b5be4 100644 (file)
@@ -892,6 +892,25 @@ convert_to_void (tree expr, const char *implicit)
        break;
       }
 
+    case TARGET_EXPR:
+      /* Don't bother with the temporary object returned from a function if
+        we don't use it and don't need to destroy it.  We'll still
+        allocate space for it in expand_call or declare_return_variable,
+        but we don't need to track it through all the tree phases.  */
+      if (0 && TARGET_EXPR_IMPLICIT_P (expr)
+         && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (expr)))
+       {
+         tree init = TARGET_EXPR_INITIAL (expr);
+         if (TREE_CODE (init) == AGGR_INIT_EXPR
+             && !AGGR_INIT_VIA_CTOR_P (init))
+           {
+             tree fn = TREE_OPERAND (init, 0);
+             expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
+                            fn, TREE_OPERAND (init, 1), NULL_TREE);
+           }
+       }
+      break;
+
     default:;
     }
   {
index 89941cc..526077a 100644 (file)
@@ -312,6 +312,7 @@ build_cplus_new (tree type, tree init)
     rval = init;
 
   rval = build_target_expr (slot, rval);
+  TARGET_EXPR_IMPLICIT_P (rval) = 1;
 
   return rval;
 }
diff --git a/gcc/testsuite/g++.dg/warn/unused-result1.C b/gcc/testsuite/g++.dg/warn/unused-result1.C
new file mode 100644 (file)
index 0000000..1b9ef8a
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/27371
+
+class QByteArray {
+public:
+  QByteArray(const QByteArray &);
+};
+class QString {
+  QByteArray toLocal8Bit() const __attribute__ ((warn_unused_result));
+  void fooWarnHere() const { toLocal8Bit(); } // { dg-warning "ignoring" }
+};
index e77c9b8..baca834 100644 (file)
@@ -120,6 +120,7 @@ static void declare_inline_vars (tree, tree);
 static void remap_save_expr (tree *, void *, int *);
 static void add_lexical_block (tree current_block, tree new_block);
 static tree copy_decl_to_var (tree, copy_body_data *);
+static tree copy_result_decl_to_var (tree, copy_body_data *);
 static tree copy_decl_no_change (tree, copy_body_data *);
 static tree copy_decl_maybe_to_var (tree, copy_body_data *);
 
@@ -1261,7 +1262,7 @@ declare_return_variable (copy_body_data *id, tree return_slot_addr,
 
   gcc_assert (TREE_CODE (TYPE_SIZE_UNIT (callee_type)) == INTEGER_CST);
 
-  var = copy_decl_to_var (result, id);
+  var = copy_result_decl_to_var (result, id);
 
   DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
   DECL_STRUCT_FUNCTION (caller)->unexpanded_var_list
@@ -1272,6 +1273,8 @@ declare_return_variable (copy_body_data *id, tree return_slot_addr,
      not be visible to the user.  */
   TREE_NO_WARNING (var) = 1;
 
+  declare_inline_vars (id->block, var);
+
   /* Build the use expr.  If the return type of the function was
      promoted, convert it back to the expected type.  */
   use = var;
@@ -1280,6 +1283,9 @@ declare_return_variable (copy_body_data *id, tree return_slot_addr,
     
   STRIP_USELESS_TYPE_CONVERSION (use);
 
+  if (DECL_BY_REFERENCE (result))
+    var = build_fold_addr_expr (var);
+
  done:
   /* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
      way, when the RESULT_DECL is encountered, it will be
@@ -1926,7 +1932,6 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
   bool successfully_inlined = FALSE;
   tree t_step;
   tree var;
-  tree decl;
 
   /* See what we've got.  */
   id = (copy_body_data *) data;
@@ -2103,11 +2108,8 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
     modify_dest = NULL;
 
   /* Declare the return variable for the function.  */
-  decl = declare_return_variable (id, return_slot_addr,
-                                 modify_dest, &use_retvar);
-  /* Do this only if declare_return_variable created a new one.  */
-  if (decl && !return_slot_addr && decl != modify_dest)
-    declare_inline_vars (id->block, decl);
+  declare_return_variable (id, return_slot_addr,
+                          modify_dest, &use_retvar);
 
   /* This is it.  Duplicate the callee body.  Assume callee is
      pre-gimplified.  Note that we must not alter the caller
@@ -2630,6 +2632,34 @@ copy_decl_to_var (tree decl, copy_body_data *id)
   return copy_decl_for_dup_finish (id, decl, copy);
 }
 
+/* Like copy_decl_to_var, but create a return slot object instead of a
+   pointer variable for return by invisible reference.  */
+
+static tree
+copy_result_decl_to_var (tree decl, copy_body_data *id)
+{
+  tree copy, type;
+
+  gcc_assert (TREE_CODE (decl) == PARM_DECL
+             || TREE_CODE (decl) == RESULT_DECL);
+
+  type = TREE_TYPE (decl);
+  if (DECL_BY_REFERENCE (decl))
+    type = TREE_TYPE (type);
+
+  copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
+  TREE_READONLY (copy) = TREE_READONLY (decl);
+  TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
+  if (!DECL_BY_REFERENCE (decl))
+    {
+      TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
+      DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_GIMPLE_REG_P (decl);
+    }
+
+  return copy_decl_for_dup_finish (id, decl, copy);
+}
+
+
 static tree
 copy_decl_no_change (tree decl, copy_body_data *id)
 {