X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=inline;f=parser.c;h=7e44886f46008e79158729be22a7f0faf84fa522;hb=37f1ce3da5d6b4d308af26d117805fa8b357e277;hp=ce7ce2ff8f4c01cf37f5402cde8d9fa0b6aeab45;hpb=8401d6d945ec76bf96b3ebc479c70e1d5eba6870;p=cparser diff --git a/parser.c b/parser.c index ce7ce2f..7e44886 100644 --- a/parser.c +++ b/parser.c @@ -702,6 +702,7 @@ static void scope_pop(scope_t *old_scope) static entity_t *get_entity(const symbol_t *const symbol, namespace_tag_t namespc) { + assert(namespc != NAMESPACE_INVALID); entity_t *entity = symbol->entity; for (; entity != NULL; entity = entity->base.symbol_next) { if (entity->base.namespc == namespc) @@ -916,10 +917,13 @@ static bool is_null_pointer_constant(const expression_t *expression) } type_t *const type = skip_typeref(expression->base.type); - return - is_type_integer(type) && - is_constant_expression(expression) && - !fold_constant_to_bool(expression); + if (!is_type_integer(type)) + return false; + switch (is_constant_expression(expression)) { + case EXPR_CLASS_ERROR: return true; + case EXPR_CLASS_CONSTANT: return !fold_constant_to_bool(expression); + default: return false; + } } /** @@ -1079,7 +1083,7 @@ static expression_t *parse_constant_expression(void) { expression_t *result = parse_subexpression(PREC_CONDITIONAL); - if (!is_constant_expression(result)) { + if (is_constant_expression(result) == EXPR_CLASS_VARIABLE) { errorf(&result->base.source_position, "expression '%E' is not constant", result); } @@ -1732,8 +1736,9 @@ static initializer_t *initializer_from_expression(type_t *orig_type, */ static bool is_initializer_constant(const expression_t *expression) { - return is_constant_expression(expression) - || is_address_constant(expression); + return + is_constant_expression(expression) != EXPR_CLASS_VARIABLE || + is_address_constant(expression) != EXPR_CLASS_VARIABLE; } /** @@ -2506,6 +2511,7 @@ static void parse_enum_entries(type_t *const enum_type) entity_t *entity = allocate_entity_zero(ENTITY_ENUM_VALUE); entity->enum_value.enum_type = enum_type; + entity->base.namespc = NAMESPACE_NORMAL; entity->base.symbol = token.symbol; entity->base.source_position = token.source_position; next_token(); @@ -2820,6 +2826,7 @@ end_error: static entity_t *create_error_entity(symbol_t *symbol, entity_kind_tag_t kind) { entity_t *entity = allocate_entity_zero(kind); + entity->base.namespc = NAMESPACE_NORMAL; entity->base.source_position = *HERE; entity->base.symbol = symbol; if (is_declaration(entity)) { @@ -3658,12 +3665,16 @@ ptr_operator_end: ; } rem_anchor_token(')'); expect(')', end_error); + } else if (!env->may_be_abstract) { + errorf(HERE, "declarator must have a name"); + goto error_out; } break; default: if (env->may_be_abstract) break; parse_error_expected("while parsing declarator", T_IDENTIFIER, '(', NULL); +error_out: eat_until_anchor(); return NULL; } @@ -3775,24 +3786,31 @@ static type_t *construct_declarator_type(construct_type_t *construct_list, array_type->array.size_expression = size_expression; if (size_expression != NULL) { - if (is_constant_expression(size_expression)) { - long const size - = fold_constant_to_int(size_expression); - array_type->array.size = size; - array_type->array.size_constant = true; - /* §6.7.5.2:1 If the expression is a constant expression, it shall - * have a value greater than zero. */ - if (size <= 0) { - if (size < 0 || !GNU_MODE) { - errorf(&size_expression->base.source_position, - "size of array must be greater than zero"); - } else if (warning.other) { - warningf(&size_expression->base.source_position, - "zero length arrays are a GCC extension"); + switch (is_constant_expression(size_expression)) { + case EXPR_CLASS_CONSTANT: { + long const size = fold_constant_to_int(size_expression); + array_type->array.size = size; + array_type->array.size_constant = true; + /* §6.7.5.2:1 If the expression is a constant expression, it shall + * have a value greater than zero. */ + if (size <= 0) { + if (size < 0 || !GNU_MODE) { + errorf(&size_expression->base.source_position, + "size of array must be greater than zero"); + } else if (warning.other) { + warningf(&size_expression->base.source_position, + "zero length arrays are a GCC extension"); + } } + break; } - } else { - array_type->array.is_vla = true; + + case EXPR_CLASS_VARIABLE: + array_type->array.is_vla = true; + break; + + case EXPR_CLASS_ERROR: + break; } } @@ -3875,6 +3893,7 @@ static entity_t *parse_declarator(const declaration_specifiers_t *specifiers, entity_t *entity; if (specifiers->storage_class == STORAGE_CLASS_TYPEDEF) { entity = allocate_entity_zero(ENTITY_TYPEDEF); + entity->base.namespc = NAMESPACE_NORMAL; entity->base.symbol = env.symbol; entity->base.source_position = env.source_position; entity->typedefe.type = orig_type; @@ -4091,9 +4110,9 @@ static void error_redefined_as_different_kind(const source_position_t *pos, static bool is_error_entity(entity_t *const ent) { if (is_declaration(ent)) { - return is_type_valid(skip_typeref(ent->declaration.type)); + return !is_type_valid(skip_typeref(ent->declaration.type)); } else if (ent->kind == ENTITY_TYPEDEF) { - return is_type_valid(skip_typeref(ent->typedefe.type)); + return !is_type_valid(skip_typeref(ent->typedefe.type)); } return false; } @@ -4879,8 +4898,8 @@ static void check_declarations(void) static int determine_truth(expression_t const* const cond) { return - !is_constant_expression(cond) ? 0 : - fold_constant_to_bool(cond) ? 1 : + is_constant_expression(cond) != EXPR_CLASS_CONSTANT ? 0 : + fold_constant_to_bool(cond) ? 1 : -1; } @@ -5090,7 +5109,7 @@ static void check_reachable(statement_t *const stmt) if (!expression_returns(expr)) return; - if (is_constant_expression(expr)) { + if (is_constant_expression(expr) == EXPR_CLASS_CONSTANT) { long const val = fold_constant_to_int(expr); case_label_statement_t * defaults = NULL; for (case_label_statement_t *i = switchs->first_case; i != NULL; i = i->next) { @@ -5676,7 +5695,7 @@ static type_t *make_bitfield_type(type_t *base_type, expression_t *size, bit_size = get_type_size(base_type) * 8; } - if (is_constant_expression(size)) { + if (is_constant_expression(size) == EXPR_CLASS_CONSTANT) { long v = fold_constant_to_int(size); const symbol_t *user_symbol = symbol == NULL ? sym_anonymous : symbol; @@ -6215,6 +6234,7 @@ static entity_t *create_implicit_function(symbol_t *symbol, entity->declaration.declared_storage_class = STORAGE_CLASS_EXTERN; entity->declaration.type = type; entity->declaration.implicit = true; + entity->base.namespc = NAMESPACE_NORMAL; entity->base.symbol = symbol; entity->base.source_position = *source_position; @@ -7150,6 +7170,7 @@ static expression_t *parse_primary_expression(void) } errorf(HERE, "unexpected token %K, expected an expression", &token); + eat_until_anchor(); return create_invalid_expression(); } @@ -7253,12 +7274,28 @@ typeprop_expression: tp_expression->typeprop.type = orig_type; type_t const* const type = skip_typeref(orig_type); - char const* const wrong_type = - GNU_MODE && is_type_atomic(type, ATOMIC_TYPE_VOID) ? NULL : - is_type_incomplete(type) ? "incomplete" : - type->kind == TYPE_FUNCTION ? "function designator" : - type->kind == TYPE_BITFIELD ? "bitfield" : - NULL; + char const* wrong_type = NULL; + if (is_type_incomplete(type)) { + if (!is_type_atomic(type, ATOMIC_TYPE_VOID) || !GNU_MODE) + wrong_type = "incomplete"; + } else if (type->kind == TYPE_FUNCTION) { + if (GNU_MODE) { + /* function types are allowed (and return 1) */ + if (warning.other) { + char const* const what = kind == EXPR_SIZEOF ? "sizeof" : "alignof"; + warningf(&tp_expression->base.source_position, + "%s expression with function argument returns invalid result", what); + } + } else { + wrong_type = "function"; + } + } else { + if (is_type_incomplete(type)) + wrong_type = "incomplete"; + } + if (type->kind == TYPE_BITFIELD) + wrong_type = "bitfield"; + if (wrong_type != NULL) { char const* const what = kind == EXPR_SIZEOF ? "sizeof" : "alignof"; errorf(&tp_expression->base.source_position, @@ -7285,6 +7322,7 @@ static expression_t *parse_select_expression(expression_t *addr) { assert(token.type == '.' || token.type == T_MINUSGREATER); bool select_left_arrow = (token.type == T_MINUSGREATER); + source_position_t const pos = *HERE; next_token(); if (token.type != T_IDENTIFIER) { @@ -7301,7 +7339,7 @@ static expression_t *parse_select_expression(expression_t *addr) bool saw_error = false; if (is_type_pointer(type)) { if (!select_left_arrow) { - errorf(HERE, + errorf(&pos, "request for member '%Y' in something not a struct or union, but '%T'", symbol, orig_type); saw_error = true; @@ -7309,7 +7347,7 @@ static expression_t *parse_select_expression(expression_t *addr) type_left = skip_typeref(type->pointer.points_to); } else { if (select_left_arrow && is_type_valid(type)) { - errorf(HERE, "left hand side of '->' is not a pointer, but '%T'", orig_type); + errorf(&pos, "left hand side of '->' is not a pointer, but '%T'", orig_type); saw_error = true; } type_left = type; @@ -7319,7 +7357,7 @@ static expression_t *parse_select_expression(expression_t *addr) type_left->kind != TYPE_COMPOUND_UNION) { if (is_type_valid(type_left) && !saw_error) { - errorf(HERE, + errorf(&pos, "request for member '%Y' in something not a struct or union, but '%T'", symbol, type_left); } @@ -7328,17 +7366,17 @@ static expression_t *parse_select_expression(expression_t *addr) compound_t *compound = type_left->compound.compound; if (!compound->complete) { - errorf(HERE, "request for member '%Y' in incomplete type '%T'", + errorf(&pos, "request for member '%Y' in incomplete type '%T'", symbol, type_left); return create_invalid_expression(); } type_qualifiers_t qualifiers = type_left->base.qualifiers; - expression_t *result - = find_create_select(HERE, addr, qualifiers, compound, symbol); + expression_t *result = + find_create_select(&pos, addr, qualifiers, compound, symbol); if (result == NULL) { - errorf(HERE, "'%T' has no member named '%Y'", orig_type, symbol); + errorf(&pos, "'%T' has no member named '%Y'", orig_type, symbol); return create_invalid_expression(); } @@ -7411,7 +7449,7 @@ static void handle_builtin_argument_restrictions(call_expression_t *call) { /* argument must be constant */ call_argument_t *argument = call->arguments; - if (! is_constant_expression(argument->expression)) { + if (is_constant_expression(argument->expression) == EXPR_CLASS_VARIABLE) { errorf(&call->base.source_position, "argument of '%Y' must be a constant expression", call->function->reference.entity->base.symbol); @@ -7423,7 +7461,7 @@ static void handle_builtin_argument_restrictions(call_expression_t *call) { break; call_argument_t *arg = call->arguments->next; - if (arg != NULL && ! is_constant_expression(arg->expression)) { + if (arg != NULL && is_constant_expression(arg->expression) == EXPR_CLASS_VARIABLE) { errorf(&call->base.source_position, "second argument of '%Y' must be a constant expression", call->function->reference.entity->base.symbol); @@ -7437,7 +7475,7 @@ static void handle_builtin_argument_restrictions(call_expression_t *call) { call_argument_t *locality = NULL; if (rw != NULL) { - if (! is_constant_expression(rw->expression)) { + if (is_constant_expression(rw->expression) == EXPR_CLASS_VARIABLE) { errorf(&call->base.source_position, "second argument of '%Y' must be a constant expression", call->function->reference.entity->base.symbol); @@ -7445,7 +7483,7 @@ static void handle_builtin_argument_restrictions(call_expression_t *call) { locality = rw->next; } if (locality != NULL) { - if (! is_constant_expression(locality->expression)) { + if (is_constant_expression(locality->expression) == EXPR_CLASS_VARIABLE) { errorf(&call->base.source_position, "third argument of '%Y' must be a constant expression", call->function->reference.entity->base.symbol); @@ -8228,8 +8266,8 @@ static void warn_div_by_zero(binary_expression_t const *const expression) expression_t const *const right = expression->right; /* The type of the right operand can be different for /= */ - if (is_type_integer(right->base.type) && - is_constant_expression(right) && + if (is_type_integer(right->base.type) && + is_constant_expression(right) == EXPR_CLASS_CONSTANT && !fold_constant_to_bool(right)) { warningf(&expression->base.source_position, "division by zero"); } @@ -8280,7 +8318,7 @@ static bool semantic_shift(binary_expression_t *expression) type_left = promote_integer(type_left); - if (is_constant_expression(right)) { + if (is_constant_expression(right) == EXPR_CLASS_CONSTANT) { long count = fold_constant_to_int(right); if (count < 0) { warningf(&right->base.source_position, @@ -8428,9 +8466,11 @@ static void warn_comparison_in_comparison(const expression_t *const expr) static bool maybe_negative(expression_t const *const expr) { - return - !is_constant_expression(expr) || - fold_constant_to_int(expr) < 0; + switch (is_constant_expression(expr)) { + case EXPR_CLASS_ERROR: return false; + case EXPR_CLASS_CONSTANT: return fold_constant_to_int(expr) < 0; + default: return true; + } } /** @@ -9310,11 +9350,9 @@ static statement_t *parse_case_statement(void) expression_t *const expression = parse_expression(); statement->case_label.expression = expression; - if (!is_constant_expression(expression)) { - /* This check does not prevent the error message in all cases of an - * prior error while parsing the expression. At least it catches the - * common case of a mistyped enum entry. */ - if (is_type_valid(skip_typeref(expression->base.type))) { + expression_classification_t const expr_class = is_constant_expression(expression); + if (expr_class != EXPR_CLASS_CONSTANT) { + if (expr_class != EXPR_CLASS_ERROR) { errorf(pos, "case label does not reduce to an integer constant"); } statement->case_label.is_bad = true; @@ -9328,11 +9366,9 @@ static statement_t *parse_case_statement(void) if (next_if(T_DOTDOTDOT)) { expression_t *const end_range = parse_expression(); statement->case_label.end_range = end_range; - if (!is_constant_expression(end_range)) { - /* This check does not prevent the error message in all cases of an - * prior error while parsing the expression. At least it catches the - * common case of a mistyped enum entry. */ - if (is_type_valid(skip_typeref(end_range->base.type))) { + expression_classification_t const end_class = is_constant_expression(end_range); + if (end_class != EXPR_CLASS_CONSTANT) { + if (end_class != EXPR_CLASS_ERROR) { errorf(pos, "case range does not reduce to an integer constant"); } statement->case_label.is_bad = true; @@ -10099,8 +10135,9 @@ static statement_t *parse_local_label_declaration(void) eat(T___label__); - entity_t *begin = NULL, *end = NULL; - + entity_t *begin = NULL; + entity_t *end = NULL; + entity_t **anchor = &begin; do { if (token.type != T_IDENTIFIER) { parse_error_expected("while parsing local label declaration", @@ -10120,11 +10157,9 @@ static statement_t *parse_local_label_declaration(void) entity->base.source_position = token.source_position; entity->base.symbol = symbol; - if (end != NULL) - end->base.next = entity; - end = entity; - if (begin == NULL) - begin = entity; + *anchor = entity; + anchor = &entity->base.next; + end = entity; environment_push(entity); }