Remove stale (since r21011) comment.
[cparser] / parser.c
index a167ab3..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 };
@@ -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:
@@ -7369,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,
@@ -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();
 }
 
 /**
@@ -9134,7 +9151,7 @@ static statement_t *parse_do(void)
 
        eat(T_do);
 
-       PUSH_PARENT(statement)
+       PUSH_PARENT(statement);
 
        add_anchor_token(T_while);
        statement->do_while.body = parse_loop_body(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: