X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=1502d2ed4242732a62b3fcc7794ddde4318de69f;hb=4ccdad496797f05c13ddb2723c52e42eb9023496;hp=d25c44fb8ba770d2a54d31dd7f5b8cc299231802;hpb=0f15057a5b66c97d32658bb937abcc7e8ee22932;p=cparser diff --git a/parser.c b/parser.c index d25c44f..1502d2e 100644 --- a/parser.c +++ b/parser.c @@ -1030,7 +1030,7 @@ static void report_assign_error(assign_error_t error, type_t *orig_type_left, case ASSIGN_WARNING_POINTER_FROM_INT: warningf(source_position, - "%s makes integer '%T' from pointer '%T' without a cast", + "%s makes pointer '%T' from integer '%T' without a cast", context, orig_type_left, orig_type_right); return; @@ -2148,8 +2148,6 @@ static void descend_into_subtype(type_path_t *path) type_t *orig_top_type = path->top_type; type_t *top_type = skip_typeref(orig_top_type); - assert(is_type_compound(top_type) || is_type_array(top_type)); - type_path_entry_t *top = append_to_type_path(path); top->type = top_type; @@ -2163,11 +2161,11 @@ static void descend_into_subtype(type_path_t *path) } else { path->top_type = NULL; } - } else { - assert(is_type_array(top_type)); - + } else if (is_type_array(top_type)) { top->v.index = 0; path->top_type = top_type->array.element_type; + } else { + assert(!is_type_valid(top_type)); } } @@ -4032,8 +4030,10 @@ static construct_type_t *parse_inner_declarator(declaration_t *declaration, next_token(); add_anchor_token(')'); inner_types = parse_inner_declarator(declaration, may_be_abstract); - /* All later declarators only modify the return type, not declaration */ - declaration = NULL; + if (inner_types != NULL) { + /* All later declarators only modify the return type, not declaration */ + declaration = NULL; + } rem_anchor_token(')'); expect(')'); break; @@ -4450,8 +4450,9 @@ static declaration_t *record_declaration( if (old_storage_class == STORAGE_CLASS_EXTERN && new_storage_class == STORAGE_CLASS_EXTERN) { warn_redundant_declaration: - if (!is_definition && - warning.redundant_decls && + if (!is_definition && + warning.redundant_decls && + is_type_valid(prev_type) && strcmp(previous_declaration->source_position.input_name, "") != 0) { warningf(&declaration->source_position, "redundant declaration for '%Y' (declared %P)", @@ -4469,14 +4470,16 @@ warn_redundant_declaration: } else { goto warn_redundant_declaration; } - } else if (old_storage_class == new_storage_class) { - errorf(&declaration->source_position, - "redeclaration of '%Y' (declared %P)", - symbol, &previous_declaration->source_position); - } else { - errorf(&declaration->source_position, - "redeclaration of '%Y' with different linkage (declared %P)", - symbol, &previous_declaration->source_position); + } else if (is_type_valid(prev_type)) { + if (old_storage_class == new_storage_class) { + errorf(&declaration->source_position, + "redeclaration of '%Y' (declared %P)", + symbol, &previous_declaration->source_position); + } else { + errorf(&declaration->source_position, + "redeclaration of '%Y' with different linkage (declared %P)", + symbol, &previous_declaration->source_position); + } } } @@ -6046,11 +6049,8 @@ static expression_t *parse_reference(void) declaration_t *declaration = get_declaration(symbol, NAMESPACE_NORMAL); - source_position_t source_position = token.source_position; - next_token(); - if (declaration == NULL) { - if (token.type == '(') { + if (look_ahead(1)->type == '(') { /* an implicitly declared function */ if (strict_mode) { errorf(HERE, "unknown symbol '%Y' found.", symbol); @@ -6059,8 +6059,7 @@ static expression_t *parse_reference(void) symbol); } - declaration = create_implicit_function(symbol, - &source_position); + declaration = create_implicit_function(symbol, HERE); } else { errorf(HERE, "unknown symbol '%Y' found.", symbol); declaration = create_error_declaration(symbol, STORAGE_CLASS_NONE); @@ -6086,23 +6085,21 @@ static expression_t *parse_reference(void) "function" : "variable"; if (declaration->deprecated_string != NULL) { - warningf(&source_position, - "%s '%Y' is deprecated (declared %P): \"%s\"", prefix, - declaration->symbol, &declaration->source_position, + warningf(HERE, "%s '%Y' is deprecated (declared %P): \"%s\"", + prefix, declaration->symbol, &declaration->source_position, declaration->deprecated_string); } else { - warningf(&source_position, - "%s '%Y' is deprecated (declared %P)", prefix, + warningf(HERE, "%s '%Y' is deprecated (declared %P)", prefix, declaration->symbol, &declaration->source_position); } } if (warning.init_self && declaration == current_init_decl) { current_init_decl = NULL; - warningf(&source_position, - "variable '%#T' is initialized by itself", + warningf(HERE, "variable '%#T' is initialized by itself", declaration->type, declaration->symbol); } + next_token(); return expression; } @@ -6858,19 +6855,18 @@ static expression_t *parse_array_expression(unsigned precedence, orig_type_left, orig_type_inside); } return_type = type_error_type; - array_access->array_ref = create_invalid_expression(); + array_access->array_ref = left; + array_access->index = inside; } + expression->base.type = automatic_type_conversion(return_type); + rem_anchor_token(']'); - if (token.type != ']') { + if (token.type == ']') { + next_token(); + } else { parse_error_expected("Problem while parsing array access", ']', NULL); - return expression; } - next_token(); - - return_type = automatic_type_conversion(return_type); - expression->base.type = return_type; - return expression; } @@ -6990,7 +6986,7 @@ static expression_t *parse_select_expression(unsigned precedence, if (!declaration->init.complete) { errorf(HERE, "request for member '%Y' of incomplete type '%T'", symbol, type_left); - return create_invalid_expression(); + goto create_error_entry; } entry = find_compound_entry(declaration, symbol); @@ -7072,26 +7068,15 @@ static void check_call_argument(const function_parameter_t *parameter, snprintf(buf, sizeof(buf), "call argument %u", pos); report_assign_error(error, expected_type, arg_expr, buf, &arg_expr->base.source_position); - } else if (warning.traditional | warning.conversion) { - if ( - /* passing as integer instead of float or complex */ - (is_type_integer(expected_type) && - (is_type_float(arg_type) || is_type_complex(arg_type))) || - /* passing as complex instead of integer or float */ - (is_type_complex(expected_type) && - (is_type_integer(arg_type) || is_type_float(arg_type))) || - /* passing as float instead of integer or complex */ - (is_type_float(expected_type) && - (is_type_integer(arg_type) || is_type_complex(arg_type))) || - /* passing as float instead of double */ - (is_type_float(expected_type) && expected_type != type_double && - is_type_float(arg_type))) { + } else if (warning.traditional || warning.conversion) { + type_t *const promoted_type = get_default_promoted_type(arg_type); + if (!types_compatible(expected_type_skip, promoted_type) && + !types_compatible(expected_type_skip, type_void_ptr) && + !types_compatible(type_void_ptr, promoted_type)) { + /* Deliberately show the skipped types in this warning */ warningf(&arg_expr->base.source_position, "passing call argument %u as '%T' rather than '%T' due to prototype", - pos, expected_type, arg_type); - } - if (is_type_integer(expected_type) && is_type_integer(arg_type)) { - /* TODO check for size HERE */ + pos, expected_type_skip, promoted_type); } } } @@ -7612,6 +7597,9 @@ static type_t *semantic_arithmetic(type_t *type_left, type_t *type_right) { /* TODO: handle complex + imaginary types */ + type_left = get_unqualified_type(type_left); + type_right = get_unqualified_type(type_right); + /* § 6.3.1.8 Usual arithmetic conversions */ if (type_left == type_long_double || type_right == type_long_double) { return type_long_double; @@ -7698,10 +7686,15 @@ static void semantic_binexpr_arithmetic(binary_expression_t *expression) static void warn_div_by_zero(binary_expression_t const *const expression) { - if (warning.div_by_zero && - is_type_integer(expression->base.type) && - is_constant_expression(expression->right) && - fold_constant(expression->right) == 0) { + if (!warning.div_by_zero || + !is_type_integer(expression->base.type)) + return; + + 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) && + fold_constant(right) == 0) { warningf(&expression->base.source_position, "division by zero"); } } @@ -8627,12 +8620,18 @@ static statement_t *parse_case_statement(void) source_position_t *const pos = &statement->base.source_position; *pos = token.source_position; - statement->case_label.expression = parse_expression(); - if (! is_constant_expression(statement->case_label.expression)) { - errorf(pos, "case label does not reduce to an integer constant"); + 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(expression->base.type)) { + errorf(pos, "case label does not reduce to an integer constant"); + } statement->case_label.is_bad = true; } else { - long const val = fold_constant(statement->case_label.expression); + long const val = fold_constant(expression); statement->case_label.first_case = val; statement->case_label.last_case = val; } @@ -8640,12 +8639,18 @@ static statement_t *parse_case_statement(void) if (c_mode & _GNUC) { if (token.type == T_DOTDOTDOT) { next_token(); - statement->case_label.end_range = parse_expression(); - if (! is_constant_expression(statement->case_label.end_range)) { - errorf(pos, "case range does not reduce to an integer constant"); + 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(end_range->base.type)) { + errorf(pos, "case range does not reduce to an integer constant"); + } statement->case_label.is_bad = true; } else { - long const val = fold_constant(statement->case_label.end_range); + long const val = fold_constant(end_range); statement->case_label.last_case = val; if (val < statement->case_label.first_case) { @@ -9477,13 +9482,18 @@ static statement_t *intern_parse_statement(void) } else if (is_typedef_symbol(token.v.symbol)) { statement = parse_declaration_statement(); } else switch (la1_type) { + case '*': + if (get_declaration(token.v.symbol, NAMESPACE_NORMAL) != NULL) + goto expression_statment; + /* FALLTHROUGH */ + DECLARATION_START case T_IDENTIFIER: - case '*': statement = parse_declaration_statement(); break; default: +expression_statment: statement = parse_expression_statement(); break; }