X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=497ecd634e8fd5e20c49bf69e2ddcf8166b2a9fb;hb=9e9141455d9e7a9028d7ffa1d5656b1e9bb25c74;hp=a167ab363594c3d3af790d2bf67bd8a55b89f726;hpb=0a863bf803aca3f74d1f000bf799e3944ef6a87a;p=cparser diff --git a/parser.c b/parser.c index a167ab3..497ecd6 100644 --- a/parser.c +++ b/parser.c @@ -842,10 +842,14 @@ static void stack_pop_to(stack_entry_t **stack_ptr, size_t new_top) break; } - /* Because of scopes and appending other namespaces to the end of - * the list, this must hold. */ - assert((old_declaration != NULL ? old_declaration->symbol_next : NULL) == iter->symbol_next); - *anchor = old_declaration; + /* Not all declarations adhere scopes (e.g. jump labels), so this + * correction is necessary */ + if (old_declaration != NULL) { + old_declaration->symbol_next = iter->symbol_next; + *anchor = old_declaration; + } else { + *anchor = iter->symbol_next; + } } ARR_SHRINKLEN(*stack_ptr, (int) new_top); @@ -1658,7 +1662,6 @@ static decl_modifiers_t parse_gnu_attribute(gnu_attribute_t **attributes) } switch(kind) { - case GNU_AK_CONST: case GNU_AK_VOLATILE: case GNU_AK_NAKED: case GNU_AK_MALLOC: @@ -1698,6 +1701,7 @@ static decl_modifiers_t parse_gnu_attribute(gnu_attribute_t **attributes) case GNU_AK_UNUSED: modifiers |= DM_UNUSED; goto no_arg; case GNU_AK_USED: modifiers |= DM_USED; goto no_arg; case GNU_AK_PURE: modifiers |= DM_PURE; goto no_arg; + case GNU_AK_CONST: modifiers |= DM_CONST; goto no_arg; case GNU_AK_ALWAYS_INLINE: modifiers |= DM_FORCEINLINE; goto no_arg; case GNU_AK_DLLIMPORT: modifiers |= DM_DLLIMPORT; goto no_arg; case GNU_AK_DLLEXPORT: modifiers |= DM_DLLEXPORT; goto no_arg; @@ -1987,6 +1991,11 @@ static initializer_t *initializer_from_expression(type_t *orig_type, &expression->base.source_position); initializer_t *const result = allocate_initializer_zero(INITIALIZER_VALUE); +#if 0 + if (type->kind == TYPE_BITFIELD) { + type = type->bitfield.base_type; + } +#endif result->value.value = create_implicit_cast(expression, type); return result; @@ -2207,34 +2216,37 @@ static bool walk_designator(type_path_t *path, const designator_t *designator, "'.%Y' designator used for non-compound type '%T'", symbol, orig_type); } - goto failed; - } - declaration_t *declaration = type->compound.declaration; - declaration_t *iter = declaration->scope.declarations; - for( ; iter != NULL; iter = iter->next) { - if (iter->symbol == symbol) { - break; + top->type = type_error_type; + top->v.compound_entry = NULL; + orig_type = type_error_type; + } else { + declaration_t *declaration = type->compound.declaration; + declaration_t *iter = declaration->scope.declarations; + for( ; iter != NULL; iter = iter->next) { + if (iter->symbol == symbol) { + break; + } } - } - if (iter == NULL) { - errorf(&designator->source_position, - "'%T' has no member named '%Y'", orig_type, symbol); - goto failed; - } - if (used_in_offsetof) { - type_t *real_type = skip_typeref(iter->type); - if (real_type->kind == TYPE_BITFIELD) { + if (iter == NULL) { errorf(&designator->source_position, - "offsetof designator '%Y' may not specify bitfield", - symbol); + "'%T' has no member named '%Y'", orig_type, symbol); goto failed; } - } + if (used_in_offsetof) { + type_t *real_type = skip_typeref(iter->type); + if (real_type->kind == TYPE_BITFIELD) { + errorf(&designator->source_position, + "offsetof designator '%Y' may not specify bitfield", + symbol); + goto failed; + } + } - top->type = orig_type; - top->v.compound_entry = iter; - orig_type = iter->type; + top->type = orig_type; + top->v.compound_entry = iter; + orig_type = iter->type; + } } else { expression_t *array_index = designator->array_index; assert(designator->array_index != NULL); @@ -2247,24 +2259,18 @@ static bool walk_designator(type_path_t *path, const designator_t *designator, } goto failed; } - if (!is_type_valid(array_index->base.type)) { - goto failed; - } long index = fold_constant(array_index); if (!used_in_offsetof) { if (index < 0) { errorf(&designator->source_position, "array index [%E] must be positive", array_index); - goto failed; - } - if (type->array.size_constant == true) { + } else if (type->array.size_constant) { long array_size = type->array.size; if (index >= array_size) { errorf(&designator->source_position, "designator [%E] (%d) exceeds array size %d", array_index, index, array_size); - goto failed; } } } @@ -2302,7 +2308,7 @@ static void advance_current_object(type_path_t *path, size_t top_path_level) path->top_type = entry->type; return; } - } else { + } else if (is_type_array(type)) { assert(is_type_array(type)); top->v.index++; @@ -2310,6 +2316,9 @@ static void advance_current_object(type_path_t *path, size_t top_path_level) if (!type->array.size_constant || top->v.index < type->array.size) { return; } + } else { + assert(!is_type_valid(type)); + return; } /* we're past the last member of the current sub-aggregate, try if we @@ -2381,13 +2390,6 @@ static initializer_t *parse_sub_initializer(type_path_t *path, /* We are initializing an empty compound. */ } else { type = skip_typeref(orig_type); - - /* we can't do usefull stuff if we didn't even parse the type. Skip the - * initializers in this case. */ - if (!is_type_valid(type)) { - skip_initializers(); - return create_empty_initializer(); - } } initializer_t **initializers = NEW_ARR_F(initializer_t*, 0); @@ -2464,8 +2466,9 @@ finish_designator: if (type == NULL) { /* we are already outside, ... */ - if (is_type_compound(outer_type) && - !outer_type->compound.declaration->init.complete) { + type_t *const outer_type_skip = skip_typeref(outer_type); + if (is_type_compound(outer_type_skip) && + !outer_type_skip->compound.declaration->init.complete) { goto error_parse_next; } goto error_excess; @@ -6011,11 +6014,17 @@ static type_t *get_builtin_symbol_type(symbol_t *symbol) return make_function_1_type(type_void_ptr, type_size_t); case T___builtin_huge_val: return make_function_0_type(type_double); + case T___builtin_inf: + return make_function_0_type(type_double); + case T___builtin_inff: + return make_function_0_type(type_float); + case T___builtin_infl: + return make_function_0_type(type_long_double); case T___builtin_nan: return make_function_1_type(type_double, type_char_ptr); case T___builtin_nanf: return make_function_1_type(type_float, type_char_ptr); - case T___builtin_nand: + case T___builtin_nanl: return make_function_1_type(type_long_double, type_char_ptr); case T___builtin_va_end: return make_function_1_type(type_void, type_valist); @@ -6843,9 +6852,12 @@ static expression_t *parse_primary_expression(void) case T___builtin_va_arg: return parse_va_arg(); case T___builtin_expect: case T___builtin_alloca: + case T___builtin_inf: + case T___builtin_inff: + case T___builtin_infl: case T___builtin_nan: - case T___builtin_nand: case T___builtin_nanf: + case T___builtin_nanl: case T___builtin_huge_val: case T___builtin_va_end: return parse_builtin_symbol(); case T___builtin_isgreater: @@ -7473,7 +7485,10 @@ static bool is_lvalue(const expression_t *expression) return true; default: - return false; + /* Claim it is an lvalue, if the type is invalid. There was a parse + * error before, which maybe prevented properly recognizing it as + * lvalue. */ + return !is_type_valid(skip_typeref(expression->base.type)); } } @@ -7643,7 +7658,7 @@ static void semantic_take_addr(unary_expression_t *expression) value->base.type = revert_automatic_type_conversion(value); type_t *orig_type = value->base.type; - if (!is_type_valid(orig_type)) + if (!is_type_valid(skip_typeref(orig_type))) return; set_address_taken(value, false); @@ -8775,7 +8790,7 @@ static statement_t *parse_case_statement(void) /* 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)) { + if (is_type_valid(skip_typeref(expression->base.type))) { errorf(pos, "case label does not reduce to an integer constant"); } statement->case_label.is_bad = true; @@ -8794,7 +8809,7 @@ static statement_t *parse_case_statement(void) /* 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)) { + if (is_type_valid(skip_typeref(end_range->base.type))) { errorf(pos, "case range does not reduce to an integer constant"); } statement->case_label.is_bad = true; @@ -8974,12 +8989,17 @@ static statement_t *parse_if(void) PUSH_PARENT(statement); + add_anchor_token('{'); + expect('('); add_anchor_token(')'); statement->ifs.condition = parse_expression(); rem_anchor_token(')'); expect(')'); +end_error: + rem_anchor_token('{'); + add_anchor_token(T_else); statement->ifs.true_statement = parse_statement(); rem_anchor_token(T_else); @@ -8991,9 +9011,6 @@ static statement_t *parse_if(void) POP_PARENT; return statement; -end_error: - POP_PARENT; - return create_invalid_statement(); } /** @@ -9703,9 +9720,12 @@ expression_statment: case T___builtin_islessequal: case T___builtin_islessgreater: case T___builtin_isunordered: + case T___builtin_inf: + case T___builtin_inff: + case T___builtin_infl: case T___builtin_nan: - case T___builtin_nand: case T___builtin_nanf: + case T___builtin_nanl: case T___builtin_offsetof: case T___builtin_prefetch: case T___builtin_va_arg: