decl.c (build_result_decl): New method.
authorPer Bothner <bothner@gcc.gnu.org>
Sun, 21 Feb 1999 15:42:27 +0000 (07:42 -0800)
committerPer Bothner <bothner@gcc.gnu.org>
Sun, 21 Feb 1999 15:42:27 +0000 (07:42 -0800)
d
* decl.c (build_result_decl), java-tree.h:  New method.
(complete_start_java_method):  Handle synchronized methods.
Don't build DECL_RESULT here.  (Ordering dependency problem.)
(start_java_method):  Call build_result_decl here instead  ...
* parse.y (java_complete_expand_method):  ... and here.
(expand_start_java_method): Don't call complete_start_java_method here.
(java_complete_expand_method):  Call it here instead.
* parse.h (BUILD_MONITOR_ENTER, BUILD_MONITOR_EXIT):  Moved to ..
* java-tree.h:  ... here.
* expr.c (force_evaluation_order):  Fix typo, don't handle ARRAY_REF.
* parse.y (java_complete_lhs):  Don't call force_evaluation_order
for ARRAY_REF - it doesn't work when array bounds are checked.
(patch_array_ref):  Handle it here instead.

From-SVN: r25346

gcc/java/decl.c
gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/parse.c
gcc/java/parse.h
gcc/java/parse.y

index 5293ddc906eabf74d8b3f6ca4a9278ef6b283a91..14b8ece1367dff126ab956c25ef80538a76d9ed0 100644 (file)
@@ -1465,8 +1465,8 @@ give_name_to_locals (jcf)
     }
 }
 
-void
-complete_start_java_method (fndecl)
+tree
+build_result_decl (fndecl)
   tree fndecl;
 {
   tree restype = TREE_TYPE (TREE_TYPE (fndecl));
@@ -1474,8 +1474,13 @@ complete_start_java_method (fndecl)
   if (INTEGRAL_TYPE_P (restype)
       && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
     restype = integer_type_node;
-  DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype);
+  return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype));
+}
 
+void
+complete_start_java_method (fndecl)
+  tree fndecl;
+{
   if (! flag_emit_class_files)
     {
       /* Initialize the RTL code for the function.  */
@@ -1509,9 +1514,27 @@ complete_start_java_method (fndecl)
       expand_expr_stmt (init);
     }
 
-  if (METHOD_SYNCHRONIZED (fndecl))
+  if (METHOD_SYNCHRONIZED (fndecl) && ! flag_emit_class_files
+      && DECL_FUNCTION_BODY (fndecl) != NULL_TREE)
     {
-      /* FIXME: surround the function body by a try/finally set.  */
+      /* Warp function body with a monitorenter plus monitorexit cleanup. */
+      tree function_body = DECL_FUNCTION_BODY (fndecl);
+      tree body = BLOCK_EXPR_BODY (function_body);
+      tree enter, exit, lock;
+      if (METHOD_STATIC (fndecl))
+       lock = build_class_ref (DECL_CONTEXT (fndecl));
+      else
+       lock = DECL_ARGUMENTS (fndecl);
+      BUILD_MONITOR_ENTER (enter, lock);
+      BUILD_MONITOR_EXIT (exit, lock);
+      lock = build (WITH_CLEANUP_EXPR, void_type_node,
+                   enter,  NULL_TREE, exit);
+      TREE_SIDE_EFFECTS (lock) = 1;
+      lock = build (COMPOUND_EXPR, TREE_TYPE (body), lock, body);
+      TREE_SIDE_EFFECTS (lock) = 1;
+      lock = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (body), lock);
+      TREE_SIDE_EFFECTS (lock) = 1;
+      BLOCK_EXPR_BODY (function_body) = lock;
     }
 
   /* Push local variables. Function compiled from source code are
@@ -1578,6 +1601,7 @@ start_java_method (fndecl)
   while (i < DECL_MAX_LOCALS(fndecl))
     type_map[i++] = NULL_TREE;
 
+  build_result_decl (fndecl);
   complete_start_java_method (fndecl);
 }
 
index 0848806ac5b51803a52683d44426276fde9c2488..7e2e26cbd69d086a6c658ddc446a64e34766add4 100644 (file)
@@ -2492,8 +2492,7 @@ force_evaluation_order (node)
 {
   if (flag_syntax_only)
     return node;
-  if (TREE_CODE_CLASS (TREE_CODE (node)) == '2'
-      && TREE_CODE (node) == ARRAY_REF)
+  if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
     {
       if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
        TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
index ad1880d9601ff2a692321e642bc298a4421ae1ad..28cba1c7104b22c14dff82548926a1c2b96a809e 100644 (file)
@@ -552,6 +552,7 @@ extern int get_access_flags_from_decl PROTO ((tree));
 extern int interface_of_p PROTO ((tree, tree));
 extern int inherits_from_p PROTO ((tree, tree));
 extern void complete_start_java_method PROTO ((tree));
+extern tree build_result_decl PROTO ((tree));
 extern void emit_handlers PROTO (());
 extern void init_outgoing_cpool PROTO (());
 extern void make_class_data PROTO ((tree));
@@ -861,6 +862,24 @@ extern tree *type_map;
 #define BLOCK_EXPR_DECLS(NODE)  BLOCK_VARS(NODE)
 #define BLOCK_EXPR_BODY(NODE)   BLOCK_SUBBLOCKS(NODE)
 
+#define BUILD_MONITOR_ENTER(WHERE, ARG)                                \
+  {                                                            \
+    (WHERE) = build (CALL_EXPR, int_type_node,                 \
+                    build_address_of (soft_monitorenter_node), \
+                    build_tree_list (NULL_TREE, (ARG)),        \
+                    NULL_TREE);                                \
+    TREE_SIDE_EFFECTS (WHERE) = 1;                             \
+  }
+
+#define BUILD_MONITOR_EXIT(WHERE, ARG)                         \
+  {                                                            \
+    (WHERE) = build (CALL_EXPR, int_type_node,                 \
+                    build_address_of (soft_monitorexit_node),  \
+                    build_tree_list (NULL_TREE, (ARG)),        \
+                    NULL_TREE);                                \
+    TREE_SIDE_EFFECTS (WHERE) = 1;                             \
+  }
+
 /* Non zero if TYPE is an unchecked exception */
 #define IS_UNCHECKED_EXCEPTION_P(TYPE)                         \
   (inherits_from_p ((TYPE), runtime_exception_type_node)       \
index 74530c3b675d7dbab9ec4f3583b457d2a471f103..13744dfcfc99f41a76f50c4a8bfe4b57c0096310 100644 (file)
@@ -8066,7 +8066,6 @@ expand_start_java_method (fndecl)
   *ptr = NULL_TREE;
   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
-  complete_start_java_method (fndecl); 
 }
 
 /* Terminate a function and expand its body.  */
