bitfield is a complete type
[cparser] / parser.c
index 3ca86ca..8977956 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -132,7 +132,7 @@ static const symbol_t *sym_noalias    = NULL;
 static unsigned char token_anchor_set[T_LAST_TOKEN];
 
 /** The current source position. */
-#define HERE &token.source_position
+#define HERE (&token.source_position)
 
 static type_t *type_valist;
 
@@ -3976,18 +3976,18 @@ static void parser_error_multiple_definition(declaration_t *declaration,
 }
 
 static bool is_declaration_specifier(const token_t *token,
-                                     bool only_type_specifiers)
+                                     bool only_specifiers_qualifiers)
 {
        switch(token->type) {
                TYPE_SPECIFIERS
+               TYPE_QUALIFIERS
                        return true;
                case T_IDENTIFIER:
                        return is_typedef_symbol(token->v.symbol);
 
                case T___extension__:
                STORAGE_CLASSES
-               TYPE_QUALIFIERS
-                       return !only_type_specifiers;
+                       return !only_specifiers_qualifiers;
 
                default:
                        return false;
@@ -4782,18 +4782,11 @@ static declaration_t *create_implicit_function(symbol_t *symbol,
        declaration->type                   = type;
        declaration->symbol                 = symbol;
        declaration->source_position        = *source_position;
-       declaration->parent_scope           = global_scope;
 
-       scope_t *old_scope = scope;
-       set_scope(global_scope);
-
-       environment_push(declaration);
-       /* prepends the declaration to the global declarations list */
-       declaration->next   = scope->declarations;
-       scope->declarations = declaration;
-
-       assert(scope == global_scope);
-       set_scope(old_scope);
+       bool strict_prototypes_old = warning.strict_prototypes;
+       warning.strict_prototypes  = false;
+       record_declaration(declaration);
+       warning.strict_prototypes = strict_prototypes_old;
 
        return declaration;
 }
@@ -5645,20 +5638,47 @@ static expression_t *parse_array_expression(unsigned precedence,
        return expression;
 }
 
-static expression_t *parse_typeprop(expression_kind_t kind, unsigned precedence)
+static expression_t *parse_typeprop(expression_kind_t const kind,
+                                    source_position_t const pos,
+                                    unsigned const precedence)
 {
        expression_t *tp_expression = allocate_expression_zero(kind);
-       tp_expression->base.type    = type_size_t;
+       tp_expression->base.type            = type_size_t;
+       tp_expression->base.source_position = pos;
+
+       char const* const what = kind == EXPR_SIZEOF ? "sizeof" : "alignof";
 
-       if(token.type == '(' && is_declaration_specifier(look_ahead(1), true)) {
+       if (token.type == '(' && is_declaration_specifier(look_ahead(1), true)) {
                next_token();
                add_anchor_token(')');
-               tp_expression->typeprop.type = parse_typename();
+               type_t* const type = parse_typename();
+               tp_expression->typeprop.type = type;
+
+               char const* const wrong_type =
+                       is_type_incomplete(type)    ? "incomplete"          :
+                       type->kind == TYPE_FUNCTION ? "function designator" :
+                       type->kind == TYPE_BITFIELD ? "bitfield"            :
+                       NULL;
+               if (wrong_type != NULL) {
+                       errorf(&pos, "operand of %s expression must not be %s type '%T'", what, wrong_type, type);
+               }
+
                rem_anchor_token(')');
                expect(')');
        } else {
                expression_t *expression = parse_sub_expression(precedence);
-               expression->base.type    = revert_automatic_type_conversion(expression);
+
+               type_t* const type = revert_automatic_type_conversion(expression);
+               expression->base.type = type;
+
+               char const* const wrong_type =
+                       is_type_incomplete(type)    ? "incomplete"          :
+                       type->kind == TYPE_FUNCTION ? "function designator" :
+                       type->kind == TYPE_BITFIELD ? "bitfield"            :
+                       NULL;
+               if (wrong_type != NULL) {
+                       errorf(&pos, "operand of %s expression must not be expression of %s type '%T'", what, wrong_type, type);
+               }
 
                tp_expression->typeprop.type          = expression->base.type;
                tp_expression->typeprop.tp_expression = expression;
@@ -5671,14 +5691,16 @@ end_error:
 
 static expression_t *parse_sizeof(unsigned precedence)
 {
+       source_position_t pos = *HERE;
        eat(T_sizeof);
-       return parse_typeprop(EXPR_SIZEOF, precedence);
+       return parse_typeprop(EXPR_SIZEOF, pos, precedence);
 }
 
 static expression_t *parse_alignof(unsigned precedence)
 {
+       source_position_t pos = *HERE;
        eat(T___alignof__);
-       return parse_typeprop(EXPR_SIZEOF, precedence);
+       return parse_typeprop(EXPR_ALIGNOF, pos, precedence);
 }
 
 static expression_t *parse_select_expression(unsigned precedence,