only use rts_entities when number of parameters and results match
[cparser] / ast2firm.c
index ea749ac..702730e 100644 (file)
@@ -868,11 +868,11 @@ static const struct {
        { rts_strncmp,    1, "strncmp",      3, _C89 },
        { rts_strcpy,     1, "strcpy",       2, _C89 },
        { rts_strlen,     1, "strlen",       1, _C89 },
-       { rts_memcpy,     1, "memcpy",       3, _C89 },  /* HMM, man say its C99 */
+       { rts_memcpy,     1, "memcpy",       3, _C89 },
        { rts_mempcpy,    1, "mempcpy",      3, _GNUC },
-       { rts_memmove,    1, "memmove",      3, _C89 },  /* HMM, man say its C99 */
-       { rts_memset,     1, "memset",       3, _C89 },  /* HMM, man say its C99 */
-       { rts_memcmp,     1, "memcmp",       3, _C89 },  /* HMM, man say its C99 */
+       { rts_memmove,    1, "memmove",      3, _C89 },
+       { rts_memset,     1, "memset",       3, _C89 },
+       { rts_memcmp,     1, "memcmp",       3, _C89 },
 };
 
 static ident *rts_idents[lengthof(rts_data)];
@@ -1026,6 +1026,22 @@ static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
                        if (id != rts_idents[i])
                                continue;
 
+                       function_type_t *function_type
+                               = &entity->declaration.type->function;
+                       /* rts_entities code can't handle a "wrong" number of parameters */
+                       if (function_type->unspecified_parameters)
+                               continue;
+
+                       /* check number of parameters */
+                       int n_params = count_parameters(function_type);
+                       if (n_params != rts_data[i].n_params)
+                               continue;
+
+                       type_t *return_type = skip_typeref(function_type->return_type);
+                       int     n_res       = return_type != type_void ? 1 : 0;
+                       if (n_res != rts_data[i].n_res)
+                               continue;
+
                        /* ignore those rts functions not necessary needed for current mode */
                        if ((c_mode & rts_data[i].flags) == 0)
                                continue;
@@ -1192,13 +1208,12 @@ static void create_integer_tarval(literal_expression_t *literal)
                }
        }
 
-       unsigned char base = 10;
-       if (literal->base.kind == EXPR_LITERAL_INTEGER_OCTAL) {
-               base = 8;
-       } else if (literal->base.kind == EXPR_LITERAL_INTEGER_HEXADECIMAL) {
-               base = 16;
-       } else {
-               assert(literal->base.kind == EXPR_LITERAL_INTEGER);
+       unsigned base;
+       switch (literal->base.kind) {
+               case EXPR_LITERAL_INTEGER_OCTAL:       base =  8; break;
+               case EXPR_LITERAL_INTEGER:             base = 10; break;
+               case EXPR_LITERAL_INTEGER_HEXADECIMAL: base = 16; break;
+               default: panic("invalid literal kind");
        }
 
        tarval_int_overflow_mode_t old_mode = tarval_get_integer_overflow_mode();
@@ -1229,7 +1244,7 @@ static void create_integer_tarval(literal_expression_t *literal)
        assert(us == 1 || base != 10);
        tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP);
        bool res = try_create_integer(literal, type_unsigned_long_long, base);
-       if (res == false)
+       if (!res)
                panic("internal error when parsing number literal");
 
 finished:
@@ -2060,7 +2075,8 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
                 * nodes into a new and unreachable block. */
                keep_alive(node);
                keep_alive(get_cur_block());
-               new_Block(0, NULL);
+               ir_node *block = new_Block(0, NULL);
+               set_cur_block(block);
        }
 
        return result;
@@ -2617,7 +2633,8 @@ static ir_node *produce_condition_result(const expression_t *expression,
        mature_immBlock(zero_block);
 
        ir_node *in_cf[2] = { jmp_one, jmp_zero };
-       new_Block(2, in_cf);
+       ir_node *block = new_Block(2, in_cf);
+       set_cur_block(block);
 
        ir_node *in[2] = { one, zero };
        ir_node *val   = new_d_Phi(dbgi, 2, in, mode);
@@ -3168,7 +3185,8 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression)
 
        /* create the common block */
        ir_node *in_cf[2] = { true_jmp, false_jmp };
-       new_Block(2, in_cf);
+       ir_node *block = new_Block(2, in_cf);
+       set_cur_block(block);
 
        /* TODO improve static semantics, so either both or no values are NULL */
        if (true_val == NULL || false_val == NULL)
@@ -5473,7 +5491,7 @@ static void asm_statement_to_firm(const asm_statement_t *statement)
 
        /* create output projs & connect them */
        if (needs_memory) {
-               ir_node *projm = new_Proj(node, mode_M, out_size+1);
+               ir_node *projm = new_Proj(node, mode_M, out_size);
                set_store(projm);
        }
 
@@ -5641,13 +5659,12 @@ static void initialize_function_parameters(entity_t *entity)
        assert(entity->kind == ENTITY_FUNCTION);
        ir_graph *irg             = current_ir_graph;
        ir_node  *args            = get_irg_args(irg);
-       ir_node  *start_block     = get_irg_start_block(irg);
        ir_type  *function_irtype = get_ir_type(entity->declaration.type);
        int      first_param_nr   = 0;
 
        if (entity->function.need_closure) {
                /* add an extra parameter for the static link */
-               entity->function.static_link = new_r_Proj(start_block, args, mode_P_data, 0);
+               entity->function.static_link = new_r_Proj(args, mode_P_data, 0);
                ++first_param_nr;
        }
 
@@ -5681,7 +5698,7 @@ static void initialize_function_parameters(entity_t *entity)
                ir_mode *param_mode   = get_type_mode(param_irtype);
 
                long     pn    = n + first_param_nr;
-               ir_node *value = new_r_Proj(start_block, args, param_mode, pn);
+               ir_node *value = new_r_Proj(args, param_mode, pn);
 
                ir_mode *mode = get_ir_mode_storage(type);
                value = create_conv(NULL, value, mode);