@@ -8333,6 +8332,7 @@ java_complete_expand_method (mdecl)
       tree fbody = DECL_FUNCTION_BODY (mdecl);
       tree block_body = BLOCK_EXPR_BODY (fbody);
       expand_start_java_method (mdecl);
+      build_result_decl (mdecl);
 
       current_this 
        = (!METHOD_STATIC (mdecl) ? 
@@ -8355,6 +8355,8 @@ java_complete_expand_method (mdecl)
          && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
        missing_return_error (current_function_decl);
 
+      complete_start_java_method (mdecl); 
+
       /* Don't go any further if we've found error(s) during the
          expansion */
       if (!java_error_count)
@@ -9052,8 +9054,9 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                  return 1;
                }
              
-             if (!(field_decl = 
-                   lookup_field_wrapper (type, EXPR_WFL_NODE (qual_wfl))))
+             field_decl = lookup_field_wrapper (type,
+                                                EXPR_WFL_NODE (qual_wfl));
+             if (field_decl == NULL_TREE)
                {
                  parse_error_context 
                    (qual_wfl, "No variable `%s' defined in class `%s'",
@@ -9061,6 +9064,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
                  return 1;
                }
+             if (field_decl == error_mark_node)
+               return 1;
 
              /* Layout the type of field_decl, since we may need
                  it. Don't do primitive types or loaded classes. The
@@ -10178,7 +10183,8 @@ java_complete_lhs (node)
          /* Now do the actual complete, without deep recursion for
              long blocks. */
          ptr = &BLOCK_EXPR_BODY (node);
-         while (TREE_CODE (*ptr) == COMPOUND_EXPR)
+         while (TREE_CODE (*ptr) == COMPOUND_EXPR
+                && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
            {
              tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
              tree *next = &TREE_OPERAND (*ptr, 1);
@@ -10198,8 +10204,7 @@ java_complete_lhs (node)
                        break;
                    }
                  if (TREE_CODE (wfl_op2) != CASE_EXPR
-                     && TREE_CODE (wfl_op2) != DEFAULT_EXPR
-                     && wfl_op2 != empty_stmt_node)
+                     && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
                    unreachable_stmt_error (*ptr);
                }
              ptr = next;
@@ -10389,26 +10394,30 @@ java_complete_lhs (node)
       wfl_op2 = TREE_OPERAND (node, 1);
       TREE_OPERAND (node, 0) = nn = 
        java_complete_tree (TREE_OPERAND (node, 0));
-      if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK
-         && wfl_op2 != empty_stmt_node)
-       {
-         /* An unreachable condition in a do-while statement
-            is *not* (technically) an unreachable statement. */
-         nn = wfl_op2;
-         if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
-           nn = EXPR_WFL_NODE (nn);
-         if (TREE_CODE (nn) != EXIT_EXPR)
+      if (wfl_op2 == empty_stmt_node)
+       CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
+      else
+       {
+         if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
            {
-             SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
-             parse_error_context (wfl_operator, "Unreachable statement");
+             /* An unreachable condition in a do-while statement
+                is *not* (technically) an unreachable statement. */
+             nn = wfl_op2;
+             if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
+               nn = EXPR_WFL_NODE (nn);
+             if (TREE_CODE (nn) != EXIT_EXPR)
+               {
+                 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
+                 parse_error_context (wfl_operator, "Unreachable statement");
+               }
            }
+         TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
+         if (TREE_OPERAND (node, 1) == error_mark_node)
+           return error_mark_node;
+         CAN_COMPLETE_NORMALLY (node)
+           = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
        }
-      TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
-      if (TREE_OPERAND (node, 1) == error_mark_node)
-       return error_mark_node;
       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
-      CAN_COMPLETE_NORMALLY (node)
-       = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
       break;
 
     case RETURN_EXPR:
@@ -10420,6 +10429,8 @@ java_complete_lhs (node)
          || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
        {
          node = resolve_expression_name (node, NULL);
+         if (node == error_mark_node)
+           return node;
          CAN_COMPLETE_NORMALLY (node) = 1;
        }
       else
@@ -10430,9 +10441,9 @@ java_complete_lhs (node)
          body = java_complete_tree (EXPR_WFL_NODE (node));
          lineno = save_lineno;
          EXPR_WFL_NODE (node) = body;
-         TREE_SIDE_EFFECTS (node) = 1;
+         TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
          CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
-         if (EXPR_WFL_NODE (node) == error_mark_node)
+         if (body == error_mark_node)
            {
              /* Its important for the evaluation of assignment that
                 this mark on the TREE_TYPE is propagated. */
@@ -10494,7 +10505,7 @@ java_complete_lhs (node)
              tree_cons (wfl, decl, 
                         DECL_CONSTRUCTOR_CALLS (current_function_decl));
          CAN_COMPLETE_NORMALLY (node) = 1;
-         return node;
+         return force_evaluation_order (node);
        }
 
     case MODIFY_EXPR:
@@ -10603,7 +10614,7 @@ java_complete_lhs (node)
          if (TREE_OPERAND (node, 1) == error_mark_node)
            return error_mark_node;
        }
