From f173506ef6202d1929befc36168bcb32585db728 Mon Sep 17 00:00:00 2001 From: tromey Date: Thu, 8 Nov 2001 15:33:40 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46845 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/java/ChangeLog | 8 ++++++++ gcc/java/jcf-write.c | 3 ++- gcc/java/parse.y | 53 +++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 2af05a1..ce4073f 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,11 @@ +2001-11-07 Tom Tromey + + 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 * parse.y (patch_assignment): Removed unused third argument. diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index 5f72b7c..4262f41 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -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 diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 58a2b30..bc79e58 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -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 (¤t_this, 1); ggc_add_tree_root (¤tly_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) { -- 2.7.4