X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftr%2Ftrvrfy.c;h=49e8fead744d38f1b85f1e27afd83f3394245139;hb=04321ea9f9ac1185bd7092813c34683aa15cd05f;hp=aac29358787277293b1340580d920285b90aec55;hpb=60a271b605cd365033e0a4df54f3cc53ac831957;p=libfirm diff --git a/ir/tr/trvrfy.c b/ir/tr/trvrfy.c index aac293587..49e8fead7 100644 --- a/ir/tr/trvrfy.c +++ b/ir/tr/trvrfy.c @@ -30,7 +30,8 @@ #include "irflag_t.h" #include "irprintf.h" #include "irgwalk.h" - +#include "error.h" +#include "tv.h" #ifdef NDEBUG /* @@ -55,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 { \ @@ -69,7 +70,7 @@ do { \ } \ return (ret); \ } \ -} while(0) +} while (0) #endif /* NDEBUG */ @@ -81,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; @@ -100,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; @@ -137,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; @@ -204,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) { @@ -222,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", @@ -239,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); @@ -255,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.", @@ -276,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. */ @@ -288,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 */ @@ -298,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; @@ -340,10 +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 rem_vpi; +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( @@ -353,60 +363,42 @@ int check_entity(ir_entity *ent) { ir_fprintf(stderr, "%+e not on %+F\n", ent, current_ir_graph) ); - rem_vpi = get_visit_pseudo_irgs(); - set_visit_pseudo_irgs(1); - if ((get_entity_peculiarity(ent) == peculiarity_existent) && - (get_entity_visibility(ent) != visibility_external_allocated) && - (is_Method_type(get_entity_type(ent))) && - (!get_entity_irg(ent) || !(is_ir_graph(get_entity_irg(ent))))) { - ASSERT_AND_RET_DBG( - 0, - "Method ents with pec_exist must have an irg", - error_existent_entity_without_irg, - ir_fprintf(stderr, "%+e\n", ent) - ); - } - set_visit_pseudo_irgs(rem_vpi); - /* 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; } @@ -414,7 +406,8 @@ 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.ent); if (is_type(tore.typ)) { @@ -428,9 +421,49 @@ static void check_tore(type_or_ent tore, void *env) { /* * 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; }