glsl: Throw the required error when a case label is a non-constant.
authorEric Anholt <eric@anholt.net>
Sat, 28 Jan 2012 19:43:22 +0000 (11:43 -0800)
committerEric Anholt <eric@anholt.net>
Fri, 3 Feb 2012 10:06:54 +0000 (11:06 +0100)
It's not quite spelled out in the spec text, but the grammar indicates
that only constant values are allowed as switch() case labels (and
only constant values make sense, anyway).

Fixes piglit glsl-1.30/compiler/switch-statement/switch-case-uniform-int.vert.

NOTE: This is a candidate for the 8.0 branch.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/ast_to_hir.cpp

index 25ccdab27c0e96f136d1444b675ef3a4e0b97652..28aff397757aa483573d97fc1478b236376c8c97 100644 (file)
@@ -3697,14 +3697,26 @@ ast_switch_statement::hir(exec_list *instructions,
        /* Conditionally set fallthru state based on
         * comparison of cached test expression value to case label.
         */
-       ir_rvalue *const test_val = this->test_value->hir(instructions, state);
+       ir_rvalue *const label_rval = this->test_value->hir(instructions, state);
+       ir_constant *label_const = label_rval->constant_expression_value();
+
+       if (!label_const) {
+          YYLTYPE loc = this->test_value->get_location();
+
+          _mesa_glsl_error(& loc, state,
+                           "switch statement case label must be a "
+                           "constant expression");
+
+          /* Stuff a dummy value in to allow processing to continue. */
+          label_const = new(ctx) ir_constant(0);
+       }
 
        ir_dereference_variable *deref_test_var =
           new(ctx) ir_dereference_variable(state->switch_state.test_var);
 
        ir_rvalue *const test_cond = new(ctx) ir_expression(ir_binop_all_equal,
                                                            glsl_type::bool_type,
-                                                           test_val,
+                                                           label_const,
                                                            deref_test_var);
 
        ir_assignment *set_fallthru_on_test =