Print \n after $invalid statement$.
[cparser] / parser.c
index 609ef8d..1ccaffa 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -134,6 +134,9 @@ static struct obstack      temp_obst;
 
 static source_position_t null_position = { NULL, 0 };
 
+/** special symbol used for anonymous entities. */
+static const symbol_t *sym_anonymous = NULL;
+
 /* symbols for Microsoft extended-decl-modifier */
 static const symbol_t *sym_align      = NULL;
 static const symbol_t *sym_allocate   = NULL;
@@ -1030,7 +1033,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;
 
@@ -3129,33 +3132,38 @@ static void finish_struct_type(compound_type_t *type) {
        if (! struct_decl->init.complete)
                return;
 
-       il_size_t      size      = 0;
-       il_size_t      new_size;
-       il_alignment_t alignment = 1;
-       bool           need_pad  = false;
+       il_size_t      size           = 0;
+       il_size_t      offset;
+       il_alignment_t alignment      = 1;
+       bool           need_pad       = false;
 
        declaration_t *entry = struct_decl->scope.declarations;
        for (; entry != NULL; entry = entry->next) {
                if (entry->namespc != NAMESPACE_NORMAL)
                        continue;
 
-               type_t         *m_type      = skip_typeref(entry->type);
-               il_alignment_t  m_alignment = m_type->base.alignment;
-
-               new_size = (size + m_alignment - 1) & -m_alignment;
+               type_t *m_type = skip_typeref(entry->type);
+               if (! is_type_valid(m_type)) {
+                       /* simply ignore errors here */
+                       continue;
+               }
+               il_alignment_t m_alignment = m_type->base.alignment;
                if (m_alignment > alignment)
                        alignment = m_alignment;
-               if (new_size > size)
+
+               offset = (size + m_alignment - 1) & -m_alignment;
+
+               if (offset > size)
                        need_pad = true;
-               entry->offset = new_size;
-               size = new_size + m_type->base.size;
+               entry->offset = offset;
+               size = offset + m_type->base.size;
        }
        if (type->base.alignment != 0) {
                alignment = type->base.alignment;
        }
 
-       new_size = (size + alignment - 1) & -alignment;
-       if (new_size > size)
+       offset = (size + alignment - 1) & -alignment;
+       if (offset > size)
                need_pad = true;
 
        if (warning.padded && need_pad) {
@@ -3168,7 +3176,7 @@ static void finish_struct_type(compound_type_t *type) {
                        type, struct_decl->symbol);
        }
 
-       type->base.size      = new_size;
+       type->base.size      = offset;
        type->base.alignment = alignment;
 }
 
@@ -3192,6 +3200,8 @@ static void finish_union_type(compound_type_t *type) {
                        continue;
 
                type_t *m_type = skip_typeref(entry->type);
+               if (! is_type_valid(m_type))
+                       continue;
 
                entry->offset = 0;
                if (m_type->base.size > size)
@@ -5511,12 +5521,40 @@ static void parse_external_declaration(void)
 }
 
 static type_t *make_bitfield_type(type_t *base_type, expression_t *size,
-                                  source_position_t *source_position)
+                                  source_position_t *source_position,
+                                  const symbol_t *symbol)
 {
        type_t *type = allocate_type_zero(TYPE_BITFIELD, source_position);
 
-       type->bitfield.base_type = base_type;
-       type->bitfield.size      = size;
+       type->bitfield.base_type       = base_type;
+       type->bitfield.size_expression = size;
+
+       il_size_t bit_size;
+       type_t *skipped_type = skip_typeref(base_type);
+       if (!is_type_integer(skipped_type)) {
+               errorf(HERE, "bitfield base type '%T' is not an integer type",
+                       base_type);
+               bit_size = 0;
+       } else {
+               bit_size = skipped_type->base.size * 8;
+       }
+
+       if (is_constant_expression(size)) {
+               long v = fold_constant(size);
+
+               if (v < 0) {
+                       errorf(source_position, "negative width in bit-field '%Y'",
+                               symbol);
+               } else if (v == 0) {
+                       errorf(source_position, "zero width for bit-field '%Y'",
+                               symbol);
+               } else if (bit_size > 0 && (il_size_t)v > bit_size) {
+                       errorf(source_position, "width of '%Y' exceeds its type",
+                               symbol);
+               } else {
+                       type->bitfield.bit_size = v;
+               }
+       }
 
        return type;
 }
