X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=35762b9a76289530f41e07e421bf16839b262355;hb=23ebb996cbe0f5d2c74184d1cfb783cb2a529a13;hp=a1fb92370af25d1957fee7cd7a5b81e57a1c781d;hpb=3426ea17597cecb7c065260ea8e648a5c3ec50aa;p=cparser diff --git a/parser.c b/parser.c index a1fb923..35762b9 100644 --- a/parser.c +++ b/parser.c @@ -3220,7 +3220,11 @@ static bool has_parameters(void) type_t const *const type = skip_typeref(entity->typedefe.type); if (!is_type_void(type)) return true; - if (type->base.qualifiers != TYPE_QUALIFIER_NONE) { + if (c_mode & _CXX) { + /* ISO/IEC 14882:1998(E) §8.3.5:2 It must be literally (void). A typedef + * is not allowed. */ + errorf(HERE, "empty parameter list defined with a typedef of 'void' not allowed in C++"); + } else if (type->base.qualifiers != TYPE_QUALIFIER_NONE) { /* §6.7.5.3:10 Qualification is not allowed here. */ errorf(HERE, "'void' as parameter must not have type qualifiers"); } @@ -6278,7 +6282,7 @@ static bool semantic_cast(expression_t *cast) source_position_t const *pos = &cast->base.source_position; /* §6.5.4 A (void) cast is explicitly permitted, more for documentation than for utility. */ - if (dst_type == type_void) + if (is_type_void(dst_type)) return true; /* only integer and pointer can be casted to pointer */ @@ -9044,6 +9048,7 @@ end_of_asm: expect(')', end_error); expect(';', end_error); +end_error: if (asm_statement->outputs == NULL) { /* GCC: An 'asm' instruction without any output operands will be treated * identically to a volatile 'asm' instruction. */ @@ -9051,8 +9056,6 @@ end_of_asm: } return statement; -end_error: - return create_error_statement(); } static statement_t *parse_label_inner_statement(statement_t const *const label, char const *const label_kind) @@ -9283,6 +9286,23 @@ static statement_t *parse_inner_statement(void) return stmt; } +/** + * Parse an expression in parentheses and mark its variables as read. + */ +static expression_t *parse_condition(void) +{ + expect('(', end_error0); + add_anchor_token(')'); + expression_t *const expr = parse_expression(); + mark_vars_read(expr, NULL); + rem_anchor_token(')'); + expect(')', end_error1); +end_error1: + return expr; +end_error0: + return create_error_expression(); +} + /** * Parse an if statement. */ @@ -9296,18 +9316,12 @@ static statement_t *parse_if(void) add_anchor_token('{'); - expect('(', end_error); - add_anchor_token(')'); - expression_t *const expr = parse_expression(); + expression_t *const expr = parse_condition(); statement->ifs.condition = expr; /* §6.8.4.1:1 The controlling expression of an if statement shall have * scalar type. */ semantic_condition(expr, "condition of 'if'-statment"); - mark_vars_read(expr, NULL); - rem_anchor_token(')'); - expect(')', end_error); -end_error: rem_anchor_token('{'); add_anchor_token(T_else); @@ -9391,10 +9405,7 @@ static statement_t *parse_switch(void) PUSH_PARENT(statement); - expect('(', end_error); - add_anchor_token(')'); - expression_t *const expr = parse_expression(); - mark_vars_read(expr, NULL); + expression_t *const expr = parse_condition(); type_t * type = skip_typeref(expr->base.type); if (is_type_integer(type)) { type = promote_integer(type); @@ -9407,8 +9418,6 @@ static statement_t *parse_switch(void) type = type_error_type; } statement->switchs.expression = create_implicit_cast(expr, type); - expect(')', end_error); - rem_anchor_token(')'); switch_statement_t *rem = current_switch; current_switch = &statement->switchs; @@ -9422,9 +9431,6 @@ static statement_t *parse_switch(void) POP_PARENT(); return statement; -end_error: - POP_PARENT(); - return create_error_statement(); } static statement_t *parse_loop_body(statement_t *const loop) @@ -9449,24 +9455,16 @@ static statement_t *parse_while(void) PUSH_PARENT(statement); - expect('(', end_error); - add_anchor_token(')'); - expression_t *const cond = parse_expression(); + expression_t *const cond = parse_condition(); statement->whiles.condition = cond; /* §6.8.5:2 The controlling expression of an iteration statement shall * have scalar type. */ semantic_condition(cond, "condition of 'while'-statement"); - mark_vars_read(cond, NULL); - rem_anchor_token(')'); - expect(')', end_error); statement->whiles.body = parse_loop_body(statement); POP_PARENT(); return statement; -end_error: - POP_PARENT(); - return create_error_statement(); } /** @@ -9484,24 +9482,18 @@ static statement_t *parse_do(void) statement->do_while.body = parse_loop_body(statement); rem_anchor_token(T_while); - expect(T_while, end_error); - expect('(', end_error); - add_anchor_token(')'); - expression_t *const cond = parse_expression(); + expect(T_while, end_error0); +end_error0:; + expression_t *const cond = parse_condition(); statement->do_while.condition = cond; /* §6.8.5:2 The controlling expression of an iteration statement shall * have scalar type. */ semantic_condition(cond, "condition of 'do-while'-statement"); - mark_vars_read(cond, NULL); - rem_anchor_token(')'); - expect(')', end_error); - expect(';', end_error); + expect(';', end_error1); +end_error1: POP_PARENT(); return statement; -end_error: - POP_PARENT(); - return create_error_statement(); } /** @@ -9513,12 +9505,12 @@ static statement_t *parse_for(void) eat(T_for); - expect('(', end_error1); - add_anchor_token(')'); - PUSH_PARENT(statement); PUSH_SCOPE(&statement->fors.scope); + expect('(', end_error1); + add_anchor_token(')'); + PUSH_EXTENSION(); if (next_if(';')) { @@ -9533,7 +9525,8 @@ static statement_t *parse_for(void) warningf(WARN_UNUSED_VALUE, &init->base.source_position, "initialisation of 'for'-statement has no effect"); } rem_anchor_token(';'); - expect(';', end_error2); + expect(';', end_error3); +end_error3:; } POP_EXTENSION(); @@ -9549,6 +9542,7 @@ static statement_t *parse_for(void) rem_anchor_token(';'); } expect(';', end_error2); +end_error2: if (token.kind != ')') { expression_t *const step = parse_expression(); statement->fors.step = step; @@ -9557,22 +9551,14 @@ static statement_t *parse_for(void) warningf(WARN_UNUSED_VALUE, &step->base.source_position, "step of 'for'-statement has no effect"); } } - expect(')', end_error2); rem_anchor_token(')'); + expect(')', end_error1); +end_error1: statement->fors.body = parse_loop_body(statement); POP_SCOPE(); POP_PARENT(); return statement; - -end_error2: - POP_PARENT(); - rem_anchor_token(')'); - POP_SCOPE(); - /* fallthrough */ - -end_error1: - return create_error_statement(); } /** @@ -9621,7 +9607,7 @@ static statement_t *parse_goto(void) else parse_error_expected("while parsing goto", T_IDENTIFIER, NULL); eat_until_anchor(); - return create_error_statement(); + statement->gotos.label = &allocate_entity_zero(ENTITY_LABEL, NAMESPACE_LABEL, sym_anonymous)->label; } } @@ -9860,10 +9846,7 @@ static statement_t *parse_ms_try_statment(void) POP_PARENT(); if (next_if(T___except)) { - expect('(', end_error); - add_anchor_token(')'); - expression_t *const expr = parse_expression(); - mark_vars_read(expr, NULL); + expression_t *const expr = parse_condition(); type_t * type = skip_typeref(expr->base.type); if (is_type_integer(type)) { type = promote_integer(type); @@ -9873,18 +9856,11 @@ static statement_t *parse_ms_try_statment(void) type = type_error_type; } statement->ms_try.except_expression = create_implicit_cast(expr, type); - rem_anchor_token(')'); - expect(')', end_error); - statement->ms_try.final_statement = parse_compound_statement(false); - } else if (next_if(T__finally)) { - statement->ms_try.final_statement = parse_compound_statement(false); - } else { + } else if (!next_if(T__finally)) { parse_error_expected("while parsing __try statement", T___except, T___finally, NULL); - return create_error_statement(); } + statement->ms_try.final_statement = parse_compound_statement(false); return statement; -end_error: - return create_error_statement(); } static statement_t *parse_empty_statement(void) @@ -9994,10 +9970,8 @@ end_error: */ static statement_t *intern_parse_statement(void) { - statement_t *statement = NULL; - /* declaration or statement */ - add_anchor_token(';'); + statement_t *statement; switch (token.kind) { case T_IDENTIFIER: { token_kind_t la1_type = (token_kind_t)look_ahead(1)->kind; @@ -10068,14 +10042,9 @@ static statement_t *intern_parse_statement(void) default: errorf(HERE, "unexpected token %K while parsing statement", &token); statement = create_error_statement(); - if (!at_anchor()) - next_token(); + eat_until_anchor(); break; } - rem_anchor_token(';'); - - assert(statement != NULL - && statement->base.source_position.input_name != NULL); return statement; } @@ -10120,6 +10089,7 @@ static statement_t *parse_compound_statement(bool inside_expression_statement) add_anchor_token('*'); add_anchor_token('+'); add_anchor_token('-'); + add_anchor_token(';'); add_anchor_token('{'); add_anchor_token('~'); add_anchor_token(T_CHARACTER_CONSTANT); @@ -10332,6 +10302,7 @@ end_error: rem_anchor_token(T_CHARACTER_CONSTANT); rem_anchor_token('~'); rem_anchor_token('{'); + rem_anchor_token(';'); rem_anchor_token('-'); rem_anchor_token('+'); rem_anchor_token('*');