diff options
author | Ian Romanick <[email protected]> | 2010-07-02 13:30:23 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2010-07-12 15:19:29 -0700 |
commit | c67016de960c988c748ffdb11247072543a8f328 (patch) | |
tree | 40c039fdc244d0567f777946a42c38128d3d6fa7 | |
parent | df05ad4e1aa5512ce1dfd2e6661641e012c8b279 (diff) |
ir_validate: Additional function related invariant checks
Add two invariant checks related to functions and function signatures:
1. Ensure that function definitions (ir_function) are not nested.
2. Ensure that the ir_function pointed to by an ir_function_signature
is the one that contains it in its signatures list.
-rw-r--r-- | src/glsl/ir_validate.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 7582d57e7c3..8c86748d26a 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -46,6 +46,8 @@ public: this->ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); + this->current_function = NULL; + this->callback = ir_validate::validate_ir; this->data = ht; } @@ -57,12 +59,70 @@ public: virtual ir_visitor_status visit(ir_variable *v); + virtual ir_visitor_status visit_enter(ir_function *ir); + virtual ir_visitor_status visit_leave(ir_function *ir); + virtual ir_visitor_status visit_enter(ir_function_signature *ir); + static void validate_ir(ir_instruction *ir, void *data); + ir_function *current_function; + struct hash_table *ht; }; ir_visitor_status +ir_validate::visit_enter(ir_function *ir) +{ + /* Function definitions cannot be nested. + */ + if (this->current_function != NULL) { + printf("Function definition nested inside another function " + "definition:\n"); + printf("%s %p inside %s %p\n", + ir->name, ir, + this->current_function->name, this->current_function); + abort(); + } + + /* Store the current function hierarchy being traversed. This is used + * by the function signature visitor to ensure that the signatures are + * linked with the correct functions. + */ + this->current_function = ir; + + this->validate_ir(ir, this->data); + + return visit_continue; +} + +ir_visitor_status +ir_validate::visit_leave(ir_function *ir) +{ + (void) ir; + + this->current_function = NULL; + return visit_continue; +} + +ir_visitor_status +ir_validate::visit_enter(ir_function_signature *ir) +{ + if (this->current_function != ir->function()) { + printf("Function signature nested inside wrong function " + "definition:\n"); + printf("%p inside %s %p instead of %s %p\n", + ir, + this->current_function->name, this->current_function, + ir->function_name(), ir->function()); + abort(); + } + + this->validate_ir(ir, this->data); + + return visit_continue; +} + +ir_visitor_status ir_validate::visit(ir_variable *ir) { /* An ir_variable is the one thing that can (and will) appear multiple times |