Remove stale (since r21011) comment.
[cparser] / parser.c
index 5f76904..fa85c3c 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -141,7 +141,7 @@ static struct obstack      temp_obst;
 
 #define PUSH_PARENT(stmt)                          \
        statement_t *const prev_parent = current_parent; \
-       current_parent = (stmt);
+       ((void)(current_parent = (stmt)))
 #define POP_PARENT ((void)(current_parent = prev_parent))
 
 static source_position_t null_position = { NULL, 0 };
@@ -356,8 +356,9 @@ static statement_t *allocate_statement_zero(statement_kind_t kind)
        size_t       size = get_statement_struct_size(kind);
        statement_t *res  = allocate_ast_zero(size);
 
-       res->base.kind   = kind;
-       res->base.parent = current_parent;
+       res->base.kind            = kind;
+       res->base.parent          = current_parent;
+       res->base.source_position = token.source_position;
        return res;
 }
 
@@ -390,9 +391,7 @@ static expression_t *create_invalid_expression(void)
  */
 static statement_t *create_invalid_statement(void)
 {
-       statement_t *statement          = allocate_statement_zero(STATEMENT_INVALID);
-       statement->base.source_position = token.source_position;
-       return statement;
+       return allocate_statement_zero(STATEMENT_INVALID);
 }
 
 /**
@@ -400,9 +399,7 @@ static statement_t *create_invalid_statement(void)
  */
 static statement_t *create_empty_statement(void)
 {
-       statement_t *statement          = allocate_statement_zero(STATEMENT_EMPTY);
-       statement->base.source_position = token.source_position;
-       return statement;
+       return allocate_statement_zero(STATEMENT_EMPTY);
 }
 
 /**
@@ -845,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);
@@ -1661,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:
@@ -1701,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;
@@ -1990,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;
@@ -2210,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);
@@ -2250,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;
                                        }
                                }
                        }
@@ -2305,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++;
@@ -2313,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
@@ -2384,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);
@@ -2467,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;
@@ -6014,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);
@@ -6846,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:
@@ -7372,13 +7381,13 @@ static expression_t *parse_conditional_expression(unsigned precedence,
                                        "pointer/integer type mismatch in conditional expression ('%T' and '%T')", true_type, false_type);
                        result_type = pointer_type;
                } else {
-                       type_error_incompatible("while parsing conditional",
-                                       &expression->base.source_position, true_type, false_type);
+                       if (is_type_valid(other_type)) {
+                               type_error_incompatible("while parsing conditional",
+                                               &expression->base.source_position, true_type, false_type);
+                       }
                        result_type = type_error_type;
                }
        } else {
-               /* TODO: one pointer to void*, other some pointer */
-
                if (is_type_valid(true_type) && is_type_valid(false_type)) {
                        type_error_incompatible("while parsing conditional",
                                                &conditional->base.source_position, true_type,
@@ -7476,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));
        }
 }
 
