implement sizeof(func) and alignof(func) in gnu99 mode
authorMatthias Braun <matze@braunis.de>
Fri, 18 Feb 2011 16:45:53 +0000 (16:45 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 18 Feb 2011 16:45:53 +0000 (16:45 +0000)
[r28414]

ast2firm.c
parser.c

index 3464616..7b2881d 100644 (file)
@@ -3040,6 +3040,11 @@ static ir_node *sizeof_to_firm(const typeprop_expression_t *expression)
                        && expression->tp_expression != NULL) {
                expression_to_firm(expression->tp_expression);
        }
                        && expression->tp_expression != NULL) {
                expression_to_firm(expression->tp_expression);
        }
+       /* strange gnu extensions: sizeof(function) == 1 */
+       if (is_type_function(type)) {
+               ir_mode *mode = get_ir_mode_storage(type_size_t);
+               return new_Const(get_mode_one(mode));
+       }
 
        return get_type_size_node(type);
 }
 
        return get_type_size_node(type);
 }
@@ -3079,7 +3084,12 @@ static ir_node *alignof_to_firm(const typeprop_expression_t *expression)
        if (tp_expression != NULL) {
                entity_t *entity = get_expression_entity(tp_expression);
                if (entity != NULL) {
        if (tp_expression != NULL) {
                entity_t *entity = get_expression_entity(tp_expression);
                if (entity != NULL) {
-                       alignment = get_cparser_entity_alignment(entity);
+                       if (entity->kind == ENTITY_FUNCTION) {
+                               /* a gnu-extension */
+                               alignment = 1;
+                       } else {
+                               alignment = get_cparser_entity_alignment(entity);
+                       }
                }
        }
 
                }
        }
 
index 70a7dc5..cd2f037 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -7274,12 +7274,28 @@ typeprop_expression:
 
        tp_expression->typeprop.type   = orig_type;
        type_t const* const type       = skip_typeref(orig_type);
 
        tp_expression->typeprop.type   = orig_type;
        type_t const* const type       = skip_typeref(orig_type);
-       char   const* const wrong_type =
-               GNU_MODE && is_type_atomic(type, ATOMIC_TYPE_VOID) ? NULL                  :
-               is_type_incomplete(type)                           ? "incomplete"          :
-               type->kind == TYPE_FUNCTION                        ? "function designator" :
-               type->kind == TYPE_BITFIELD                        ? "bitfield"            :
-               NULL;
+       char   const*       wrong_type = NULL;
+       if (is_type_incomplete(type)) {
+               if (!is_type_atomic(type, ATOMIC_TYPE_VOID) || !GNU_MODE)
+                       wrong_type = "incomplete";
+       } else if (type->kind == TYPE_FUNCTION) {
+               if (GNU_MODE) {
+                       /* function types are allowed (and return 1) */
+                       if (warning.other) {
+                               char const* const what = kind == EXPR_SIZEOF ? "sizeof" : "alignof";
+                               warningf(&tp_expression->base.source_position,
+                                        "%s expression with function argument returns invalid result", what);
+                       }
+               } else {
+                       wrong_type = "function";
+               }
+       } else {
+               if (is_type_incomplete(type))
+                       wrong_type = "incomplete";
+       }
+       if (type->kind == TYPE_BITFIELD)
+               wrong_type = "bitfield";
+
        if (wrong_type != NULL) {
                char const* const what = kind == EXPR_SIZEOF ? "sizeof" : "alignof";
                errorf(&tp_expression->base.source_position,
        if (wrong_type != NULL) {
                char const* const what = kind == EXPR_SIZEOF ? "sizeof" : "alignof";
                errorf(&tp_expression->base.source_position,