From b8dc7adc7030c79be9590e6f03b32da629201a92 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Sat, 31 Dec 2005 15:58:09 +0000 Subject: [PATCH] trvrfy uses now verification flags [r7174] --- ir/tr/trvrfy.c | 183 +++++++++++++++++++++++++++++++++++++------------ ir/tr/trvrfy.h | 43 ++++++++---- 2 files changed, 169 insertions(+), 57 deletions(-) diff --git a/ir/tr/trvrfy.c b/ir/tr/trvrfy.c index bb9c99849..42c6e2843 100644 --- a/ir/tr/trvrfy.c +++ b/ir/tr/trvrfy.c @@ -16,11 +16,58 @@ #include "trvrfy.h" #include "irgraph_t.h" /* for checking whether constant code is allocated on proper obstack */ +#include "irflag_t.h" +#include "irprintf.h" +#include "irgwalk.h" +#include "typewalk.h" + +static const char *firm_vrfy_failure_msg; + +#ifdef NDEBUG +/* + * in RELEASE mode, returns ret if the expression expr evaluates to zero + * in ASSERT mode, asserts the expression expr (and the string string). + */ +#define ASSERT_AND_RET(expr, string, ret) if (!(expr)) return (ret) + +/* + * in RELEASE mode, returns ret if the expression expr evaluates to zero + * in ASSERT mode, executes blk if the expression expr evaluates to zero and asserts expr + */ +#define ASSERT_AND_RET_DBG(expr, string, ret, blk) if (!(expr)) return (ret) +#else +#define ASSERT_AND_RET(expr, string, ret) \ +do { \ + if (opt_do_node_verification == FIRM_VERIFICATION_ON) {\ + assert((expr) && string); } \ + if (!(expr)) { \ + if (opt_do_node_verification == FIRM_VERIFICATION_REPORT) \ + fprintf(stderr, #expr " : " string "\n"); \ + firm_vrfy_failure_msg = #expr " && " string; \ + return (ret); \ + } \ +} while(0) + +#define ASSERT_AND_RET_DBG(expr, string, ret, blk) \ +do { \ + if (!(expr)) { \ + firm_vrfy_failure_msg = #expr " && " string; \ + if (opt_do_node_verification != FIRM_VERIFICATION_ERROR_ONLY) { blk; } \ + if (opt_do_node_verification == FIRM_VERIFICATION_REPORT) \ + fprintf(stderr, #expr " : " string "\n"); \ + else if (opt_do_node_verification == FIRM_VERIFICATION_ON) { \ + assert((expr) && string); \ + } \ + return (ret); \ + } \ +} while(0) + +#endif /* NDEBUG */ /** * Check a class */ -static int check_class(type *tp) { +static int check_class(ir_type *tp) { int i, j, k; int found; @@ -34,8 +81,12 @@ static int check_class(type *tp) { if (!mem) return error_null_mem; if (get_entity_n_overwrites(mem) > get_class_n_supertypes(tp)) { - DDMT(tp); DDME(mem); - assert(get_entity_n_overwrites(mem) <= get_class_n_supertypes(tp)); + ASSERT_AND_RET_DBG( + get_entity_n_overwrites(mem) <= get_class_n_supertypes(tp), + "wrong number of entity overwrites", + error_wrong_ent_overwrites, + ir_fprintf(stderr, "%+F %+F\n", tp, mem) + ); } for (j = 0; j < get_entity_n_overwrites(mem); j++) { entity *ovw = get_entity_overwrites(mem, j); @@ -50,12 +101,14 @@ static int check_class(type *tp) { } } if (!found) { - DDMT(tp); DDME(mem); - assert(found && "overwrites an entity not contained in direct supertype"); - return error_ent_not_cont; + ASSERT_AND_RET_DBG( + found, + "overwrites an entity not contained in direct supertype", + error_ent_not_cont, + ir_fprintf(stderr, "%+F %+F\n", tp, mem) + ); } } - } return 0; } @@ -63,11 +116,16 @@ static int check_class(type *tp) { /** * Check an array. */ -static int check_array(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) - assert(has_array_lower_bound(tp, i) || has_array_upper_bound(tp, i)); - + for (i = 0; i < n_dim; ++i) { + ASSERT_AND_RET_DBG( + has_array_lower_bound(tp, i) || has_array_upper_bound(tp, i), + "array bound missing", + 1, + ir_fprintf(stderr, "%+F in dimension %d\n", tp, i) + ); + } return 0; } @@ -75,19 +133,24 @@ static int check_array(type *tp) { /** * Check a primitive. */ -static int check_primitive(type *tp) { - assert(is_mode(get_type_mode(tp))); - +static int check_primitive(ir_type *tp) { + ASSERT_AND_RET_DBG( + is_mode(get_type_mode(tp)), + "Primitive type without mode", + 1, + ir_fprintf(stderr, "%+F\n", tp) + ); return 0; } -/** +/* * Checks a type. * - * Currently checks class types only. + * return + * 0 if no error encountered */ -static int check_type(type *tp) { +int check_type(ir_type *tp) { switch (get_type_tpop_code(tp)) { case tpo_class: return check_class(tp); @@ -100,6 +163,19 @@ static int check_type(type *tp) { return 0; } +/** + * checks the visited flag + */ +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.", + 0, + ir_fprintf(stderr, "%+F in %+F\n", n, irg) + ); + return 1; +} + /** * helper environment struct for constant_on_wrong_obstack() */ @@ -112,13 +188,11 @@ struct myenv { * called by the walker */ static void on_irg_storage(ir_node *n, void *env) { - struct myenv * myenv = env; - - myenv->res = node_is_in_irgs_storage(myenv->irg, n); + struct myenv *myenv = env; /* We also test whether the setting of the visited flag is legal. */ - assert(get_irn_visited(n) <= get_irg_visited(myenv->irg) && - "Visited flag of node is larger than that of corresponding irg."); + myenv->res = node_is_in_irgs_storage(myenv->irg, n) && + check_visited_flag(myenv->irg, n); } /** @@ -151,10 +225,15 @@ static int constants_on_wrong_irg(entity *ent) { /* 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((is_Class_type(get_entity_owner(ent)) && - get_class_peculiarity(get_entity_owner(ent)) == peculiarity_description) && - "Value in constant atomic entity not set."); + 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, "%+F, owner %+F\n", ent, get_entity_owner(ent)) + ); + } } return 0; } @@ -165,18 +244,15 @@ static int constants_on_wrong_irg(entity *ent) { * * @return * 0 if no error encountered - * != 0 else + * != 0 a trvrfy_error_codes code */ -static int check_entity(entity *ent) { +int check_entity(entity *ent) { int rem_vpi; - type *tp = get_entity_type(ent); - type *owner = get_entity_owner(ent); + ir_type *tp = get_entity_type(ent); + ir_type *owner = get_entity_owner(ent); current_ir_graph = get_const_code_irg(); - if (constants_on_wrong_irg(ent)) { - assert(0 && "Contants placed on wrong IRG"); - return error_const_on_wrong_irg; - } + ASSERT_AND_RET(constants_on_wrong_irg(ent) == 0, "Contants placed on wrong IRG", error_const_on_wrong_irg); rem_vpi = get_visit_pseudo_irgs(); set_visit_pseudo_irgs(1); @@ -184,37 +260,54 @@ static int check_entity(entity *ent) { (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(0 && "Method ents with pec_exist must have an irg"); - return error_existent_entity_without_irg; + ASSERT_AND_RET_DBG( + 0, + "Method ents with pec_exist must have an irg", + error_existent_entity_without_irg, + ir_fprintf(stderr, "%+F\n", ent) + ); } set_visit_pseudo_irgs(rem_vpi); /* Originally, this test assumed, that only method entities have - pec_inh. As I changed this, I have to test for method type before + 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))) { entity *impl = get_SymConst_entity(get_atomic_ent_value(ent)); - assert(get_entity_peculiarity(impl) == peculiarity_existent && - "inherited method entities must have constant pointing to existent entity."); + 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, "%+F points to %+F\n", ent, impl) + ); } } /* Entities in global type are not dynamic or automatic allocated. */ if (owner == get_glob_type()) { - assert(get_entity_allocation(ent) != allocation_dynamic && - get_entity_allocation(ent) != allocation_automatic); + 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, + ir_fprintf(stderr, "%+F\n", ent) + ); } if (get_entity_variability(ent) != variability_uninitialized) { if (is_atomic_type(tp)) { ir_node *val = get_atomic_ent_value(ent); if (val) - assert(get_irn_mode(val) == get_type_mode(tp) && - "Mode of constant in entity must match type."); + 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, "%+F const %+F, type %+F(%+F)\n", + ent, val, tp, get_type_mode(tp)) + ); } } - return no_error; } @@ -225,7 +318,7 @@ static void check_tore(type_or_ent *tore, void *env) { int *res = env; assert(tore); if (is_type(tore)) { - *res = check_type((type *)tore); + *res = check_type((ir_type *)tore); } else { assert(is_entity(tore)); *res = check_entity((entity *)tore); diff --git a/ir/tr/trvrfy.h b/ir/tr/trvrfy.h index bca59bd49..8e1f82490 100644 --- a/ir/tr/trvrfy.h +++ b/ir/tr/trvrfy.h @@ -9,11 +9,11 @@ * Copyright: (c) 2003 Universität Karlsruhe * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ - - #ifndef TRVRFY_H #define TRVRFY_H +#include "firm_types.h" + /** * @file trvrfy.h * @@ -27,19 +27,38 @@ * */ -#include "firm.h" - /** * possible trvrfy() error codes */ -enum trvrfy_error_codes { - no_error = 0, /**< no error */ - error_ent_not_cont = 1, /**< overwritten entity not in superclass */ - error_null_mem = 2, /**< compound contains NULL member */ - error_const_on_wrong_irg = 3, /**< constant placed on wrong IRG */ - error_existent_entity_without_irg = 4 /**< Method ents with pec_exist must have an irg */ +enum trvrfy_error_codes { + no_error = 0, /**< no error */ + error_ent_not_cont = 1, /**< overwritten entity not in superclass */ + error_null_mem = 2, /**< compound contains NULL member */ + error_const_on_wrong_irg = 3, /**< constant placed on wrong IRG */ + error_existent_entity_without_irg = 4, /**< Method entities with pecularity_exist must have an irg */ + error_wrong_ent_overwrites = 5, /**< number of entity overwrites exceeds number of class overwrites */ + error_inherited_ent_without_const = 6, /**< inherited method entity not pointing to existent entity */ + error_glob_ent_allocation = 7, /**< wrong allocation of a global entity */ + error_ent_const_mode = 8 /**< Mode of constant in entity did not match entities type. */ }; +/** + * Checks a type. + * + * @return + * 0 if no error encountered + */ +int check_type(ir_type *tp); + +/** + * Check an entity. Currently, we check only if initialized constants + * are build on the const irg graph. + * + * @return + * 0 if no error encountered + * != 0 a trvrfy_error_codes code + */ +int check_entity(entity *ent); /** * Walks the type information and performs a set of sanity checks. @@ -47,7 +66,7 @@ enum trvrfy_error_codes { * Currently, the following checks are executed: * - values of initialized entities must be allocated on the constant IRG * - class types: doesn't have NULL members - * - class types: all overwrites are existant in the super type + * - class types: all overwrites are existent in the super type * * @return * 0 if graph is correct @@ -56,7 +75,7 @@ enum trvrfy_error_codes { int tr_vrfy(void); /** - * If NDEBUG is defined performs nothing, else calles the tr_vrfy() function. + * If NDEBUG is defined performs nothing, else calls the tr_vrfy() function. */ #ifdef NDEBUG #define TR_VRFY() 0 -- 2.20.1