X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=19e165e7eb5e1062106c5ecbfa7fe88e2798d8be;hb=8845feb009950d2c76a394660a5bd81a0be0f2a6;hp=830d08f77b10e8a20ef8c133a54f80d2a98da819;hpb=f467b3a652163b047ab2079540e4ad499e277079;p=cparser diff --git a/parser.c b/parser.c index 830d08f..19e165e 100644 --- a/parser.c +++ b/parser.c @@ -1,21 +1,6 @@ /* * This file is part of cparser. - * Copyright (C) 2007-2009 Matthias Braun - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * Copyright (C) 2012 Matthias Braun */ #include @@ -173,7 +158,8 @@ typedef enum declarator_flags_t { static entity_t *parse_declarator(const declaration_specifiers_t *specifiers, declarator_flags_t flags); -static void semantic_comparison(binary_expression_t *expression); +static void semantic_comparison(binary_expression_t *expression, + bool is_relational); #define STORAGE_CLASSES \ STORAGE_CLASSES_NO_EXTERN \ @@ -1534,7 +1520,13 @@ static designator_t *parse_designation(void) designator->pos = *HERE; eat('['); add_anchor_token(']'); + add_anchor_token(T_DOTDOTDOT); designator->array_index = parse_constant_expression(); + if (accept(T_DOTDOTDOT)) { + designator->range_last = parse_constant_expression(); + errorf(&designator->pos, "range initializer not supported"); + } + rem_anchor_token(T_DOTDOTDOT); rem_anchor_token(']'); expect(']'); break; @@ -4079,9 +4071,7 @@ warn_redundant_declaration: ; decl->attributes); if (has_new_attrs) { merge_in_attributes(decl, prev_decl->attributes); - } else if (!is_definition && - is_type_valid(prev_type) && - !pos->is_system_header) { + } else if (!is_definition && is_type_valid(prev_type)) { warningf(WARN_REDUNDANT_DECLS, pos, "redundant declaration for '%N' (declared %P)", entity, ppos); } } else if (current_function == NULL) { @@ -5396,6 +5386,7 @@ static expression_t *create_select(const position_t *pos, expression_t *addr, check_deprecated(pos, entry); expression_t *select = allocate_expression_zero(EXPR_SELECT); + select->base.pos = *pos; select->select.compound = addr; select->select.compound_entry = entry; @@ -5446,7 +5437,6 @@ static expression_t *find_create_select(const position_t *pos, continue; expression_t *sub_addr = create_select(pos, addr, qualifiers, iter); - sub_addr->base.pos = *pos; sub_addr->base.implicit = true; return find_create_select(pos, sub_addr, qualifiers, sub_compound, symbol); @@ -6305,17 +6295,9 @@ static expression_t *parse_cast(void) return cast; } -static expression_t *parse_complex_extract_expression(void) +static expression_t *parse_complex_extract_expression(expression_kind_t const kind) { - expression_kind_t kind; - if (token.kind == T___imag__) { - kind = EXPR_UNARY_IMAG; - } else { - assert(token.kind == T___real__); - kind = EXPR_UNARY_REAL; - } expression_t *extract = allocate_expression_zero(kind); - extract->base.pos = *HERE; next_token(); extract->unary.value = parse_subexpression(PREC_CAST); @@ -6427,9 +6409,6 @@ static designator_t *parse_designator(void) designator->array_index = parse_expression(); rem_anchor_token(']'); expect(']'); - if (designator->array_index == NULL) { - return NULL; - } last_designator->next = designator; last_designator = designator; @@ -6596,7 +6575,7 @@ static expression_t *parse_builtin_constant(void) add_anchor_token(')'); expect('('); - expression->builtin_constant.value = parse_assignment_expression(); + expression->builtin_constant.value = parse_expression(); rem_anchor_token(')'); expect(')'); expression->base.type = type_int; @@ -6666,7 +6645,7 @@ static expression_t *parse_compare_builtin(void) &expression->base.pos, orig_type_left, orig_type_right); } } else { - semantic_comparison(&expression->binary); + semantic_comparison(&expression->binary, true); } return expression; @@ -6683,7 +6662,7 @@ static expression_t *parse_assume(void) add_anchor_token(')'); expect('('); - expression->unary.value = parse_assignment_expression(); + expression->unary.value = parse_expression(); rem_anchor_token(')'); expect(')'); @@ -6809,8 +6788,8 @@ static expression_t *parse_primary_expression(void) case '(': return parse_parenthesized_expression(); case T___noop: return parse_noop_expression(); - case T___real__: - case T___imag__: return parse_complex_extract_expression(); + case T___imag__: return parse_complex_extract_expression(EXPR_UNARY_IMAG); + case T___real__: return parse_complex_extract_expression(EXPR_UNARY_REAL); /* Gracefully handle type names while parsing expressions. */ case T_COLONCOLON: @@ -8155,10 +8134,9 @@ static void warn_comparison(position_t const *const pos, expression_t const *con /** * Check the semantics of comparison expressions. - * - * @param expression The expression to check. */ -static void semantic_comparison(binary_expression_t *expression) +static void semantic_comparison(binary_expression_t *expression, + bool is_relational) { position_t const *const pos = &expression->base.pos; expression_t *const left = expression->left; @@ -8190,14 +8168,17 @@ static void semantic_comparison(binary_expression_t *expression) } } - expression->left = create_implicit_cast(left, arithmetic_type); - expression->right = create_implicit_cast(right, arithmetic_type); - expression->base.type = arithmetic_type; - if ((expression->base.kind == EXPR_BINARY_EQUAL || - expression->base.kind == EXPR_BINARY_NOTEQUAL) && - is_type_float(arithmetic_type)) { + expression->left = create_implicit_cast(left, arithmetic_type); + expression->right = create_implicit_cast(right, arithmetic_type); + expression->base.type = arithmetic_type; + if (!is_relational && is_type_float(arithmetic_type)) { warningf(WARN_FLOAT_EQUAL, pos, "comparing floating point with == or != is unsafe"); } + /* for relational ops we need real types, not just arithmetic */ + if (is_relational + && (!is_type_real(type_left) || !is_type_real(type_right))) { + type_error_incompatible("invalid operands for relational operator", pos, type_left, type_right); + } } else if (is_type_pointer(type_left) && is_type_pointer(type_right)) { /* TODO check compatibility */ } else if (is_type_pointer(type_left)) { @@ -8210,6 +8191,16 @@ static void semantic_comparison(binary_expression_t *expression) expression->base.type = c_mode & _CXX ? type_bool : type_int; } +static void semantic_relational(binary_expression_t *expression) +{ + semantic_comparison(expression, true); +} + +static void semantic_equality(binary_expression_t *expression) +{ + semantic_comparison(expression, false); +} + /** * Checks if a compound type has constant fields. */ @@ -8599,12 +8590,12 @@ CREATE_BINEXPR_PARSER('+', EXPR_BINARY_ADD, PR CREATE_BINEXPR_PARSER('-', EXPR_BINARY_SUB, PREC_MULTIPLICATIVE, semantic_sub) CREATE_BINEXPR_PARSER(T_LESSLESS, EXPR_BINARY_SHIFTLEFT, PREC_ADDITIVE, semantic_shift_op) CREATE_BINEXPR_PARSER(T_GREATERGREATER, EXPR_BINARY_SHIFTRIGHT, PREC_ADDITIVE, semantic_shift_op) -CREATE_BINEXPR_PARSER('<', EXPR_BINARY_LESS, PREC_SHIFT, semantic_comparison) -CREATE_BINEXPR_PARSER('>', EXPR_BINARY_GREATER, PREC_SHIFT, semantic_comparison) -CREATE_BINEXPR_PARSER(T_LESSEQUAL, EXPR_BINARY_LESSEQUAL, PREC_SHIFT, semantic_comparison) -CREATE_BINEXPR_PARSER(T_GREATEREQUAL, EXPR_BINARY_GREATEREQUAL, PREC_SHIFT, semantic_comparison) -CREATE_BINEXPR_PARSER(T_EXCLAMATIONMARKEQUAL, EXPR_BINARY_NOTEQUAL, PREC_RELATIONAL, semantic_comparison) -CREATE_BINEXPR_PARSER(T_EQUALEQUAL, EXPR_BINARY_EQUAL, PREC_RELATIONAL, semantic_comparison) +CREATE_BINEXPR_PARSER('<', EXPR_BINARY_LESS, PREC_SHIFT, semantic_relational) +CREATE_BINEXPR_PARSER('>', EXPR_BINARY_GREATER, PREC_SHIFT, semantic_relational) +CREATE_BINEXPR_PARSER(T_LESSEQUAL, EXPR_BINARY_LESSEQUAL, PREC_SHIFT, semantic_relational) +CREATE_BINEXPR_PARSER(T_GREATEREQUAL, EXPR_BINARY_GREATEREQUAL, PREC_SHIFT, semantic_relational) +CREATE_BINEXPR_PARSER(T_EXCLAMATIONMARKEQUAL, EXPR_BINARY_NOTEQUAL, PREC_RELATIONAL, semantic_equality) +CREATE_BINEXPR_PARSER(T_EQUALEQUAL, EXPR_BINARY_EQUAL, PREC_RELATIONAL, semantic_equality) CREATE_BINEXPR_PARSER('&', EXPR_BINARY_BITWISE_AND, PREC_EQUALITY, semantic_binexpr_integer) CREATE_BINEXPR_PARSER('^', EXPR_BINARY_BITWISE_XOR, PREC_AND, semantic_binexpr_integer) CREATE_BINEXPR_PARSER('|', EXPR_BINARY_BITWISE_OR, PREC_XOR, semantic_binexpr_integer)