authorbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 15 Nov 1998 14:37:52 +0000 (14:37 +0000)
committerbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 15 Nov 1998 14:37:52 +0000 (14:37 +0000)
* decl.c (error_mark_node), java-tree.h:  New global.
* parse.y:  Use empty_stmt_node instead of size_zero_node.
(build_if_else_statement):  If missing else, use empty_stmt_node.
* parse.y (not_initialized_as_it_should_p):  Removed, with its callers.
(java_complete_expand_method):  Complain if return is missing.
(java_check_regular_methods):  Comment out incorrect error check.
(not_accessible_p):  Fix incorrect handling of protected methods.
(patch_method_invocation):  Pass correct context to not_accessible_p.
(find_applicable_accessible_methods_list):  Likewise.
(qualify_ambiguous_name):  If ARRAY_REF, it's an expression name.
(java_complete_tree):  For CASE_EXPR and DEFAULT_EXPR, set
TREE_TYPE (to void_type_node);  otherwise expand_expr crashes.
(patch_if_else_statement):  Fix setting of CAN_COMPLETE_NORMALLY.
* jcf-write.c (CHECK_OP, CHECK_PUT):  Add some error checking.
(push_int_const):  Remove reundant NOTE_PUSH.
(generate_bytecode_insns - case STRING_CST):  Do NOTE_PUSH.
(- case SWITCH_EXPR):  Fix code generation bug.
(- case PREDECREMENT_EXPR etc):  Remove redundant NOTE_PUSH.
(generate_classfile):  More robust for abstract methods.

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

gcc/java/ChangeLog
gcc/java/decl.c
gcc/java/java-tree.h
gcc/java/jcf-write.c
gcc/java/parse.y

index 2310854..a9da798 100644 (file)
@@ -1,3 +1,27 @@
+Sun Nov 15 14:36:29 1998  Per Bothner  <bothner@cygnus.com>
+
+       * decl.c (error_mark_node), java-tree.h:  New global.
+       * parse.y:  Use empty_stmt_node instead of size_zero_node.
+       (build_if_else_statement):  If missing else, use empty_stmt_node.
+
+       * parse.y (not_initialized_as_it_should_p):  Removed, with its callers.
+       (java_complete_expand_method):  Complain if return is missing.
+       (java_check_regular_methods):  Comment out incorrect error check.
+       (not_accessible_p):  Fix incorrect handling of protected methods.
+       (patch_method_invocation):  Pass correct context to not_accessible_p.
+       (find_applicable_accessible_methods_list):  Likewise.
+       (qualify_ambiguous_name):  If ARRAY_REF, it's an expression name.
+       (java_complete_tree):  For CASE_EXPR and DEFAULT_EXPR, set
+       TREE_TYPE (to void_type_node);  otherwise expand_expr crashes.
+       (patch_if_else_statement):  Fix setting of CAN_COMPLETE_NORMALLY.
+
+       * jcf-write.c (CHECK_OP, CHECK_PUT):  Add some error checking.
+       (push_int_const):  Remove reundant NOTE_PUSH.
+       (generate_bytecode_insns - case STRING_CST):  Do NOTE_PUSH.
+       (- case SWITCH_EXPR):  Fix code generation bug.
+       (- case PREDECREMENT_EXPR etc):  Remove redundant NOTE_PUSH.
+       (generate_classfile):  More robust for abstract methods.
+
 Sun Nov 15 13:52:39 1998  Anthony Green  <green@cygnus.com>
 
        * Makefile.in: jv-scan and jvgenmain all require libiberty.
index c625075..24118b9 100644 (file)
@@ -318,6 +318,7 @@ tree error_mark_node;
    The first is of type `int', the second of type `void *'.  */
 tree integer_zero_node;
 tree null_pointer_node;
+tree empty_stmt_node;
 
 /* Nodes for boolean constants TRUE and FALSE. */
 tree boolean_true_node, boolean_false_node;
@@ -431,8 +432,6 @@ init_decl_processing ()
   TREE_TYPE (size_zero_node) = sizetype;
   size_one_node = build_int_2 (1, 0);
   TREE_TYPE (size_one_node) = sizetype;
