X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftr%2Ftrvrfy.c;h=49e8fead744d38f1b85f1e27afd83f3394245139;hb=04321ea9f9ac1185bd7092813c34683aa15cd05f;hp=ee3f6152c30f0cd06908cf527da10c0b6812a7ca;hpb=d79a44d18a33ec48ce0c9be0491880d240bb07ef;p=libfirm diff --git a/ir/tr/trvrfy.c b/ir/tr/trvrfy.c index ee3f6152c..49e8fead7 100644 --- a/ir/tr/trvrfy.c +++ b/ir/tr/trvrfy.c @@ -24,16 +24,14 @@ * @author Michael Beck, Goetz Lindenmaier * @version $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif -#include "irgraph_t.h" /* for checking whether constant code is allocated - on proper obstack */ +#include "irgraph_t.h" #include "irflag_t.h" #include "irprintf.h" #include "irgwalk.h" - +#include "error.h" +#include "tv.h" #ifdef NDEBUG /* @@ -58,7 +56,7 @@ do { \ firm_vrfy_failure_msg = #expr " && " string; \ return (ret); \ } \ -} while(0) +} while (0) #define ASSERT_AND_RET_DBG(expr, string, ret, blk) \ do { \ @@ -72,7 +70,7 @@ do { \ } \ return (ret); \ } \ -} while(0) +} while (0) #endif /* NDEBUG */ @@ -84,7 +82,8 @@ static const char *firm_vrfy_failure_msg; * Show diagnostic if an entity overwrites another one not * in direct superclasses. */ -static void show_ent_not_supertp(ir_entity *ent, ir_entity *ovw) { +static void show_ent_not_supertp(ir_entity *ent, ir_entity *ovw) +{ ir_type *owner = get_entity_owner(ent); ir_type *ov_own = get_entity_owner(ovw); int i; @@ -103,7 +102,8 @@ static void show_ent_not_supertp(ir_entity *ent, ir_entity *ovw) { /** * Show diagnostic if an entity overwrites a wrong number of things. */ -static void show_ent_overwrite_cnt(ir_entity *ent) { +static void show_ent_overwrite_cnt(ir_entity *ent) +{ ir_type *owner = get_entity_owner(ent); int i, j, k, found, show_stp = 0; @@ -140,21 +140,13 @@ static void show_ent_overwrite_cnt(ir_entity *ent) { } } -/** - * Shows a wrong entity allocation - */ -static void show_ent_alloc_error(ir_entity *ent) { - ir_fprintf(stderr, "%+e owner %t has allocation %s\n", - ent, get_entity_type(ent), - get_allocation_name(get_entity_allocation(ent))); -} - #endif /* #ifndef NDEBUG */ /** * Check a class */ -static int check_class(ir_type *tp) { +static int check_class(ir_type *tp) +{ int i, j, k; int found; @@ -207,7 +199,8 @@ static int check_class(ir_type *tp) { /** * Check an array. */ -static int check_array(ir_type *tp) { +static int check_array(ir_type *tp) +{ int i, n_dim = get_array_n_dimensions(tp); for (i = 0; i < n_dim; ++i) { @@ -225,7 +218,8 @@ static int check_array(ir_type *tp) { /** * Check a primitive. */ -static int check_primitive(ir_type *tp) { +static int check_primitive(ir_type *tp) +{ ASSERT_AND_RET_DBG( is_mode(get_type_mode(tp)), "Primitive type without mode", @@ -242,7 +236,8 @@ static int check_primitive(ir_type *tp) { * return * 0 if no error encountered */ -int check_type(ir_type *tp) { +int check_type(ir_type *tp) +{ switch (get_type_tpop_code(tp)) { case tpo_class: return check_class(tp); @@ -258,7 +253,8 @@ int check_type(ir_type *tp) { /** * checks the visited flag */ -static int check_visited_flag(ir_graph *irg, ir_node *n) { +static int check_visited_flag(ir_graph *irg, ir_node *n) +{ ASSERT_AND_RET_DBG( get_irn_visited(n) <= get_irg_visited(irg), "Visited flag of node is larger than that of corresponding irg.", @@ -279,7 +275,8 @@ struct myenv { /** * called by the walker */ -static void on_irg_storage(ir_node *n, void *env) { +static void on_irg_storage(ir_node *n, void *env) +{ struct myenv *myenv = env; /* We also test whether the setting of the visited flag is legal. */ @@ -291,7 +288,8 @@ static void on_irg_storage(ir_node *n, void *env) { * checks whether a given constant IR node is NOT on the * constant IR graph. */ -static int constant_on_wrong_irg(ir_node *n) { +static int constant_on_wrong_irg(ir_node *n) +{ struct myenv env; env.res = 1; /* on right obstack */ @@ -301,35 +299,45 @@ static int constant_on_wrong_irg(ir_node *n) { return ! env.res; } +static int initializer_constant_on_wrong_irg(ir_initializer_t *initializer) +{ + switch (get_initializer_kind(initializer)) { + case IR_INITIALIZER_NULL: + return 0; + case IR_INITIALIZER_TARVAL: + return 0; + case IR_INITIALIZER_CONST: + return constant_on_wrong_irg(get_initializer_const_value(initializer)); + case IR_INITIALIZER_COMPOUND: { + int n = get_initializer_compound_n_entries(initializer); + int i; + for (i = 0; i < n; ++i) { + ir_initializer_t *sub + = get_initializer_compound_value(initializer, i); + if (initializer_constant_on_wrong_irg(sub)) + return 1; + } + return 0; + } + } + panic("invalid initializer in initializer_on_wrong_irg"); +} + /** * Check if constants node are NOT on the constant IR graph. * * @return NON-zero if an entity initializer constant is NOT on * the current_ir_graph's obstack. */ -static int constants_on_wrong_irg(ir_entity *ent) { - if (get_entity_variability(ent) == variability_uninitialized) return 0; - - if (is_compound_entity(ent)) { - if(!ent->has_initializer) { - int i; - for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i) { - if (constant_on_wrong_irg(get_compound_ent_value(ent, i))) - return 1; - } - } - } else { - /* Might not be set if entity belongs to a description or is external allocated. */ - if (get_atomic_ent_value(ent)) - return constant_on_wrong_irg(get_atomic_ent_value(ent)); - else if (get_entity_visibility(ent) != visibility_external_allocated) { - ASSERT_AND_RET_DBG( - is_Class_type(get_entity_owner(ent)) && - get_class_peculiarity(get_entity_owner(ent)) == peculiarity_description, - "Value in constant atomic entity not set.", - 0, - ir_fprintf(stderr, "%+e, owner %+F\n", ent, get_entity_owner(ent)) - ); +static int constants_on_wrong_irg(ir_entity *ent) +{ + if (ent->initializer != NULL) { + return initializer_constant_on_wrong_irg(ent->initializer); + } else if (entity_has_compound_ent_values(ent)) { + int i; + for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i) { + if (constant_on_wrong_irg(get_compound_ent_value(ent, i))) + return 1; } } return 0; @@ -343,9 +351,9 @@ static int constants_on_wrong_irg(ir_entity *ent) { * 0 if no error encountered * != 0 a trvrfy_error_codes code */ -int check_entity(ir_entity *ent) { +int check_entity(ir_entity *ent) +{ ir_type *tp = get_entity_type(ent); - ir_type *owner = get_entity_owner(ent); current_ir_graph = get_const_code_irg(); ASSERT_AND_RET_DBG( @@ -356,44 +364,41 @@ int check_entity(ir_entity *ent) { ); /* Originally, this test assumed, that only method entities have - pecularity_inherited. As I changed this, I have to test for method type before - doing the test. */ - if (get_entity_peculiarity(ent) == peculiarity_inherited) { - if (is_Method_type(get_entity_type(ent))) { - ir_entity *impl = get_SymConst_entity(get_atomic_ent_value(ent)); - ASSERT_AND_RET_DBG( - get_entity_peculiarity(impl) == peculiarity_existent, - "inherited method entities must have constant pointing to existent entity.", - error_inherited_ent_without_const, - ir_fprintf(stderr, "%+e points to %+e\n", ent, impl) - ); - } - } + pecularity_inherited. As I changed this, I have to test for method type + before doing the test. */ + if (get_entity_peculiarity(ent) == peculiarity_existent + && is_method_entity(ent)) { - /* Entities in global type are not dynamic or automatic allocated. */ - if (owner == get_glob_type()) { + ir_entity *impl = get_SymConst_entity(get_atomic_ent_value(ent)); ASSERT_AND_RET_DBG( - get_entity_allocation(ent) != allocation_dynamic && - get_entity_allocation(ent) != allocation_automatic, - "Entities in global type are not allowed to by dynamic or automatic allocated", - error_glob_ent_allocation, - show_ent_alloc_error(ent) + impl != NULL, + "inherited method entities must have constant pointing to existent entity.", + error_inherited_ent_without_const, + ir_fprintf(stderr, "%+e points to %+e\n", ent, impl) ); } - if (get_entity_variability(ent) != variability_uninitialized) { - if (is_atomic_type(tp)) { - ir_node *val = get_atomic_ent_value(ent); - if (val) { - ASSERT_AND_RET_DBG( - get_irn_mode(val) == get_type_mode(tp), - "Mode of constant in entity must match type.", - error_ent_const_mode, - ir_fprintf(stderr, "%+e const %+F, type %+F(%+F)\n", - ent, val, tp, get_type_mode(tp)) - ); - } + if (is_atomic_entity(ent) && ent->initializer != NULL) { + ir_mode *mode = NULL; + ir_initializer_t *initializer = ent->initializer; + switch (initializer->kind) { + case IR_INITIALIZER_CONST: + mode = get_irn_mode(get_initializer_const_value(initializer)); + break; + case IR_INITIALIZER_TARVAL: + mode = get_tarval_mode(get_initializer_tarval_value(initializer)); + break; + case IR_INITIALIZER_NULL: + case IR_INITIALIZER_COMPOUND: + break; } + ASSERT_AND_RET_DBG( + mode == NULL || mode == get_type_mode(tp), + "Mode of constant in entity must match type.", + error_ent_const_mode, + ir_fprintf(stderr, "%+e, type %+F(%+F)\n", + ent, tp, get_type_mode(tp)) + ); } return no_error; } @@ -401,23 +406,64 @@ int check_entity(ir_entity *ent) { /* * check types and entities */ -static void check_tore(type_or_ent *tore, void *env) { +static void check_tore(type_or_ent tore, void *env) +{ int *res = env; - assert(tore); - if (is_type(tore)) { - *res = check_type((ir_type *)tore); + assert(tore.ent); + if (is_type(tore.typ)) { + *res = check_type(tore.typ); } else { - assert(is_entity(tore)); - *res = check_entity((ir_entity *)tore); + assert(is_entity(tore.ent)); + *res = check_entity(tore.ent); } } /* * Verify types and entities. */ -int tr_vrfy(void) { - int res; +int tr_vrfy(void) +{ + int res = no_error; + ir_type *constructors; + ir_type *destructors; + ir_type *thread_locals; + int i; + static ident *empty = NULL; + + if (empty == NULL) + empty = new_id_from_chars("", 0); type_walk(check_tore, NULL, &res); + + constructors = get_segment_type(IR_SEGMENT_CONSTRUCTORS); + for (i = get_compound_n_members(constructors)-1; i >= 0; --i) { + const ir_entity *entity = get_compound_member(constructors, i); + ASSERT_AND_RET(get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER, + "entity without LINKAGE_HIDDEN_USER in constructors is pointless", + 1); + /* Mach-O doesn't like labels in this section */ + ASSERT_AND_RET(get_entity_ld_ident(entity), + "entity in constructors should have ld_ident=''", 1); + } + destructors = get_segment_type(IR_SEGMENT_DESTRUCTORS); + for (i = get_compound_n_members(destructors)-1; i >= 0; --i) { + const ir_entity *entity = get_compound_member(destructors, i); + ASSERT_AND_RET(get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER, + "entity without LINKAGE_HIDDEN_USER in destructors is pointless", + 1); + /* Mach-O doesn't like labels in this section */ + ASSERT_AND_RET(get_entity_ld_ident(entity), + "entity in destructors should have ld_ident=''", 1); + } + thread_locals = get_segment_type(IR_SEGMENT_THREAD_LOCAL); + for (i = get_compound_n_members(thread_locals)-1; i >= 0; --i) { + const ir_entity *entity = get_compound_member(thread_locals, i); + /* this is odd and should not be allowed I think */ + ASSERT_AND_RET(!is_method_entity(entity), + "method in THREAD_LOCAL segment", 1); + ASSERT_AND_RET(! (get_entity_linkage(entity) & IR_LINKAGE_CONSTANT), + "thread locals must not be constant", 1); + } + return res; }