From: Michael Beck Date: Wed, 12 Dec 2007 01:35:44 +0000 (+0000) Subject: - check for case labels outside a switch statement X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=64bf64a7a86bc49d31bb0d7a1e9f90f94cf259bb;hp=524755e6c9e00c7aa78ecd7da9ecc3b15e795a43;p=cparser - check for case labels outside a switch statement - add infrastructure for further case label checks [r18690] --- diff --git a/ast_t.h b/ast_t.h index d19147a..79418c5 100644 --- a/ast_t.h +++ b/ast_t.h @@ -474,9 +474,10 @@ struct if_statement_t { }; struct switch_statement_t { - statement_base_t statement; - expression_t *expression; - statement_t *body; + statement_base_t statement; + expression_t *expression; + statement_t *body; + case_label_statement_t *first_case, *last_case; }; struct goto_statement_t { @@ -485,9 +486,10 @@ struct goto_statement_t { }; struct case_label_statement_t { - statement_base_t statement; - expression_t *expression; - statement_t *label_statement; + statement_base_t statement; + expression_t *expression; + statement_t *label_statement; + case_label_statement_t *next; /**< link to the next case label in the switch */ }; struct label_statement_t { diff --git a/parser.c b/parser.c index 0e45442..d34696a 100644 --- a/parser.c +++ b/parser.c @@ -39,15 +39,16 @@ struct declaration_specifiers_t { typedef declaration_t* (*parsed_declaration_func) (declaration_t *declaration); -static token_t token; -static token_t lookahead_buffer[MAX_LOOKAHEAD]; -static int lookahead_bufpos; -static stack_entry_t *environment_stack = NULL; -static stack_entry_t *label_stack = NULL; -static context_t *global_context = NULL; -static context_t *context = NULL; -static declaration_t *last_declaration = NULL; -static declaration_t *current_function = NULL; +static token_t token; +static token_t lookahead_buffer[MAX_LOOKAHEAD]; +static int lookahead_bufpos; +static stack_entry_t *environment_stack = NULL; +static stack_entry_t *label_stack = NULL; +static context_t *global_context = NULL; +static context_t *context = NULL; +static declaration_t *last_declaration = NULL; +static declaration_t *current_function = NULL; +static switch_statement_t *current_switch = NULL; static struct obstack temp_obst; /** The current source position. */ @@ -4847,6 +4848,19 @@ static statement_t *parse_case_statement(void) statement->case_label.expression = parse_expression(); expect(':'); + + if (current_switch != NULL) { + /* link all cases into the switch statement */ + if (current_switch->last_case == NULL) { + current_switch->first_case = + current_switch->last_case = &statement->case_label; + } else { + current_switch->last_case->next = &statement->case_label; + } + } else { + errorf(statement->base.source_position, + "case label not within a switch statement"); + } statement->case_label.label_statement = parse_statement(); return statement; @@ -4973,7 +4987,11 @@ static statement_t *parse_switch(void) type_t *const type = promote_integer(skip_typeref(expr->base.datatype)); statement->expression = create_implicit_cast(expr, type); expect(')'); + + switch_statement_t *rem = current_switch; + current_switch = &statement; statement->body = parse_statement(); + current_switch = rem; return (statement_t*) statement; }