@@ -7646,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);
@@ -8708,13 +8720,11 @@ static asm_clobber_t *parse_asm_clobbers(void)
  */
 static statement_t *parse_asm_statement(void)
 {
-       eat(T_asm);
-
-       statement_t *statement          = allocate_statement_zero(STATEMENT_ASM);
-       statement->base.source_position = token.source_position;
-
+       statement_t     *statement     = allocate_statement_zero(STATEMENT_ASM);
        asm_statement_t *asm_statement = &statement->asms;
 
+       eat(T_asm);
+
        if (token.type == T_volatile) {
                next_token();
                asm_statement->is_volatile = true;
@@ -8769,19 +8779,18 @@ end_error:
  */
 static statement_t *parse_case_statement(void)
 {
-       eat(T_case);
-
        statement_t       *const statement = allocate_statement_zero(STATEMENT_CASE_LABEL);
        source_position_t *const pos       = &statement->base.source_position;
 
-       *pos                             = token.source_position;
+       eat(T_case);
+
        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)) {
+               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;
@@ -8800,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;
@@ -8865,10 +8874,9 @@ end_error:
  */
 static statement_t *parse_default_statement(void)
 {
-       eat(T_default);
-
        statement_t *statement = allocate_statement_zero(STATEMENT_CASE_LABEL);
-       statement->base.source_position = token.source_position;
+
+       eat(T_default);
 
        PUSH_PARENT(statement);
 
@@ -8913,14 +8921,13 @@ end_error:
 static statement_t *parse_label_statement(void)
 {
        assert(token.type == T_IDENTIFIER);
-       symbol_t *symbol = token.v.symbol;
-       next_token();
-
-       declaration_t *label = get_label(symbol);
+       symbol_t      *symbol = token.v.symbol;
+       declaration_t *label  = get_label(symbol);
 
        statement_t *const statement = allocate_statement_zero(STATEMENT_LABEL);
-       statement->base.source_position = token.source_position;
-       statement->label.label          = label;
+       statement->label.label       = label;
+
+       next_token();
 
        PUSH_PARENT(statement);
 
@@ -8976,19 +8983,23 @@ static statement_t *parse_label_statement(void)
  */
 static statement_t *parse_if(void)
 {
-       eat(T_if);
+       statement_t *statement = allocate_statement_zero(STATEMENT_IF);
 
-       statement_t *statement          = allocate_statement_zero(STATEMENT_IF);
-       statement->base.source_position = token.source_position;
+       eat(T_if);
 
        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);
@@ -9000,9 +9011,6 @@ static statement_t *parse_if(void)
 
        POP_PARENT;
        return statement;
-end_error:
-       POP_PARENT;
-       return create_invalid_statement();
 }
 
 /**
@@ -9050,10 +9058,9 @@ static void check_enum_cases(const switch_statement_t *statement) {
  */
 static statement_t *parse_switch(void)
 {
-       eat(T_switch);
+       statement_t *statement = allocate_statement_zero(STATEMENT_SWITCH);
 
-       statement_t *statement          = allocate_statement_zero(STATEMENT_SWITCH);
-       statement->base.source_position = token.source_position;
+       eat(T_switch);
 
        PUSH_PARENT(statement);
 
@@ -9114,10 +9121,9 @@ static statement_t *parse_loop_body(statement_t *const loop)
  */
 static statement_t *parse_while(void)
 {
-       eat(T_while);
+       statement_t *statement = allocate_statement_zero(STATEMENT_WHILE);
 
-       statement_t *statement          = allocate_statement_zero(STATEMENT_WHILE);
-       statement->base.source_position = token.source_position;
+       eat(T_while);
 
        PUSH_PARENT(statement);
 
@@ -9141,12 +9147,11 @@ end_error:
  */
 static statement_t *parse_do(void)
 {
-       eat(T_do);
-
        statement_t *statement = allocate_statement_zero(STATEMENT_DO_WHILE);
-       statement->base.source_position = token.source_position;
 
-       PUSH_PARENT(statement)
+       eat(T_do);
+
+       PUSH_PARENT(statement);
 
        add_anchor_token(T_while);
        statement->do_while.body = parse_loop_body(statement);
@@ -9172,10 +9177,9 @@ end_error:
  */
 static statement_t *parse_for(void)
 {
-       eat(T_for);
+       statement_t *statement = allocate_statement_zero(STATEMENT_FOR);
 
-       statement_t *statement          = allocate_statement_zero(STATEMENT_FOR);
-       statement->base.source_position = token.source_position;
+       eat(T_for);
 
        PUSH_PARENT(statement);
 
@@ -9243,10 +9247,9 @@ end_error:
  */
 static statement_t *parse_goto(void)
 {
-       source_position_t source_position = token.source_position;
+       statement_t *statement = allocate_statement_zero(STATEMENT_GOTO);
        eat(T_goto);
 
-       statement_t *statement;
        if (GNU_MODE && token.type == '*') {
                next_token();
                expression_t *expression = parse_expression();
@@ -9257,17 +9260,16 @@ static statement_t *parse_goto(void)
 
                if (type != type_error_type) {
                        if (!is_type_pointer(type) && !is_type_integer(type)) {
-                               errorf(&source_position, "cannot convert to a pointer type");
+                               errorf(&expression->base.source_position,
+                                       "cannot convert to a pointer type");
                        } else if (type != type_void_ptr) {
-                               warningf(&source_position,
+                               warningf(&expression->base.source_position,
                                        "type of computed goto expression should be 'void*' not '%T'", type);
                        }
                        expression = create_implicit_cast(expression, type_void_ptr);
                }
 
-               statement                       = allocate_statement_zero(STATEMENT_GOTO);
-               statement->base.source_position = source_position;
-               statement->gotos.expression     = expression;
+               statement->gotos.expression = expression;
        } else {
                if (token.type != T_IDENTIFIER) {
                        if (GNU_MODE)
@@ -9280,9 +9282,7 @@ static statement_t *parse_goto(void)
                symbol_t *symbol = token.v.symbol;
                next_token();
 
-               statement                       = allocate_statement_zero(STATEMENT_GOTO);
-               statement->base.source_position = source_position;
-               statement->gotos.label          = get_label(symbol);
+               statement->gotos.label = get_label(symbol);
 
                if (statement->gotos.label->parent_scope->depth < current_function->scope.depth) {
                        statement->gotos.outer_fkt_jmp = true;
@@ -9314,7 +9314,6 @@ static statement_t *parse_continue(void)
        }
 
        statement_t *statement = allocate_statement_zero(STATEMENT_CONTINUE);
-       statement->base.source_position = token.source_position;
 
        eat(T_continue);
        expect(';');
@@ -9333,7 +9332,6 @@ static statement_t *parse_break(void)
        }
 
        statement_t *statement = allocate_statement_zero(STATEMENT_BREAK);
-       statement->base.source_position = token.source_position;
 
        eat(T_break);
        expect(';');
@@ -9352,7 +9350,6 @@ static statement_t *parse_leave_statement(void)
        }
 
        statement_t *statement = allocate_statement_zero(STATEMENT_LEAVE);
-       statement->base.source_position = token.source_position;
 
        eat(T___leave);
        expect(';');
@@ -9425,11 +9422,10 @@ declaration_t *expr_is_variable(const expression_t *expression)
  */
 static statement_t *parse_return(void)
 {
-       statement_t *statement          = allocate_statement_zero(STATEMENT_RETURN);
-       statement->base.source_position = token.source_position;
-
        eat(T_return);
 
+       statement_t *statement = allocate_statement_zero(STATEMENT_RETURN);
+
        expression_t *return_value = NULL;
        if (token.type != ';') {
                return_value = parse_expression();
@@ -9483,8 +9479,6 @@ static statement_t *parse_declaration_statement(void)
 {
        statement_t *statement = allocate_statement_zero(STATEMENT_DECLARATION);
 
-       statement->base.source_position = token.source_position;
-
        declaration_t *before = last_declaration;
        if (GNU_MODE)
                parse_external_declaration();
@@ -9508,7 +9502,6 @@ static statement_t *parse_expression_statement(void)
 {
        statement_t *statement = allocate_statement_zero(STATEMENT_EXPRESSION);
 
-       statement->base.source_position  = token.source_position;
        expression_t *const expr         = parse_expression();
        statement->expression.expression = expr;
 
@@ -9525,7 +9518,6 @@ end_error:
 static statement_t *parse_ms_try_statment(void)
 {
        statement_t *statement = allocate_statement_zero(STATEMENT_MS_TRY);
-       statement->base.source_position  = token.source_position;
        eat(T___try);
 
        PUSH_PARENT(statement);
@@ -9578,7 +9570,6 @@ static statement_t *parse_empty_statement(void)
 
 static statement_t *parse_local_label_declaration(void) {
        statement_t *statement = allocate_statement_zero(STATEMENT_DECLARATION);
-       statement->base.source_position = token.source_position;
 
        eat(T___label__);
 
@@ -9729,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:
@@ -9785,7 +9779,6 @@ static statement_t *parse_statement(void)
 static statement_t *parse_compound_statement(bool inside_expression_statement)
 {
        statement_t *statement = allocate_statement_zero(STATEMENT_COMPOUND);
-       statement->base.source_position = token.source_position;
 
        PUSH_PARENT(statement);
 
@@ -9923,14 +9916,14 @@ static void check_unused_globals(void)
 
 static void parse_global_asm(void)
 {
+       statement_t *statement = allocate_statement_zero(STATEMENT_ASM);
+
        eat(T_asm);
        expect('(');
 
-       statement_t *statement          = allocate_statement_zero(STATEMENT_ASM);
-       statement->base.source_position = token.source_position;
-       statement->asms.asm_text        = parse_string_literals();
-       statement->base.next            = unit->global_asm;
-       unit->global_asm                = statement;
+       statement->asms.asm_text = parse_string_literals();
+       statement->base.next     = unit->global_asm;
+       unit->global_asm         = statement;
 
        expect(')');
        expect(';');