-  /* Used by the parser to represent empty statements and blocks. */
-  CAN_COMPLETE_NORMALLY (size_zero_node) = 1;
 
   byte_type_node = make_signed_type (8);
   pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"), byte_type_node));
@@ -475,6 +474,10 @@ init_decl_processing ()
   null_pointer_node = build_int_2 (0, 0);
   TREE_TYPE (null_pointer_node) = ptr_type_node;
 
+  /* Used by the parser to represent empty statements and blocks. */
+  empty_stmt_node = build1 (NOP_EXPR, void_type_node, size_zero_node);
+  CAN_COMPLETE_NORMALLY (empty_stmt_node) = 1;
+
 #if 0
   /* Make a type to be the domain of a few array types
      whose domains don't really matter.
index eedcb00..de9e1a3 100644 (file)
@@ -220,6 +220,7 @@ extern tree boolean_true_node, boolean_false_node;
 extern tree integer_negative_one_node;
 extern tree integer_two_node;
 extern tree integer_four_node;
+extern tree empty_stmt_node;
 
 /* The type for struct methodtable. */
 extern tree methodtable_type;
index 5e76337..64c9e06 100644 (file)
@@ -50,34 +50,25 @@ char *jcf_write_base_directory = NULL;
 /* Make sure bytecode.data is big enough for at least N more bytes. */
 
 #define RESERVE(N) \
-  do { if (state->bytecode.ptr + (N) > state->bytecode.limit) \
+  do { CHECK_OP(state); \
+    if (state->bytecode.ptr + (N) > state->bytecode.limit) \
     buffer_grow (&state->bytecode, N); } while (0)
 
 /* Add a 1-byte instruction/operand I to bytecode.data,
    assuming space has already been RESERVE'd. */
 
-#define OP1(I) (*state->bytecode.ptr++ = (I))
+#define OP1(I) (*state->bytecode.ptr++ = (I), CHECK_OP(state))
 
 /* Like OP1, but I is a 2-byte big endian integer. */
 
 #define OP2(I) \
-  do { int _i = (I);  OP1 (_i >> 8);  OP1 (_i); } while (0)
+  do { int _i = (I); OP1 (_i >> 8);  OP1 (_i); CHECK_OP(state); } while (0)
 
 /* Like OP1, but I is a 4-byte big endian integer. */
 
 #define OP4(I) \
   do { int _i = (I);  OP1 (_i >> 24);  OP1 (_i >> 16); \
-       OP1 (_i >> 8); OP1 (_i); } while (0)
-
-/* The current stack size (stack pointer) in the current method. */
-
-int code_SP = 0;
-
-/* The largest extent of stack size (stack pointer) in the current method. */
-
-int code_SP_max = 0;
-
-CPool *code_cpool;
+       OP1 (_i >> 8); OP1 (_i); CHECK_OP(state); } while (0)
 
 /* Macro to call each time we push I words on the JVM stack. */
 
@@ -138,7 +129,13 @@ struct jcf_block
   } u;
 };
 
+/* A "relocation" type for the 0-3 bytes of padding at the start
+   of a tableswitch or a lookupswitch. */
 #define SWITCH_ALIGN_RELOC 4
+
+/* A relocation type for the labels in a tableswitch or a lookupswitch;
+   these are relative to the start of the instruction, but (due to
+   th 0-3 bytes of padding), we don't know the offset before relocation. */
 #define BLOCK_START_RELOC 1
 
 struct jcf_relocation
@@ -253,10 +250,26 @@ static void generate_bytecode_insns PROTO ((tree, int, struct jcf_partial *));
    We assume a local variable 'ptr' points into where we want to
    write next, and we assume enoygh space has been allocated. */
 
-#define PUT1(X)  (*ptr++ = (X))
+#ifdef ENABLE_CHECKING
+int
+CHECK_PUT(ptr, state, i)
+     void *ptr;
+     struct jcf_partial *state;
+     int i;
+{
+  if (ptr < state->chunk->data
+      || (char*)ptr + i > state->chunk->data + state->chunk->size)
+    fatal ("internal error - CHECK_PUT failed");
+  return 0;
+}
+#else
+#define CHECK_PUT(PTR, STATE, I) 0
+#endif
+
+#define PUT1(X)  (CHECK_PUT(ptr, state, 1), *ptr++ = (X))
 #define PUT2(X)  (PUT1((X) >> 8), PUT1((X) & 0xFF))
 #define PUT4(X)  (PUT2((X) >> 16), PUT2((X) & 0xFFFF))
-#define PUTN(P, N)  (memcpy(ptr, P, N), ptr += (N))
+#define PUTN(P, N)  (CHECK_PUT(ptr, state, N), memcpy(ptr, P, N), ptr += (N))
 
 \f
 /* Allocate a new chunk on obstack WORK, and link it in after LAST.
@@ -284,6 +297,20 @@ alloc_chunk (last, data, size, work)
   return chunk;
 }
 
+#ifdef ENABLE_CHECKING
+int
+CHECK_OP(struct jcf_partial *state)
+{
+  if (state->bytecode.ptr > state->bytecode.limit)
+    {
+      fatal("internal error - CHECK_OP failed");
+    }
+  return 0;
+}
+#else
+#define CHECK_OP(STATE) 0
+#endif
+
 unsigned char *
 append_chunk (data, size, state)
      unsigned char *data;
@@ -574,6 +601,9 @@ write_chunks (stream, chunks)
     fwrite (chunks->data, chunks->size, 1, stream);
 }
 
+/* Push a 1-word constant in the constant pool at the given INDEX.
+   (Caller is responsible for doing NOTE_PUSH.) */
+
 static void
 push_constant1 (index, state)
      int index;
@@ -592,6 +622,9 @@ push_constant1 (index, state)
     }
 }
 
+/* Push a 2-word constant in the constant pool at the given INDEX.
+   (Caller is responsible for doing NOTE_PUSH.) */
+
 static void
 push_constant2 (index, state)
      int index;
@@ -622,7 +655,6 @@ push_int_const (i, state)
     {
       OP1(OPCODE_sipush);
       OP2(i);
-      NOTE_PUSH (1);
     }
   else
     {
@@ -1257,6 +1289,7 @@ generate_bytecode_insns (exp, target, state)
       break;
     case STRING_CST:
       push_constant1 (find_string_constant (&state->cpool, exp), state);
+      NOTE_PUSH (1);
       break;
     case VAR_DECL:
       if (TREE_STATIC (exp))
@@ -1473,12 +1506,16 @@ generate_bytecode_insns (exp, target, state)
                OP4 (sw_state.max_case);
                for (i = sw_state.min_case; ; )
                  {
-                   if (i == sw_state.min_case + index)
-                     emit_case_reloc (relocs[index++], state);
+                   reloc = relocs[index];
+                   if (i == reloc->offset)
+                     {
+                       emit_case_reloc (reloc, state);
+                       if (i == sw_state.max_case)
+                         break;
+                       index++;
+                     }
                    else
                      emit_switch_reloc (sw_state.default_label, state);
-                   if (i == sw_state.max_case)
-                     break;
                    i++;
                  }
              }
@@ -1619,12 +1656,8 @@ generate_bytecode_insns (exp, target, state)
          if (target != IGNORE_TARGET && post_op)
            emit_load (exp, state);
          emit_iinc (exp, value, state);
-         if (target != IGNORE_TARGET)
-           {
-             if (! post_op)
-               emit_load (exp, state);
-             NOTE_PUSH (1);
-           }
+         if (target != IGNORE_TARGET && ! post_op)
+           emit_load (exp, state);
          break;
        }
       if (TREE_CODE (exp) == COMPONENT_REF)
@@ -2225,6 +2258,8 @@ perform_relocations (state)
              *--new_ptr = 0;
              *--new_ptr = - reloc->kind;
            }
+         if (new_ptr != chunk->data)
+           fatal ("internal error - perform_relocations");
        }
     }
   state->code_length = pc;
@@ -2352,7 +2387,9 @@ generate_classfile (clas, state)
   for (part = TYPE_METHODS (clas);  part;  part = TREE_CHAIN (part))
     {
       struct jcf_block *block;
-      tree body = BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (part));
+      tree function_body = DECL_FUNCTION_BODY (part);
+      tree body = function_body == NULL_TREE ? NULL_TREE
+       : BLOCK_EXPR_BODY (function_body);
       tree name = DECL_CONSTRUCTOR_P (part) ? init_identifier_node
        : DECL_NAME (part);
       tree type = TREE_TYPE (part);
