glsl: Add validations for ir_call.
authorPaul Berry <stereotype441@gmail.com>
Tue, 2 Aug 2011 22:44:39 +0000 (15:44 -0700)
committerPaul Berry <stereotype441@gmail.com>
Tue, 16 Aug 2011 00:23:02 +0000 (17:23 -0700)
This patch extends ir_validate.cpp to check the following
characteristics of each ir_call:

- The number of actual parameters must match the number of formal
  parameters in the signature.

- The type of each actual parameter must match the type of the
  corresponding formal parameter in the signature.

- Each "out" or "inout" actual parameter must be an lvalue.

Reviewed-by: Chad Versace <chad@chad-versace.us>
src/glsl/ir_validate.cpp

index f3fceb2a57da4b401ae1758d737d2e5471bd7d96..b3ca72ef0c218eadb4dc6833a4e9f2acfd3b6c5a 100644 (file)
@@ -541,7 +541,43 @@ ir_validate::visit_enter(ir_call *ir)
       abort();
    }
 
+   const exec_node *formal_param_node = callee->parameters.head;
+   const exec_node *actual_param_node = ir->actual_parameters.head;
+   while (true) {
+      if (formal_param_node->is_tail_sentinel()
+          != actual_param_node->is_tail_sentinel()) {
+         printf("ir_call has the wrong number of parameters:\n");
+         goto dump_ir;
+      }
+      if (formal_param_node->is_tail_sentinel()) {
+         break;
+      }
+      const ir_variable *formal_param
+         = (const ir_variable *) formal_param_node;
+      const ir_rvalue *actual_param
+         = (const ir_rvalue *) actual_param_node;
+      if (formal_param->type != actual_param->type) {
+         printf("ir_call parameter type mismatch:\n");
+         goto dump_ir;
+      }
+      if (formal_param->mode == ir_var_out
+          || formal_param->mode == ir_var_inout) {
+         if (!actual_param->is_lvalue()) {
+            printf("ir_call out/inout parameters must be lvalues:\n");
+            goto dump_ir;
+         }
+      }
+      formal_param_node = formal_param_node->next;
+      actual_param_node = actual_param_node->next;
+   }
+
    return visit_continue;
+
+dump_ir:
+   ir->print();
+   printf("callee:\n");
+   callee->print();
+   abort();
 }
 
 void