- allow '-' for s and S format
[cparser] / parser.c
index 6c8e3a3..497ecd6 100644 (file)
--- 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);
@@ -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;
@@ -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);
@@ -8778,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;
@@ -8797,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;
@@ -8977,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);
@@ -8994,9 +9011,6 @@ static statement_t *parse_if(void)
 
        POP_PARENT;
        return statement;
-end_error:
-       POP_PARENT;
-       return create_invalid_statement();
 }
 
 /**