]> gcc.gnu.org Git - gcc.git/commitdiff
Patch for PR java/1414:
authorTom Tromey <tromey@redhat.com>
Thu, 8 Nov 2001 15:33:40 +0000 (15:33 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Thu, 8 Nov 2001 15:33:40 +0000 (15:33 +0000)
* parse.y (case_label_list): New global.
(goal): Register case_label_list with GC.
(java_complete_lhs): Save new case on case_label_list.
(patch_switch_statement): Check for duplicate case labels.

From-SVN: r46845

gcc/java/ChangeLog
gcc/java/jcf-write.c
gcc/java/parse.y

index 2af05a1b224bf6541354cc3f221bc9d5bbf0a575..ce4073ffb573bba83923559b2a64837d4a25bcef 100644 (file)
@@ -1,3 +1,11 @@
+2001-11-07  Tom Tromey  <tromey@redhat.com>
+
+       Patch for PR java/1414:
+       * parse.y (case_label_list): New global.
+       (goal): Register case_label_list with GC.
+       (java_complete_lhs): Save new case on case_label_list.
+       (patch_switch_statement): Check for duplicate case labels.
+
 2001-11-07  Alexandre Petit-Bianco  <apbianco@redhat.com>
 
        * parse.y (patch_assignment): Removed unused third argument.
index 5f72b7cf70d7c4df3f106b13ce9e913a26b0c1b9..4262f41078fcf5f9e79dee8cae43c98b92763197 100644 (file)
@@ -1757,7 +1757,8 @@ generate_bytecode_insns (exp, target, state)
                    gap_start--;
                  }
                relocs[gap_start++] = reloc;
-               /* Note we don't check for duplicates.  FIXME! */
+               /* Note we don't check for duplicates.  This is
+                  handled by the parser.  */
              }
 
            if (2 * sw_state.num_cases
index 58a2b304d189d1dc413016ed2c45d6677f61bcf8..bc79e582b42cf26849eae6c98d9d056fca6936a0 100644 (file)
@@ -422,6 +422,13 @@ static tree current_this;
    the list of the catch clauses of the currently analysed try block. */
 static tree currently_caught_type_list;
 
+/* This holds a linked list of all the case labels for the current
+   switch statement.  It is only used when checking to see if there
+   are duplicate labels.  FIXME: probably this should just be attached
+   to the switch itself; then it could be referenced via
+   `ctxp->current_loop'.  */
+static tree case_label_list; 
+
 static tree src_parse_roots[1] = { NULL_TREE };
 
 /* All classes seen from source code */
@@ -622,6 +629,7 @@ goal:
                  ggc_add_tree_root (&package_list, 1);
                  ggc_add_tree_root (&current_this, 1);
                  ggc_add_tree_root (&currently_caught_type_list, 1);
+                 ggc_add_tree_root (&case_label_list, 1);
                  ggc_add_root (&ctxp, 1, 
                                sizeof (struct parser_ctxt *),
                                mark_parser_ctxt);
@@ -11674,9 +11682,12 @@ java_complete_lhs (node)
       TREE_CONSTANT_OVERFLOW (cn) = 0;
       CAN_COMPLETE_NORMALLY (cn) = 1;
 
-      /* Multiple instance of a case label bearing the same
-        value is checked during code generation. The case
-        expression is allright so far. */
+      /* Save the label on a list so that we can later check for
+        duplicates.  */
+      case_label_list = tree_cons (node, cn, case_label_list);
+
+      /* Multiple instance of a case label bearing the same value is
+        checked later. The case expression is all right so far. */
       if (TREE_CODE (cn) == VAR_DECL)
        cn = DECL_INITIAL (cn);
       TREE_OPERAND (node, 0) = cn;
@@ -15404,6 +15415,7 @@ patch_switch_statement (node)
      tree node;
 {
   tree se = TREE_OPERAND (node, 0), se_type;
+  tree save, iter;
 
   /* Complete the switch expression */
   se = TREE_OPERAND (node, 0) = java_complete_tree (se);
@@ -15421,8 +15433,43 @@ patch_switch_statement (node)
       return error_mark_node;
     }
 
+  /* Save and restore the outer case label list.  */
+  save = case_label_list;
+  case_label_list = NULL_TREE;
+
   TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
 
+  /* See if we've found a duplicate label.  We can't leave this until
+     code generation, because in `--syntax-only' and `-C' modes we
+     don't do ordinary code generation.  */
+  for (iter = case_label_list; iter != NULL_TREE; iter = TREE_CHAIN (iter))
+    {
+      HOST_WIDE_INT val = TREE_INT_CST_LOW (TREE_VALUE (iter));
+      tree subiter;
+      for (subiter = TREE_CHAIN (iter);
+          subiter != NULL_TREE;
+          subiter = TREE_CHAIN (subiter))
+       {
+         HOST_WIDE_INT subval = TREE_INT_CST_LOW (TREE_VALUE (subiter));
+         if (val == subval)
+           {
+             EXPR_WFL_LINECOL (wfl_operator)
+               = EXPR_WFL_LINECOL (TREE_PURPOSE (iter));
+             /* The case_label_list is in reverse order, so print the
+                outer label first.  */
+             parse_error_context (wfl_operator, "duplicate case label: `%d'",
+                                  subval);
+             EXPR_WFL_LINECOL (wfl_operator)
+               = EXPR_WFL_LINECOL (TREE_PURPOSE (subiter));
+             parse_error_context (wfl_operator, "original label is here");
+
+             break;
+           }
+       }
+    }
+
+  case_label_list = save;
+
   /* Ready to return */
   if (TREE_CODE (TREE_OPERAND (node, 1)) == ERROR_MARK)
     {
This page took 0.10414 seconds and 5 git commands to generate.