mesa: glsl: additional error detection
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 24 Jul 2008 23:49:33 +0000 (17:49 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 25 Jul 2008 14:26:53 +0000 (08:26 -0600)
Plus begin some fixes for vec/matrix constructors.

src/mesa/shader/slang/slang_codegen.c
src/mesa/shader/slang/slang_emit.c
src/mesa/shader/slang/slang_simplify.c

index 1b69277387e3108cd51b8b7fe552ac3e2a170eb6..2f9e147b87c78ad67c9f1a21c04031f819f34415 100644 (file)
@@ -1702,7 +1702,7 @@ print_funcs(struct slang_function_scope_ *scope, const char *name)
 
 
 /**
- * Return first function in the scope that has the given name.
+ * Find a function of the given name, taking 'numArgs' arguments.
  * This is the function we'll try to call when there is no exact match
  * between function parameters and call arguments.
  *
@@ -1710,16 +1710,18 @@ print_funcs(struct slang_function_scope_ *scope, const char *name)
  * all of them...
  */
 static slang_function *
-_slang_first_function(struct slang_function_scope_ *scope, const char *name)
+_slang_find_function_by_argc(struct slang_function_scope_ *scope,
+                             const char *name, int numArgs)
 {
    GLuint i;
    for (i = 0; i < scope->num_functions; i++) {
       slang_function *f = &scope->functions[i];
-      if (strcmp(name, (char*) f->header.a_name) == 0)
+      if (strcmp(name, (char*) f->header.a_name) == 0
+          /*&& numArgs == f->param_count*/)
          return f;
    }
    if (scope->outer_scope)
-      return _slang_first_function(scope->outer_scope, name);
+      return _slang_find_function_by_argc(scope->outer_scope, name, numArgs);
    return NULL;
 }
 
@@ -1918,7 +1920,8 @@ _slang_gen_function_call_name(slang_assemble_ctx *A, const char *name,
       /* A function with exactly the right parameters/types was not found.
        * Try adapting the parameters.
        */
-      fun = _slang_first_function(A->space.funcs, name);
+      int numArgs = oper->num_children;
+      fun = _slang_find_function_by_argc(A->space.funcs, name, numArgs);
       if (!fun || !_slang_adapt_call(oper, fun, &A->space, A->atoms, A->log)) {
          slang_info_log_error(A->log, "Function '%s' not found (check argument types)", name);
          return NULL;
@@ -2313,6 +2316,11 @@ _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var)
       n->Store->File = PROGRAM_TEMPORARY;
       n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier);
 
+      if (n->Store->Size <= 0) {
+         slang_info_log_error(A->log, "invalid declaration for '%s'",
+                              (char*) var->a_name);
+         return NULL;
+      }
 #if 0
       printf("%s var %p %s  store=%p index=%d size=%d\n",
              __FUNCTION__, (void *) var, (char *) var->a_name,
@@ -2548,8 +2556,16 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
    assert(oper->num_children == 0 || oper->num_children == 1);
 
    v = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE);
+   /*printf("Declare %s at %p\n", varName, v);*/
    assert(v);
 
+#if 0
+   if (v->declared) {
+      slang_info_log_error(A->log, "variable '%s' redeclared", varName);
+      return NULL;
+   }
+#endif
+
    varDecl = _slang_gen_var_decl(A, v);
 
    if (oper->num_children > 0) {
@@ -2706,6 +2722,11 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper)
       lhs = _slang_gen_operation(A, &oper->children[0]);
 
       if (lhs) {
+         if (!lhs->Store) {
+            slang_info_log_error(A->log,
+                                 "invalid left hand side for assignment");
+            return NULL;
+         }
          if (!(lhs->Store->File == PROGRAM_OUTPUT ||
                lhs->Store->File == PROGRAM_TEMPORARY ||
                (lhs->Store->File == PROGRAM_VARYING &&
@@ -2759,6 +2780,7 @@ _slang_gen_struct_field(slang_assemble_ctx * A, slang_operation *oper)
       GLuint swizzle;
       if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) {
          slang_info_log_error(A->log, "Bad swizzle");
+         return NULL;
       }
       swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
                               swz.swizzle[1],
@@ -2807,10 +2829,14 @@ _slang_gen_struct_field(slang_assemble_ctx * A, slang_operation *oper)
          fieldOffset = _slang_field_offset(&ti.spec, oper->a_id);
 
       if (fieldSize == 0 || fieldOffset < 0) {
+         const char *structName;
+         if (ti.spec._struct)
+            structName = (char *) ti.spec._struct->a_name;
+         else
+            structName = "unknown";
          slang_info_log_error(A->log,
                               "\"%s\" is not a member of struct \"%s\"",
-                              (char *) oper->a_id,
-                              (char *) ti.spec._struct->a_name);
+                              (char *) oper->a_id, structName);
          return NULL;
       }
       assert(fieldSize >= 0);
@@ -2945,6 +2971,23 @@ _slang_gen_array_element(slang_assemble_ctx * A, slang_operation *oper)
 }
 
 
+#if 0
+static void
+print_vars(slang_variable_scope *s)
+{
+   int i;
+   printf("vars: ");
+   for (i = 0; i < s->num_variables; i++) {
+      printf("%s %d, \n",
+             (char*) s->variables[i]->a_name,
+             s->variables[i]->declared);
+   }
+
+   printf("\n");
+}
+#endif
+
+
 /**
  * Generate IR tree for a slang_operation (AST node)
  */
@@ -2964,6 +3007,8 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
 
          _slang_pop_var_table(A->vartable);
 
+         /*print_vars(oper->locals);*/
+
          if (n)
             n = new_node1(IR_SCOPE, n);
          return n;
@@ -3006,6 +3051,7 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
             }
          }
 #endif
