summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/ast_to_hir.cpp39
1 files changed, 24 insertions, 15 deletions
diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
index 4323ec32264..a8a7cdbf2c1 100644
--- a/src/compiler/glsl/ast_to_hir.cpp
+++ b/src/compiler/glsl/ast_to_hir.cpp
@@ -6690,12 +6690,14 @@ ast_case_label::hir(exec_list *instructions,
}
}
- ir_dereference_variable *deref_test_var =
- new(ctx) ir_dereference_variable(state->switch_state.test_var);
+ /* Create an r-value version of the ir_constant label here (after we may
+ * have created a fake one in error cases) that can be passed to
+ * apply_implicit_conversion below.
+ */
+ ir_rvalue *label = label_const;
- ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal,
- label_const,
- deref_test_var);
+ ir_rvalue *deref_test_var =
+ new(ctx) ir_dereference_variable(state->switch_state.test_var);
/*
* From GLSL 4.40 specification section 6.2 ("Selection"):
@@ -6708,10 +6710,10 @@ ast_case_label::hir(exec_list *instructions,
* uint (see section 4.1.10 “Implicit Conversions”) before the compare
* is done."
*/
- if (label_const->type != state->switch_state.test_var->type) {
+ if (label->type != state->switch_state.test_var->type) {
YYLTYPE loc = this->test_value->get_location();
- const glsl_type *type_a = label_const->type;
+ const glsl_type *type_a = label->type;
const glsl_type *type_b = state->switch_state.test_var->type;
/* Check if int->uint implicit conversion is supported. */
@@ -6728,17 +6730,28 @@ ast_case_label::hir(exec_list *instructions,
/* Conversion of the case label. */
if (type_a->base_type == GLSL_TYPE_INT) {
if (!apply_implicit_conversion(glsl_type::uint_type,
- test_cond->operands[0], state))
+ label, state))
_mesa_glsl_error(&loc, state, "implicit type conversion error");
} else {
/* Conversion of the init-expression value. */
if (!apply_implicit_conversion(glsl_type::uint_type,
- test_cond->operands[1], state))
+ deref_test_var, state))
_mesa_glsl_error(&loc, state, "implicit type conversion error");
}
}
+
+ /* If the implicit conversion was allowed, the types will already be
+ * the same. If the implicit conversion wasn't allowed, smash the
+ * type of the label anyway. This will prevent the expression
+ * constructor (below) from failing an assertion.
+ */
+ label->type = deref_test_var->type;
}
+ ir_expression *test_cond = new(ctx) ir_expression(ir_binop_equal,
+ label,
+ deref_test_var);
+
ir_assignment *set_fallthru_on_test =
new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond);
@@ -6757,14 +6770,10 @@ ast_case_label::hir(exec_list *instructions,
/* Set fallthru condition on 'run_default' bool. */
ir_dereference_variable *deref_run_default =
new(ctx) ir_dereference_variable(state->switch_state.run_default);
- ir_rvalue *const cond_true = new(ctx) ir_constant(true);
- ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal,
- cond_true,
- deref_run_default);
- /* Set falltrhu state. */
+ /* Set fallthru state. */
ir_assignment *set_fallthru =
- new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond);
+ new(ctx) ir_assignment(deref_fallthru_var, true_val, deref_run_default);
instructions->push_tail(set_fallthru);
}