Mesa (7.9): glsl: Track variable usage, use that to enforce semantics

Ian Romanick idr at kemper.freedesktop.org
Wed Jan 26 00:51:34 UTC 2011


Module: Mesa
Branch: 7.9
Commit: 48e81e3b9eb8b880cd702a4ca3237101e3bc6f2d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=48e81e3b9eb8b880cd702a4ca3237101e3bc6f2d

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Fri Jan  7 18:34:58 2011 -0800

glsl: Track variable usage, use that to enforce semantics

In particular, variables cannot be redeclared invariant after being
used.

Fixes piglit test invariant-05.vert and bugzilla #29164.

NOTE: This is a candidate for the 7.9 and 7.10 branches.

(cherry picked from commit bd33055ef4b6dd18d6247ff7d9e47496ff4acc51)

---

 src/glsl/ast_to_hir.cpp |   18 ++++++++++++++++--
 src/glsl/ir.cpp         |    1 +
 src/glsl/ir.h           |    9 +++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index f1fc6e6..9a9289d 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -1465,6 +1465,7 @@ ast_expression::hir(exec_list *instructions,
       result = new(ctx) ir_dereference_variable(var);
 
       if (var != NULL) {
+	 var->used = true;
 	 type = result->type;
       } else {
 	 _mesa_glsl_error(& loc, state, "`%s' undeclared",
@@ -1639,8 +1640,16 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
 				 struct _mesa_glsl_parse_state *state,
 				 YYLTYPE *loc)
 {
-   if (qual->invariant)
-      var->invariant = 1;
+   if (qual->invariant) {
+      if (var->used) {
+	 _mesa_glsl_error(loc, state,
+			  "variable `%s' may not be redeclared "
+			  "`invariant' after being used",
+			  var->name);
+      } else {
+	 var->invariant = 1;
+      }
+   }
 
    /* FINISHME: Mark 'in' variables at global scope as read-only. */
    if (qual->constant || qual->attribute || qual->uniform
@@ -1786,6 +1795,11 @@ ast_declarator_list::hir(exec_list *instructions,
 	    _mesa_glsl_error(& loc, state,
 			     "`%s' cannot be marked invariant, fragment shader "
 			     "inputs only\n", decl->identifier);
+	 } else if (earlier->used) {
+	    _mesa_glsl_error(& loc, state,
+			     "variable `%s' may not be redeclared "
+			     "`invariant' after being used",
+			     earlier->name);
 	 } else {
 	    earlier->invariant = true;
 	 }
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 7064fed..919be13 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1124,6 +1124,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
    this->constant_value = NULL;
    this->origin_upper_left = false;
    this->pixel_center_integer = false;
+   this->used = false;
 
    if (type && type->base_type == GLSL_TYPE_SAMPLER)
       this->read_only = true;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 0a520b4..e002cc9 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -260,6 +260,15 @@ public:
    unsigned invariant:1;
 
    /**
+    * Has this variable been used for reading or writing?
+    *
+    * Several GLSL semantic checks require knowledge of whether or not a
+    * variable has been used.  For example, it is an error to redeclare a
+    * variable as invariant after it has been used.
+    */
+   unsigned used:1;
+
+   /**
     * Storage class of the variable.
     *
     * \sa ir_variable_mode




More information about the mesa-commit mailing list