glsl: Improve error message when read-only vars are written
authorChad Versace <chad.versace@intel.com>
Fri, 21 Jan 2011 21:44:08 +0000 (13:44 -0800)
committerChad Versace <chad.versace@intel.com>
Fri, 21 Jan 2011 22:06:28 +0000 (14:06 -0800)
Improves the cases when:
* an explicit assignment references the read-only variable
* an 'out' or 'inout' function parameter references the read-only variable

src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp

index 6ecf779..3e5e345 100644 (file)
@@ -145,12 +145,27 @@ match_function_by_name(exec_list *instructions, const char *name,
 
         if ((formal->mode == ir_var_out)
             || (formal->mode == ir_var_inout)) {
-           if (! actual->is_lvalue()) {
-              /* FINISHME: Log a better diagnostic here.  There is no way
-               * FINISHME: to tell the user which parameter is invalid.
-               */
-              _mesa_glsl_error(loc, state, "`%s' parameter is not lvalue",
-                               (formal->mode == ir_var_out) ? "out" : "inout");
+           const char *mode = NULL;
+           switch (formal->mode) {
+           case ir_var_out:   mode = "out";   break;
+           case ir_var_inout: mode = "inout"; break;
+           default:           assert(false);  break;
+           }
+            /* FIXME: 'loc' is incorrect (as of 2011-01-21). It is always
+             * FIXME: 0:0(0).
+             */
+           if (actual->variable_referenced()
+               && actual->variable_referenced()->read_only) {
+              _mesa_glsl_error(loc, state,
+                               "function parameter '%s %s' references the "
+                               "read-only variable '%s'",
+                               mode, formal->name,
+                               actual->variable_referenced()->name);
+
+           } else if (!actual->is_lvalue()) {
+               _mesa_glsl_error(loc, state,
+                                "function parameter '%s %s' is not an lvalue",
+                                mode, formal->name);
            }
         }
 
index dfb016c..1bca3ec 100644 (file)
@@ -639,7 +639,14 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
    bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
 
    if (!error_emitted) {
-      if (!lhs->is_lvalue()) {
+      if (lhs->variable_referenced() != NULL
+          && lhs->variable_referenced()->read_only) {
+         _mesa_glsl_error(&lhs_loc, state,
+                          "assignment to read-only variable '%s'",
+                          lhs->variable_referenced()->name);
+         error_emitted = true;
+
+      } else if (!lhs->is_lvalue()) {
         _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment");
         error_emitted = true;
       }