+         /*print_vars(oper->locals);*/
          return tree;
       }
       else {
index 1f4d962bdf6b1834ca8c3f9ac3c72309de736008..9bff055ad5648b6f9002f75f2ca14062a25cb69d 100644 (file)
@@ -625,7 +625,11 @@ emit_compare(slang_emit_info *emitInfo, slang_ir_node *n)
    emit(emitInfo, n->Children[0]);
    emit(emitInfo, n->Children[1]);
 
-   assert(n->Children[0]->Store->Size == n->Children[1]->Store->Size);
+   if (n->Children[0]->Store->Size != n->Children[1]->Store->Size) {
+      slang_info_log_error(emitInfo->log, "invalid operands to == or !=");
+      return NULL;
+   }
+
    size = n->Children[0]->Store->Size;
 
    if (size == 1) {
index d5997283a879d0a936a3f6f61593bed28f44dcdc..c34bef2164aecebc3538b691b93859d8c641a37b 100644 (file)
@@ -331,8 +331,9 @@ _slang_adapt_call(slang_operation *callOper, const slang_function *fun,
    int i;
    int dbg = 0;
 
-   if (dbg) printf("Adapt %d args to %d parameters\n",
-                   callOper->num_children, numParams);
+   if (dbg)
+      printf("Adapt %d args to %d parameters for %s\n",
+             callOper->num_children, numParams, (char *) fun->header.a_name);
 
    /* Only try adapting for constructors */
    if (fun->kind != SLANG_FUNC_CONSTRUCTOR)
@@ -441,6 +442,9 @@ _slang_adapt_call(slang_operation *callOper, const slang_function *fun,
             slang_type_specifier_type_to_string(paramVar->type.specifier.type);
          slang_operation *child = slang_operation_new(1);
 
+         if (dbg)
+            printf("Need to adapt types of arg %d\n", i);
+
          slang_operation_copy(child, &callOper->children[i]);
          child->locals->outer_scope = callOper->children[i].locals;