index 3dc35f4..7a114c2 100644 (file)
@@ -786,7 +786,7 @@ constructor_body:
           addition (super invocation and field initialization) */
        block_begin block_end
                { 
-                 BLOCK_EXPR_BODY ($2) = size_zero_node;
+                 BLOCK_EXPR_BODY ($2) = empty_stmt_node;
                  $$ = $2;
                }
 |      block_begin explicit_constructor_invocation block_end
@@ -951,7 +951,7 @@ variable_initializers:
 /* 19.11 Production from 14: Blocks and Statements  */
 block:
        OCB_TK CCB_TK
-               { $$ = size_zero_node; }
+               { $$ = empty_stmt_node; }
 |      block_begin block_statements block_end
                { $$ = $3; }
 ;
@@ -1033,7 +1033,7 @@ statement_without_trailing_substatement:
 
 empty_statement:
        SC_TK
-               { $$ = size_zero_node; }
+               { $$ = empty_stmt_node; }
 ;
 
 label_decl:
@@ -1273,7 +1273,7 @@ for_statement:
                  $$ = complete_for_loop (0, NULL_TREE, $4, $6);
                  /* We have not condition, so we get rid of the EXIT_EXPR */
                  LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
-                   size_zero_node;
+                   empty_stmt_node;
                }
 |      for_begin SC_TK error
                {yyerror ("Invalid control expression"); RECOVER;}
@@ -1291,7 +1291,7 @@ for_statement_nsi:
                  $$ = complete_for_loop (0, NULL_TREE, $4, $6);
                  /* We have not condition, so we get rid of the EXIT_EXPR */
                  LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
-                   size_zero_node;
+                   empty_stmt_node;
                }
 ;
 
@@ -1322,7 +1322,7 @@ for_begin:
                }
 ;
 for_init:                      /* Can be empty */
-               { $$ = size_zero_node; }
+               { $$ = empty_stmt_node; }
 |      statement_expression_list
                { 
                  /* Init statement recorded within the previously
@@ -1340,7 +1340,7 @@ for_init:                 /* Can be empty */
 ;
 
 for_update:                    /* Can be empty */
-               {$$ = size_zero_node;}
+               {$$ = empty_stmt_node;}
 |      statement_expression_list
                { $$ = build_debugable_stmt (BUILD_LOCATION (), $1); }
 ;
@@ -1636,6 +1636,8 @@ dims:
 field_access:
        primary DOT_TK identifier
                { $$ = make_qualified_primary ($1, $3, $2.location); }
+               /*  FIXME - REWRITE TO: 
+               { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
 |      SUPER_TK DOT_TK identifier
                {
                  tree super_wfl = 
@@ -2164,7 +2166,7 @@ parse_jdk1_1_error (msg)
 {
   sorry (": `%s' JDK1.1(TM) feature", msg);
   java_error_count++;
-  return size_zero_node;
+  return empty_stmt_node;
 }
 
 static int do_warning = 0;
@@ -4206,6 +4208,7 @@ java_check_regular_methods (class_decl)
         exceptions, if any */
       check_throws_clauses (method, method_wfl, found);
 
+#if 0
       /* If the method has default access in an other package, then
         issue a warning that the current method doesn't override the
         one that was found elsewhere. Do not issue this warning when
@@ -4220,6 +4223,7 @@ java_check_regular_methods (class_decl)
           lang_printable_name (found, 0),
           IDENTIFIER_POINTER (DECL_NAME (class_decl)),
           IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+#endif
 
       /* Inheriting multiple methods with the same signature. FIXME */
     }
@@ -5239,6 +5243,8 @@ java_complete_expand_method (mdecl)
   /* Expand functions that have a body */
   if (DECL_FUNCTION_BODY (mdecl))
     {
+      tree fbody = DECL_FUNCTION_BODY (mdecl);
+      tree block_body = BLOCK_EXPR_BODY (fbody);
       expand_start_java_method (mdecl);
 
       current_this 
@@ -5251,9 +5257,16 @@ java_complete_expand_method (mdecl)
       /* Install exceptions thrown with `throws' */
       PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
 
-      if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)))
-       java_complete_tree (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)));
+      if (block_body != NULL_TREE)
+       block_body = java_complete_tree (block_body);
+      BLOCK_EXPR_BODY (fbody) = block_body;
 
