fix cases where compoundlits are constant/get an entity
[cparser] / parser.c
index 8f362eb..a9a4041 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -6187,21 +6187,24 @@ static bool semantic_cast(expression_t *cast)
        return true;
 }
 
-static expression_t *parse_compound_literal(source_position_t const *const pos, type_t *type)
+static expression_t *parse_compound_literal(source_position_t const *const pos,
+                                            type_t *type)
 {
        expression_t *expression = allocate_expression_zero(EXPR_COMPOUND_LITERAL);
        expression->base.source_position = *pos;
+       bool global_scope = current_scope == file_scope;
 
        parse_initializer_env_t env;
        env.type             = type;
        env.entity           = NULL;
-       env.must_be_constant = false;
+       env.must_be_constant = global_scope;
        initializer_t *initializer = parse_initializer(&env);
        type = env.type;
 
-       expression->compound_literal.initializer = initializer;
-       expression->compound_literal.type        = type;
-       expression->base.type                    = automatic_type_conversion(type);
+       expression->base.type                     = automatic_type_conversion(type);
+       expression->compound_literal.initializer  = initializer;
+       expression->compound_literal.type         = type;
+       expression->compound_literal.global_scope = global_scope;
 
        return expression;
 }
@@ -6305,7 +6308,7 @@ static expression_t *parse_parenthesized_expression(void)
 static expression_t *parse_function_keyword(funcname_kind_t const kind)
 {
        if (current_function == NULL) {
-               errorf(HERE, "'%K' used outside of a function", &token);
+               errorf(HERE, "%K used outside of a function", &token);
        }
 
        expression_t *expression  = allocate_expression_zero(EXPR_FUNCNAME);
@@ -7543,9 +7546,8 @@ static void semantic_unexpr_arithmetic(unary_expression_t *expression)
        type_t *const type      = skip_typeref(orig_type);
        if (!is_type_arithmetic(type)) {
                if (is_type_valid(type)) {
-                       /* TODO: improve error message */
-                       errorf(&expression->base.source_position,
-                               "operation needs an arithmetic type");
+                       source_position_t const *const pos = &expression->base.source_position;
+                       errorf(pos, "operand of unary expression must have arithmetic type, but is '%T'", orig_type);
                }
                return;
        } else if (is_type_integer(type)) {
@@ -7780,10 +7782,9 @@ static void semantic_binexpr_arithmetic(binary_expression_t *expression)
        type_t       *const type_right      = skip_typeref(orig_type_right);
 
        if (!is_type_arithmetic(type_left) || !is_type_arithmetic(type_right)) {
-               /* TODO: improve error message */
                if (is_type_valid(type_left) && is_type_valid(type_right)) {
-                       errorf(&expression->base.source_position,
-                              "operation needs arithmetic types");
+                       source_position_t const *const pos = &expression->base.source_position;
+                       errorf(pos, "operands of binary expression must have arithmetic types, but are '%T' and '%T'", orig_type_left, orig_type_right);
                }
                return;
        }
@@ -7804,10 +7805,9 @@ static void semantic_binexpr_integer(binary_expression_t *const expression)
        type_t       *const type_right      = skip_typeref(orig_type_right);
 
        if (!is_type_integer(type_left) || !is_type_integer(type_right)) {
-               /* TODO: improve error message */
                if (is_type_valid(type_left) && is_type_valid(type_right)) {
-                       errorf(&expression->base.source_position,
-                              "operation needs integer types");
+                       source_position_t const *const pos = &expression->base.source_position;
+                       errorf(pos, "operands of binary expression must have integer types, but are '%T' and '%T'", orig_type_left, orig_type_right);
                }
                return;
        }
@@ -7877,10 +7877,9 @@ static bool semantic_shift(binary_expression_t *expression)
        type_t       *      type_right      = skip_typeref(orig_type_right);
 
        if (!is_type_integer(type_left) || !is_type_integer(type_right)) {
-               /* TODO: improve error message */
                if (is_type_valid(type_left) && is_type_valid(type_right)) {
-                       errorf(&expression->base.source_position,
-                              "operands of shift operation must have integer types");
+                       source_position_t const *const pos = &expression->base.source_position;
+                       errorf(pos, "operands of shift expression must have integer types, but are '%T' and '%T'", orig_type_left, orig_type_right);
                }
                return false;
        }