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;
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) {
type, struct_decl->symbol);
}
- type->base.size = new_size;
+ type->base.size = offset;
type->base.alignment = alignment;
}
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)
}
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;
}
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;
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
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);
}
{
/* 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;
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");
}
}
/* 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)
*/
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");