X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=cb0147a17b867b09ceea90a78937e915a59c6fbf;hb=a25daef22bc375bea28f7c8965c69edec5679e84;hp=0852cecd6007046f47277c40bbdff6fba9463c2b;hpb=a6c7a5b4a77d9a9581a6c79b3810229c5b8fce5d;p=cparser diff --git a/parser.c b/parser.c index 0852cec..cb0147a 100644 --- a/parser.c +++ b/parser.c @@ -3592,12 +3592,12 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers) /* type specifiers */ #define MATCH_SPECIFIER(token, specifier, name) \ case token: \ - next_token(); \ if (type_specifiers & specifier) { \ errorf(HERE, "multiple " name " type specifiers given"); \ } else { \ type_specifiers |= specifier; \ } \ + next_token(); \ break MATCH_SPECIFIER(T__Bool, SPECIFIER_BOOL, "_Bool"); @@ -3629,7 +3629,6 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers) break; case T_long: - next_token(); if (type_specifiers & SPECIFIER_LONG_LONG) { errorf(HERE, "multiple type specifiers given"); } else if (type_specifiers & SPECIFIER_LONG) { @@ -3637,6 +3636,7 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers) } else { type_specifiers |= SPECIFIER_LONG; } + next_token(); break; case T_struct: { @@ -7746,6 +7746,48 @@ static bool same_compound_type(const type_t *type1, const type_t *type2) type1->compound.compound == type2->compound.compound; } +static expression_t const *get_reference_address(expression_t const *expr) +{ + bool regular_take_address = true; + for (;;) { + if (expr->kind == EXPR_UNARY_TAKE_ADDRESS) { + expr = expr->unary.value; + } else { + regular_take_address = false; + } + + if (expr->kind != EXPR_UNARY_DEREFERENCE) + break; + + expr = expr->unary.value; + } + + if (expr->kind != EXPR_REFERENCE) + return NULL; + + /* special case for functions which are automatically converted to a + * pointer to function without an extra TAKE_ADDRESS operation */ + if (!regular_take_address && + expr->reference.entity->kind != ENTITY_FUNCTION) { + return NULL; + } + + return expr; +} + +static void warn_reference_address_as_bool(expression_t const* expr) +{ + if (!warning.address) + return; + + expr = get_reference_address(expr); + if (expr != NULL) { + warningf(&expr->base.source_position, + "the address of '%Y' will always evaluate as 'true'", + expr->reference.entity->base.symbol); + } +} + /** * Parse a conditional expression, ie. 'expression ? ... : ...'. * @@ -7758,6 +7800,8 @@ static expression_t *parse_conditional_expression(expression_t *expression) conditional_expression_t *conditional = &result->conditional; conditional->condition = expression; + warn_reference_address_as_bool(expression); + eat('?'); add_anchor_token(':'); @@ -8096,45 +8140,6 @@ static void semantic_unexpr_plus(unary_expression_t *expression) "traditional C rejects the unary plus operator"); } -static expression_t const *get_reference_address(expression_t const *expr) -{ - bool regular_take_address = true; - for (;;) { - if (expr->kind == EXPR_UNARY_TAKE_ADDRESS) { - expr = expr->unary.value; - } else { - regular_take_address = false; - } - - if (expr->kind != EXPR_UNARY_DEREFERENCE) - break; - - expr = expr->unary.value; - } - - /* special case for functions which are automatically converted to a - * pointer to function without an extra TAKE_ADDRESS operation */ - if (!regular_take_address && expr->kind == EXPR_REFERENCE - && expr->reference.entity->kind == ENTITY_FUNCTION) { - return expr; - } - - return NULL; -} - -static void warn_function_address_as_bool(expression_t const* expr) -{ - if (!warning.address) - return; - - expr = get_reference_address(expr); - if (expr != NULL) { - warningf(&expr->base.source_position, - "the address of '%Y' will always evaluate as 'true'", - expr->reference.entity->base.symbol); - } -} - static void semantic_not(unary_expression_t *expression) { type_t *const orig_type = expression->value->base.type; @@ -8144,7 +8149,7 @@ static void semantic_not(unary_expression_t *expression) "operand of ! must be of scalar type"); } - warn_function_address_as_bool(expression->value); + warn_reference_address_as_bool(expression->value); expression->base.type = c_mode & _CXX ? type_bool : type_int; } @@ -8744,8 +8749,8 @@ static void semantic_logical_op(binary_expression_t *expression) type_t *const type_left = skip_typeref(orig_type_left); type_t *const type_right = skip_typeref(orig_type_right); - warn_function_address_as_bool(left); - warn_function_address_as_bool(right); + warn_reference_address_as_bool(left); + warn_reference_address_as_bool(right); if (!is_type_scalar(type_left) || !is_type_scalar(type_right)) { /* TODO: improve error message */ @@ -9538,6 +9543,7 @@ static statement_t *parse_if(void) add_anchor_token(')'); expression_t *const expr = parse_expression(); statement->ifs.condition = expr; + warn_reference_address_as_bool(expr); mark_vars_read(expr, NULL); rem_anchor_token(')'); expect(')');