-      return patch_binop (node, wfl_op1, wfl_op2);
+      return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
 
     case INSTANCEOF_EXPR:
       wfl_op1 = TREE_OPERAND (node, 0);
@@ -11573,6 +11584,8 @@ patch_binop (node, wfl_op1, wfl_op2)
        {
          tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
          COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
+         TREE_SIDE_EFFECTS (mod)
+           = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
          return mod;
        }
       break;
@@ -11659,6 +11672,8 @@ patch_binop (node, wfl_op1, wfl_op2)
          to_return = convert (prom_type, node);
          /* Copy the original value of the COMPOUND_ASSIGN_P flag */
          COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
+         TREE_SIDE_EFFECTS (to_return)
+           = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
          return to_return;
        }
       break;
@@ -11693,6 +11708,7 @@ patch_binop (node, wfl_op1, wfl_op2)
          else if (flag_emit_class_files)
            {
              TREE_OPERAND (node, 1) = op2_type;
+             TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
              return node;
            }
          /* Otherwise we have to invoke instance of to figure it out */
@@ -11706,7 +11722,7 @@ patch_binop (node, wfl_op1, wfl_op2)
                        build_tree_list (NULL_TREE,
                                         build_class_ref (op2_type))),
                       NULL_TREE);
-             TREE_SIDE_EFFECTS (call) = 1;
+             TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
              return call;
            }
        }
@@ -11843,6 +11859,8 @@ patch_binop (node, wfl_op1, wfl_op2)
   TREE_OPERAND (node, 0) = op1;
   TREE_OPERAND (node, 1) = op2;
   TREE_TYPE (node) = prom_type;
+  TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+  
   return fold (node);
 }
 
@@ -11962,6 +11980,8 @@ build_string_concatenation (op1, op2)
      tree op1, op2;
 {
   tree result;
+  int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+
   
   /* Try to do some static optimization */
   if ((result = string_constant_concatenation (op1, op2)))
@@ -12014,7 +12034,8 @@ build_string_concatenation (op1, op2)
 
   /* Mark the last node holding a crafted StringBuffer */
   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
-  
+
+  TREE_SIDE_EFFECTS (op1) = side_effects;
   return op1;
 }
 