+      if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
+         && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
+       {
+         parse_error_context (fbody, "Missing return statement");
+       }
+      
       /* Don't go any further if we've found error(s) during the
          expansion */
       if (!java_error_count)
@@ -6040,26 +6053,14 @@ int not_accessible_p (reference, member, from_super)
       if (class_in_current_package (DECL_CONTEXT (member)))
        return 0;
 
-      if (TREE_CODE (member) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (member))
-       {
-         /* Access from SUPER is granted */
-         if (from_super)
-           return 0;
-         /* Otherwise, access isn't granted */
-         return 1;
-       }
-      else
-       {
-         /* If accessed with the form `super.member', then access is
-             granted */
-         if (from_super)
-           return 0;
+      /* If accessed with the form `super.member', then access is granted */
+      if (from_super)
+       return 0;
 
-         /* Otherwise, access is granted if occuring from the class where
-            member is declared or a subclass of it */
-         if (inherits_from_p (reference, current_class))
-           return 0;
-       }
+      /* Otherwise, access is granted if occuring from the class where
+        member is declared or a subclass of it */
+      if (inherits_from_p (reference, current_class))
+       return 0;
       return 1;
     }
 
@@ -6376,7 +6377,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl, super)
 
   /* Check accessibility, position the is_static flag, build and
      return the call */
-  if (not_accessible_p (DECL_CONTEXT (list), list, 0))
+  if (not_accessible_p (DECL_CONTEXT (current_function_decl), list, 0))
     {
       char *fct_name = strdup (lang_printable_name (list, 0));
       parse_error_context 
@@ -6646,7 +6647,7 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
          if (argument_types_convertible (method, arglist))
            {
              /* Retain accessible methods only */
-             if (!not_accessible_p (class, method, 0))
+             if (!not_accessible_p (DECL_CONTEXT (current_function_decl), method, 0))
                list = tree_cons (NULL_TREE, method, list);
              else
              /* Also retain all selected method here */
@@ -6884,7 +6885,8 @@ qualify_ambiguous_name (id)
     }
 
   /* Method call are expression name */
-  else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR)
+  else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
+          || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF)
     RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
 
   /* Check here that NAME isn't declared by more than one
@@ -6945,22 +6947,6 @@ breakdown_qualified (left, right, source)
   return 0;
 }
 
-static int
-not_initialized_as_it_should_p (decl)
-     tree decl;
-{
-  if (DECL_P (decl))
-    {
-      if (FIELD_FINAL (decl))
-       return 0;
-      if (TREE_CODE (decl) == FIELD_DECL 
-         && (METHOD_STATIC (current_function_decl)))
-       return 0;
-      return DECL_P (decl) && !INITIALIZED_P (decl);
-    }
-  return 0;
-}
-
 /* Patch tree nodes in a function body. When a BLOCK is found, push
    local variable decls if present.  */
 
@@ -7127,6 +7113,7 @@ java_complete_tree (node)
         value is checked during code generation. The case
         expression is allright so far. */
       TREE_OPERAND (node, 0) = cn;
+      TREE_TYPE (node) = void_type_node;
       CAN_COMPLETE_NORMALLY (node) = 1;
       break;
 
@@ -7142,6 +7129,7 @@ java_complete_tree (node)
        }
       else
        SWITCH_HAS_DEFAULT (nn) = 1;
+      TREE_TYPE (node) = void_type_node;
       CAN_COMPLETE_NORMALLY (node) = 1;
       break;
 
@@ -7427,6 +7415,13 @@ java_complete_tree (node)
        TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
       return patch_array_ref (node, wfl_op1, wfl_op2);
 
+#if 0 
+    COMPONENT_REF:
+      /* Planned re-write FIXME */
+      TREE_OPERAND (node, 0) = java_complete_tree (TREE_OPERAND (node, 0));
+      break;
+#endif
+
     case THIS_EXPR:
       /* Can't use THIS in a static environment */
       if (!current_this)