@@ -5568,12 +5606,8 @@ static void parse_compound_declarators(declaration_t *struct_declaration,
                        type_t *base_type = specifiers->type;
                        expression_t *size = parse_constant_expression();
 
-                       if (!is_type_integer(skip_typeref(base_type))) {
-                               errorf(HERE, "bitfield base type '%T' is not an integer type",
-                                      base_type);
-                       }
-
-                       type_t *type = make_bitfield_type(base_type, size, &source_position);
+                       type_t *type = make_bitfield_type(base_type, size,
+                                       &source_position, sym_anonymous);
 
                        declaration                         = allocate_declaration_zero();
                        declaration->namespc                = NAMESPACE_NORMAL;
@@ -5593,12 +5627,8 @@ static void parse_compound_declarators(declaration_t *struct_declaration,
                                next_token();
                                expression_t *size = parse_constant_expression();
 
-                               if (!is_type_integer(type)) {
-                                       errorf(HERE, "bitfield base type '%T' is not an integer type",
-                                              orig_type);
-                               }
-
-                               type_t *bitfield_type = make_bitfield_type(orig_type, size, &source_position);
+                               type_t *bitfield_type = make_bitfield_type(orig_type, size,
+                                               &source_position, declaration->symbol);
                                declaration->type = bitfield_type;
                        } else {
                                /* TODO we ignore arrays for now... what is missing is a check
@@ -6050,11 +6080,9 @@ static expression_t *parse_reference(void)
        declaration_t *declaration = get_declaration(symbol, NAMESPACE_NORMAL);
 
        if (declaration == NULL) {
-               if (look_ahead(1)->type == '(') {
+               if (!strict_mode && look_ahead(1)->type == '(') {
                        /* an implicitly declared function */
-                       if (strict_mode) {
-                               errorf(HERE, "unknown symbol '%Y' found.", symbol);
-                       } else if (warning.implicit_function_declaration) {
+                       if (warning.implicit_function_declaration) {
                                warningf(HERE, "implicit declaration of function '%Y'",
                                        symbol);
                        }
@@ -6855,19 +6883,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;
 }
 
@@ -7069,26 +7096,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);
                }
        }
 }
@@ -7609,6 +7625,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;
@@ -7695,10 +7714,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");
        }
 }
@@ -8658,7 +8682,7 @@ static statement_t *parse_case_statement(void)
                                statement->case_label.last_case = val;
 
                                if (val < statement->case_label.first_case) {
-                                       statement->case_label.is_empty = true;
+                                       statement->case_label.is_empty_range = true;
                                        warningf(pos, "empty range specified");
                                }
                        }
@@ -8674,7 +8698,7 @@ static statement_t *parse_case_statement(void)
                        /* Check for duplicate case values */
                        case_label_statement_t *c = &statement->case_label;
                        for (case_label_statement_t *l = current_switch->first_case; l != NULL; l = l->next) {
-                               if (l->is_bad || l->is_empty || l->expression == NULL)
+                               if (l->is_bad || l->is_empty_range || l->expression == NULL)
                                        continue;
 
                                if (c->last_case < l->first_case || c->first_case > l->last_case)
@@ -9486,13 +9510,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;
                }
@@ -9820,6 +9849,8 @@ void parse(void)
  */
 void init_parser(void)
 {
+       sym_anonymous = symbol_table_insert("<anonymous>");
+
        if (c_mode & _MS) {
                /* add predefined symbols for extended-decl-modifier */
                sym_align      = symbol_table_insert("align");