c-common.h (genrtl_expr_stmt_value): Declare.
authorAlexandre Oliva <aoliva@redhat.com>
Wed, 2 Jan 2002 02:31:58 +0000 (02:31 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Wed, 2 Jan 2002 02:31:58 +0000 (02:31 +0000)
* c-common.h (genrtl_expr_stmt_value): Declare.
* c-semantics.c (genrtl_goto_stmt): Redirect to...
(genrtl_goto_stmt_value): ... this new function.  Pass new
argument down to expand_expr_stmt_value, taking
TREE_ADDRESSABLE into account.
* c-common.c (c_expand_expr): Mark the last EXPR_STMT of a
STMT_EXPR as addressable, i.e., one whose result we want.
* expr.c (expand_expr): Don't save expression statement value
of labeled_blocks or loop_exprs.
* stmt.c (expand_expr_stmt): Redirect to...
(expand_expr_stmt_value): ... this new function.  Use new
argument to tell whether to save expression value.
(expand_end_stmt_expr): Reset last_expr_type and
last_expr_value if we don't have either.
* tree-inline.c (declare_return_variable): Mark its use
statement as addressable.
* tree.h: Document new use of TREE_ADDRESSABLE.
(expand_expr_stmt_value): Declare.

From-SVN: r48456

gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-semantics.c
gcc/expr.c
gcc/stmt.c
gcc/tree-inline.c
gcc/tree.h

index 1b5008b0cba7f72e45decda26203d3f3f7785135..a9eaf973d7f56a5aa77d8392acbf906d387729d9 100644 (file)
@@ -1,3 +1,24 @@
+2002-01-02  Alexandre Oliva  <aoliva@redhat.com>
+
+       * c-common.h (genrtl_expr_stmt_value): Declare.
+       * c-semantics.c (genrtl_goto_stmt): Redirect to...
+       (genrtl_goto_stmt_value): ... this new function.  Pass new
+       argument down to expand_expr_stmt_value, taking
+       TREE_ADDRESSABLE into account.
+       * c-common.c (c_expand_expr): Mark the last EXPR_STMT of a
+       STMT_EXPR as addressable, i.e., one whose result we want.
+       * expr.c (expand_expr): Don't save expression statement value
+       of labeled_blocks or loop_exprs.
+       * stmt.c (expand_expr_stmt): Redirect to...
+       (expand_expr_stmt_value): ... this new function.  Use new
+       argument to tell whether to save expression value.
+       (expand_end_stmt_expr): Reset last_expr_type and
+       last_expr_value if we don't have either.
+       * tree-inline.c (declare_return_variable): Mark its use
+       statement as addressable.
+       * tree.h: Document new use of TREE_ADDRESSABLE.
+       (expand_expr_stmt_value): Declare.
+
 2002-01-01  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * configure.in: Prepend ${srcdir}/config/${cpu_type}/ instead of
index d671e3bdf7275270739e7da5958de7aff87add26..39ae17d9a8da474aa393a87341b6224b24ccfa19 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines shared by all languages that are variants of C.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -3418,6 +3418,27 @@ c_expand_expr (exp, target, tmode, modifier)
           STMT_EXPR.  */
        push_temp_slots ();
        rtl_expr = expand_start_stmt_expr ();
+
+       /* If we want the result of this expression, find the last
+           EXPR_STMT in the COMPOUND_STMT and mark it as addressable.  */
+       if (target != const0_rtx
+           && TREE_CODE (STMT_EXPR_STMT (exp)) == COMPOUND_STMT
+           && TREE_CODE (COMPOUND_BODY (STMT_EXPR_STMT (exp))) == SCOPE_STMT)
+         {
+           tree expr = COMPOUND_BODY (STMT_EXPR_STMT (exp));
+           tree last = TREE_CHAIN (expr);
+
+           while (TREE_CHAIN (last))
+             {
+               expr = last;
+               last = TREE_CHAIN (last);
+             }
+
+           if (TREE_CODE (last) == SCOPE_STMT
+               && TREE_CODE (expr) == EXPR_STMT)
+             TREE_ADDRESSABLE (expr) = 1;
+         }
+
        expand_stmt (STMT_EXPR_STMT (exp));
        expand_end_stmt_expr (rtl_expr);
        result = expand_expr (rtl_expr, target, tmode, modifier);
index 61b8f84428b79fc66a1359734bc7125f51524a70..4c49b9fcddfeb3d889b0e53b295c723f0847946c 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions for c-common.c.
    Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -717,6 +717,7 @@ extern void add_c_tree_codes                        PARAMS ((void));
 extern void genrtl_do_pushlevel                 PARAMS ((void));
 extern void genrtl_goto_stmt                    PARAMS ((tree));
 extern void genrtl_expr_stmt                    PARAMS ((tree));
+extern void genrtl_expr_stmt_value              PARAMS ((tree, int));
 extern void genrtl_decl_stmt                    PARAMS ((tree));
 extern void genrtl_if_stmt                      PARAMS ((tree));
 extern void genrtl_while_stmt                   PARAMS ((tree));
index 86e2e8999bb76ca860edb396e7593b075d170df3..ef9ba333751a72160134cb14dc3008b4b73ac29e 100644 (file)
@@ -1,7 +1,7 @@
 /* This file contains the definitions and documentation for the common
    tree codes used in the GNU C and C++ compilers (see c-common.def
    for the standard codes).  
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
    Written by Benjamin Chelf (chelf@codesourcery.com).
 
 This file is part of GCC.
@@ -305,11 +305,26 @@ genrtl_goto_stmt (destination)
     expand_computed_goto (destination);
 }
 
-/* Generate the RTL for EXPR, which is an EXPR_STMT.  */
+/* Generate the RTL for EXPR, which is an EXPR_STMT.  Provided just
+   for backward compatibility.  genrtl_expr_stmt_value() should be
+   used for new code.  */
 
-void 
+void
 genrtl_expr_stmt (expr)
      tree expr;
+{
+  genrtl_expr_stmt_value (expr, -1);
+}
+
+/* Generate the RTL for EXPR, which is an EXPR_STMT.  WANT_VALUE tells
+   whether to (1) save the value of the expression, (0) discard it or
+   (-1) use expr_stmts_for_value to tell.  The use of -1 is
+   deprecated, and retained only for backward compatibility.  */
+
+void 
+genrtl_expr_stmt_value (expr, want_value)
+     tree expr;
+     int want_value;
 {
   if (expr != NULL_TREE)
     {
@@ -319,7 +334,7 @@ genrtl_expr_stmt (expr)
        expand_start_target_temps ();
       
       if (expr != error_mark_node)
-       expand_expr_stmt (expr);
+       expand_expr_stmt_value (expr, want_value);
       
       if (stmts_are_full_exprs_p ())
        expand_end_target_temps ();
@@ -748,7 +763,7 @@ expand_stmt (t)
          break;
 
        case EXPR_STMT:
-         genrtl_expr_stmt (EXPR_STMT_EXPR (t));
+         genrtl_expr_stmt_value (EXPR_STMT_EXPR (t), TREE_ADDRESSABLE (t));
          break;
 
        case DECL_STMT:
index 60c3431f73a053bdcef7ef91a4715d21fcb3ad52..1388b6ff8355a693e2af3cc31c424827eb38c8ff 100644 (file)
@@ -1,6 +1,6 @@
 /* Convert tree expression to rtl instructions, for GNU compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001 Free Software Foundation, Inc.
+   2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -6453,7 +6453,7 @@ expand_expr (exp, target, tmode, modifier)
 
     case LABELED_BLOCK_EXPR:
       if (LABELED_BLOCK_BODY (exp))
-       expand_expr_stmt (LABELED_BLOCK_BODY (exp));
+       expand_expr_stmt_value (LABELED_BLOCK_BODY (exp), 0);
       /* Should perhaps use expand_label, but this is simpler and safer.  */
       do_pending_stack_adjust ();
       emit_label (label_rtx (LABELED_BLOCK_LABEL (exp)));
@@ -6468,7 +6468,7 @@ expand_expr (exp, target, tmode, modifier)
     case LOOP_EXPR:
       push_temp_slots ();
       expand_start_loop (1);
-      expand_expr_stmt (TREE_OPERAND (exp, 0));
+      expand_expr_stmt_value (TREE_OPERAND (exp, 0), 0);
       expand_end_loop ();
       pop_temp_slots ();
 
index c87612aa3c38081f0a71fefd315111c12064bb3a..16a3882ffd0118e65fcbb51a169040eb4fddb1d7 100644 (file)
@@ -1,6 +1,6 @@
 /* Expands front end tree to back end RTL for GNU C-Compiler
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -2182,16 +2182,37 @@ resolve_operand_name_1 (p, outputs, inputs)
 }
 \f
 /* Generate RTL to evaluate the expression EXP
-   and remember it in case this is the VALUE in a ({... VALUE; }) constr.  */
+   and remember it in case this is the VALUE in a ({... VALUE; }) constr.
+   Provided just for backward-compatibility.  expand_expr_stmt_value()
+   should be used for new code.  */
 
 void
 expand_expr_stmt (exp)
      tree exp;
 {
+  expand_expr_stmt_value (exp, -1);
+}
+
+/* Generate RTL to evaluate the expression EXP.  WANT_VALUE tells
+   whether to (1) save the value of the expression, (0) discard it or
+   (-1) use expr_stmts_for_value to tell.  The use of -1 is
+   deprecated, and retained only for backward compatibility.  */
+
+void
+expand_expr_stmt_value (exp, want_value)
+     tree exp;
+     int want_value;
+{
+  rtx value;
+  tree type;
+
+  if (want_value == -1)
+    want_value = expr_stmts_for_value != 0;
+
   /* If -W, warn about statements with no side effects,
      except for an explicit cast to void (e.g. for assert()), and
      except inside a ({...}) where they may be useful.  */
-  if (expr_stmts_for_value == 0 && exp != error_mark_node)
+  if (! want_value && exp != error_mark_node)
     {
       if (! TREE_SIDE_EFFECTS (exp))
        {
@@ -2207,34 +2228,31 @@ expand_expr_stmt (exp)
 
   /* If EXP is of function type and we are expanding statements for
      value, convert it to pointer-to-function.  */
-  if (expr_stmts_for_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE)
+  if (want_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE)
     exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
 
   /* The call to `expand_expr' could cause last_expr_type and
      last_expr_value to get reset.  Therefore, we set last_expr_value
      and last_expr_type *after* calling expand_expr.  */
-  last_expr_value = expand_expr (exp,
-                                (expr_stmts_for_value
-                                 ? NULL_RTX : const0_rtx),
-                                VOIDmode, 0);
-  last_expr_type = TREE_TYPE (exp);
+  value = expand_expr (exp, want_value ? NULL_RTX : const0_rtx,
+                      VOIDmode, 0);
+  type = TREE_TYPE (exp);
 
   /* If all we do is reference a volatile value in memory,
      copy it to a register to be sure it is actually touched.  */
-  if (last_expr_value != 0 && GET_CODE (last_expr_value) == MEM
-      && TREE_THIS_VOLATILE (exp))
+  if (value && GET_CODE (value) == MEM && TREE_THIS_VOLATILE (exp))
     {
-      if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode)
+      if (TYPE_MODE (type) == VOIDmode)
        ;
-      else if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode)
-       copy_to_reg (last_expr_value);
+      else if (TYPE_MODE (type) != BLKmode)
+       value = copy_to_reg (value);
       else
        {
          rtx lab = gen_label_rtx ();
 
          /* Compare the value with itself to reference it.  */
-         emit_cmp_and_jump_insns (last_expr_value, last_expr_value, EQ,
-                                  expand_expr (TYPE_SIZE (last_expr_type),
+         emit_cmp_and_jump_insns (value, value, EQ,
+                                  expand_expr (TYPE_SIZE (type),
                                                NULL_RTX, VOIDmode, 0),
                                   BLKmode, 0, lab);
          emit_label (lab);
@@ -2243,13 +2261,19 @@ expand_expr_stmt (exp)
 
   /* If this expression is part of a ({...}) and is in memory, we may have
      to preserve temporaries.  */
-  preserve_temp_slots (last_expr_value);
+  preserve_temp_slots (value);
 
   /* Free any temporaries used to evaluate this expression.  Any temporary
      used as a result of this expression will already have been preserved
      above.  */
   free_temp_slots ();
 
+  if (want_value)
+    {
+      last_expr_value = value;
+      last_expr_type = type;
+    }
+
   emit_queue ();
 }
 
@@ -2386,6 +2410,7 @@ expand_start_stmt_expr ()
   start_sequence_for_rtl_expr (t);
   NO_DEFER_POP;
   expr_stmts_for_value++;
+  last_expr_value = NULL_RTX;
   return t;
 }
 
@@ -2407,15 +2432,11 @@ expand_end_stmt_expr (t)
 {
   OK_DEFER_POP;
 
-  if (last_expr_type == 0)
+  if (! last_expr_value || ! last_expr_type)
     {
-      last_expr_type = void_type_node;
       last_expr_value = const0_rtx;
+      last_expr_type = void_type_node;
     }
-  else if (last_expr_value == 0)
-    /* There are some cases where this can happen, such as when the
-       statement is void type.  */
-    last_expr_value = const0_rtx;
   else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value))
     /* Remove any possible QUEUED.  */
     last_expr_value = protect_from_queue (last_expr_value, 0);
index 6cd1fbb5e15ba3a7aa61e4bb95601abfb5ed9a03..02ba7161b46ce198144089bbe642d9afef177571 100644 (file)
@@ -1,5 +1,5 @@
 /* Control and data flow functions for trees.
-   Copyright 2001 Free Software Foundation, Inc.
+   Copyright 2001, 2002 Free Software Foundation, Inc.
    Contributed by Alexandre Oliva <aoliva@redhat.com>
 
 This file is part of GNU CC.
@@ -624,7 +624,9 @@ declare_return_variable (id, use_stmt)
     *use_stmt = build_stmt (EXPR_STMT,
                            build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)),
                                    var));
-      
+
+  TREE_ADDRESSABLE (*use_stmt) = 1;
+
   /* Build the declaration statement if FN does not return an
      aggregate.  */
   if (need_return_decl)
index eee6663cb7574feb96d6327e8d2e3a1188e8d0f0..051aa2c5bf357bf0aad76d4d48f7780f005a6e6f 100644 (file)
@@ -1,6 +1,6 @@
 /* Front-end tree definitions for GNU compiler.
-   Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+   Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -161,7 +161,9 @@ struct tree_common
 
        TREE_ADDRESSABLE in
           VAR_DECL, FUNCTION_DECL, FIELD_DECL, CONSTRUCTOR, LABEL_DECL,
-          ..._TYPE, IDENTIFIER_NODE
+          ..._TYPE, IDENTIFIER_NODE.
+          In a STMT_EXPR, it means we want the result of the enclosed
+          expression.
 
    static_flag:
 
@@ -258,8 +260,7 @@ struct tree_common
           expressions, VAR_DECL, PARM_DECL, FIELD_DECL, FUNCTION_DECL,
           IDENTIFIER_NODE
        TYPE_BOUNDED in
-          ..._TYPE
-*/
+          ..._TYPE */
 
 /* Define accessors for the fields that all tree nodes have
    (though some fields are not used for all kinds of nodes).  */
@@ -2719,6 +2720,7 @@ extern void expand_fixups                 PARAMS ((rtx));
 extern tree expand_start_stmt_expr             PARAMS ((void));
 extern tree expand_end_stmt_expr               PARAMS ((tree));
 extern void expand_expr_stmt                   PARAMS ((tree));
+extern void expand_expr_stmt_value             PARAMS ((tree, int));
 extern int warn_if_unused_value                        PARAMS ((tree));
 extern void expand_decl_init                   PARAMS ((tree));
 extern void clear_last_expr                    PARAMS ((void));