@@ -7490,11 +7485,6 @@ complete_function_arguments (node)
       parm = maybe_build_primttype_type_ref (parm, wfl);
 
       TREE_VALUE (cn) = parm;
-      if (not_initialized_as_it_should_p (parm))
-       {
-         ERROR_VARIABLE_NOT_INITIALIZED (wfl, EXPR_WFL_NODE (wfl));
-         INITIALIZED_P (parm) = 1;
-       }
     }
   ctxp->explicit_constructor_p -= (CALL_THIS_CONSTRUCTOR_P (node) ? 1 : 0);
   return flag;
@@ -7622,14 +7612,14 @@ maybe_absorb_scoping_blocks ()
    are building incomplete tree nodes and the patch_* functions that
    are completing them.  */
 
-/* Build a super() constructor invocation. Returns size_zero_node if
+/* Build a super() constructor invocation. Returns empty_stmt_node if
    we're currently dealing with the class java.lang.Object. */
 
 static tree
 build_super_invocation ()
 {
   if (current_class == object_type_node)
-    return size_zero_node;
+    return empty_stmt_node;
   else
     {
       tree super_wfl = build_wfl_node (super_identifier_node, 
@@ -7880,14 +7870,6 @@ patch_assignment (node, wfl_op1, wfl_op2)
       error_found = 1;
     }
 
-  /* Before reporting type incompatibility errors, check that the rhs
-     is initialized, if a variable */
-  if (not_initialized_as_it_should_p (rhs))
-    {
-      ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (rhs));
-      INITIALIZED_P (rhs) = 1;
-    }
-
   /* Inline read access to java.lang.PRIMTYPE.TYPE */
   rhs = maybe_build_primttype_type_ref (rhs, wfl_op2);
 
@@ -8296,14 +8278,6 @@ patch_binop (node, wfl_op1, wfl_op2)
 
   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
 
-  /* Check initialization of LHS first. We then silence further error
-     message if the variable wasn't initialized */
-  if (not_initialized_as_it_should_p (cfi))
-    {
-      ERROR_VARIABLE_NOT_INITIALIZED (cfi_wfl, DECL_NAME (cfi));
-      INITIALIZED_P (op1) = 1;
-    }
-
   switch (code)
     {
     /* 15.16 Multiplicative operators */
@@ -8581,16 +8555,6 @@ patch_binop (node, wfl_op1, wfl_op2)
       break;
     }
 
-  /* Then check the initialization of the RHS. We don't do that if
-     we're dealing with a node that is part of a compound
-     assignment. We then silence further error message if the variable
-     wasn't initialized */
-  if (not_initialized_as_it_should_p (op2) && !COMPOUND_ASSIGN_P (node))
-    {
-      ERROR_VARIABLE_NOT_INITIALIZED (wfl_op2, DECL_NAME (op2));
-      INITIALIZED_P (op2) = 1;
-    }
-
   if (error_found)
     return error_mark_node;
 
@@ -9424,10 +9388,8 @@ build_if_else_statement (location, expression, if_body, else_body)
      tree expression, if_body, else_body;
 {
   tree node;
-  /* FIXME: make else body be a void node, where this function is
-     called */
   if (!else_body)
-    else_body = build (COMPOUND_EXPR, void_type_node, NULL_TREE, NULL_TREE);
+    else_body = empty_stmt_node;
   node = build (COND_EXPR, NULL_TREE, expression, if_body, else_body);
   EXPR_WFL_LINECOL (node) = location;
   node = build_debugable_stmt (location, node);
@@ -9457,8 +9419,8 @@ patch_if_else_statement (node)
   TREE_TYPE (node) = void_type_node;
   TREE_SIDE_EFFECTS (node) = 1;
   CAN_COMPLETE_NORMALLY (node)
-    = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
-    | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
+    = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
+    | CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 2));
   return node;
 }
 
@@ -9584,7 +9546,7 @@ build_loop_body (location, condition, reversed)
   second = (reversed ? condition : body);
   return 
     build (COMPOUND_EXPR, NULL_TREE, 
-          build (COMPOUND_EXPR, NULL_TREE, first, second), size_zero_node);
+          build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
 }
 
 /* Install CONDITION (if any) and loop BODY (using REVERSED to tell