@@ -12264,7 +12285,11 @@ patch_unaryop (node, wfl_op)
          error_found = 1;
        }
       else
-       return fold (value);
+       {
+         value = fold (value);
+         TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
+         return value;
+       }
       break;
     }
   
@@ -12276,6 +12301,7 @@ patch_unaryop (node, wfl_op)
      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
   TREE_OPERAND (node, 0) = fold (op);
   TREE_TYPE (node) = prom_type;
+  TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
   return fold (node);
 }
 
@@ -12464,7 +12490,16 @@ patch_array_ref (node)
       TREE_OPERAND (node, 1) = index;
     }
   else
-    node = build_java_arrayaccess (array, array_type, index);
+    {
+      /* The save_expr is for correct evaluation order.  It would be cleaner
+        to use force_evaluation_order (see comment there), but that is
+        difficult when we also have to deal with bounds checking. */
+      if (TREE_SIDE_EFFECTS (index))
+       array = save_expr (array);
+      node = build_java_arrayaccess (array, array_type, index);
+      if (TREE_SIDE_EFFECTS (index))
+       node = build (COMPOUND_EXPR, array_type, array, node);
+    }
   TREE_TYPE (node) = array_type;
   return node;
 }
index aa35bd6d58db5d79ba6fec40beb69fa17512104d..fa6b338ebd6d704c984793df5b3b14b417b2d883 100644 (file)
@@ -509,24 +509,6 @@ static jdeplist *reverse_jdep_list ();
                        (ARG ? build_tree_list (NULL, (ARG)) : NULL_TREE))
 
 /* For exception handling, build diverse function calls */
-#define BUILD_MONITOR_ENTER(WHERE, ARG)                                \
-  {                                                            \
-    (WHERE) = build (CALL_EXPR, int_type_node,                 \
-                    build_address_of (soft_monitorenter_node), \
-                    build_tree_list (NULL_TREE, (ARG)),        \
-                    NULL_TREE);                                \
-    TREE_SIDE_EFFECTS (WHERE) = 1;                             \
-  }
-
-#define BUILD_MONITOR_EXIT(WHERE, ARG)                         \
-  {                                                            \
-    (WHERE) = build (CALL_EXPR, int_type_node,                 \
-                    build_address_of (soft_monitorexit_node),  \
-                    build_tree_list (NULL_TREE, (ARG)),        \
-                    NULL_TREE);                                \
-    TREE_SIDE_EFFECTS (WHERE) = 1;                             \
-  }
-
 #define BUILD_ASSIGN_EXCEPTION_INFO(WHERE, TO)         \
   {                                                    \
     (WHERE) = build (MODIFY_EXPR, void_type_node, (TO),        \
index b548ad1b1a1185b12cf1de063579e14b533bc433..8964e450fdab284c9c17eeff701f1c34c997abdb 100644 (file)
@@ -5464,7 +5464,6 @@ expand_start_java_method (fndecl)
   *ptr = NULL_TREE;
   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
-  complete_start_java_method (fndecl); 
 }
 
 /* Terminate a function and expand its body.  */
@@ -5731,6 +5730,7 @@ java_complete_expand_method (mdecl)
       tree fbody = DECL_FUNCTION_BODY (mdecl);
       tree block_body = BLOCK_EXPR_BODY (fbody);
       expand_start_java_method (mdecl);
+      build_result_decl (mdecl);
 
       current_this 
        = (!METHOD_STATIC (mdecl) ? 
@@ -5753,6 +5753,8 @@ java_complete_expand_method (mdecl)
          && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
        missing_return_error (current_function_decl);
 
+      complete_start_java_method (mdecl); 
+
       /* Don't go any further if we've found error(s) during the
          expansion */
       if (!java_error_count)
@@ -8053,7 +8055,7 @@ java_complete_lhs (node)
        return error_mark_node;
       if (!flag_emit_class_files)
        TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
-      return force_evaluation_order (patch_array_ref (node));
+      return patch_array_ref (node);
 
     case RECORD_TYPE:
       return node;;
@@ -9886,7 +9888,16 @@ patch_array_ref (node)
       TREE_OPERAND (node, 1) = index;
     }
   else
-    node = build_java_arrayaccess (array, array_type, index);
+    {
+      /* The save_expr is for correct evaluation order.  It would be cleaner
+        to use force_evaluation_order (see comment there), but that is
+        difficult when we also have to deal with bounds checking. */
+      if (TREE_SIDE_EFFECTS (index))
+       array = save_expr (array);
+      node = build_java_arrayaccess (array, array_type, index);
+      if (TREE_SIDE_EFFECTS (index))
+       node = build (COMPOUND_EXPR, array_type, array, node);
+    }
   TREE_TYPE (node) = array_type;
   return node;
 }