glsl: Inherrit type of declared variable from initializer after processing assignment
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 10 Dec 2010 23:48:15 +0000 (15:48 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Sat, 11 Dec 2010 01:52:35 +0000 (17:52 -0800)
do_assignment may apply implicit conversions to coerce the base type
of initializer to the base type of the variable being declared.  Fixes
piglit test glsl-implicit-conversion-02 (bugzilla #32287).  This
probably also fixes bugzilla #32273.

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

src/glsl/ast_to_hir.cpp

index 75ba3a9bafa704d428b34b72d7b0d0017ff2563e..741cd19e9d3f4a4848f82af1f9c60a2afefaf00f 100644 (file)
@@ -2239,6 +2239,17 @@ ast_declarator_list::hir(exec_list *instructions,
            if (this->type->qualifier.flags.q.constant)
               var->read_only = false;
 
+           /* Never emit code to initialize a uniform.
+            */
+           const glsl_type *initializer_type;
+           if (!this->type->qualifier.flags.q.uniform) {
+              result = do_assignment(&initializer_instructions, state,
+                                     lhs, rhs,
+                                     this->get_location());
+              initializer_type = result->type;
+           } else
+              initializer_type = rhs->type;
+
            /* If the declared variable is an unsized array, it must inherrit
             * its full type from the initializer.  A declaration such as
             *
@@ -2253,16 +2264,14 @@ ast_declarator_list::hir(exec_list *instructions,
             *
             * If the declared variable is not an array, the types must
             * already match exactly.  As a result, the type assignment
-            * here can be done unconditionally.
+            * here can be done unconditionally.  For non-uniforms the call
+            * to do_assignment can change the type of the initializer (via
+            * the implicit conversion rules).  For uniforms the initializer
+            * must be a constant expression, and the type of that expression
+            * was validated above.
             */
-           var->type = rhs->type;
+           var->type = initializer_type;
 
-           /* Never emit code to initialize a uniform.
-            */
-           if (!this->type->qualifier.flags.q.uniform)
-              result = do_assignment(&initializer_instructions, state,
-                                     lhs, rhs,
-                                     this->get_location());
            var->read_only = temp;
         }
       }