mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-03 08:40:28 +01:00
glsl: Throw an error when faced with a duplicated switch() case label.
The error message I chose matches gcc's error. Fixes piglit
switch-case-duplicated.vert.
NOTE: This is a candidate for the 8.0 branch.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
(cherry picked from commit 140632190c)
This commit is contained in:
parent
d799a7b585
commit
83075bd0fe
2 changed files with 27 additions and 0 deletions
|
|
@ -54,6 +54,7 @@
|
|||
#include "glsl_parser_extras.h"
|
||||
#include "ast.h"
|
||||
#include "glsl_types.h"
|
||||
#include "program/hash_table.h"
|
||||
#include "ir.h"
|
||||
|
||||
void
|
||||
|
|
@ -3534,6 +3535,8 @@ ast_switch_statement::hir(exec_list *instructions,
|
|||
|
||||
state->switch_state.is_switch_innermost = true;
|
||||
state->switch_state.switch_nesting_ast = this;
|
||||
state->switch_state.labels_ht = hash_table_ctor(0, hash_table_pointer_hash,
|
||||
hash_table_pointer_compare);
|
||||
|
||||
/* Initalize is_fallthru state to false.
|
||||
*/
|
||||
|
|
@ -3572,6 +3575,8 @@ ast_switch_statement::hir(exec_list *instructions,
|
|||
*/
|
||||
body->hir(instructions, state);
|
||||
|
||||
hash_table_dtor(state->switch_state.labels_ht);
|
||||
|
||||
state->switch_state = saved;
|
||||
|
||||
/* Switch statements do not have r-values.
|
||||
|
|
@ -3709,6 +3714,24 @@ ast_switch_statement::hir(exec_list *instructions,
|
|||
|
||||
/* Stuff a dummy value in to allow processing to continue. */
|
||||
label_const = new(ctx) ir_constant(0);
|
||||
} else {
|
||||
ast_expression *previous_label = (ast_expression *)
|
||||
hash_table_find(state->switch_state.labels_ht,
|
||||
(void *)(uintptr_t)label_const->value.u[0]);
|
||||
|
||||
if (previous_label) {
|
||||
YYLTYPE loc = this->test_value->get_location();
|
||||
_mesa_glsl_error(& loc, state,
|
||||
"duplicate case value");
|
||||
|
||||
loc = previous_label->get_location();
|
||||
_mesa_glsl_error(& loc, state,
|
||||
"this is the previous case label");
|
||||
} else {
|
||||
hash_table_insert(state->switch_state.labels_ht,
|
||||
this->test_value,
|
||||
(void *)(uintptr_t)label_const->value.u[0]);
|
||||
}
|
||||
}
|
||||
|
||||
ir_dereference_variable *deref_test_var =
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ struct glsl_switch_state {
|
|||
ir_variable *is_fallthru_var;
|
||||
ir_variable *is_break_var;
|
||||
class ast_switch_statement *switch_nesting_ast;
|
||||
|
||||
/** Table of constant values already used in case labels */
|
||||
struct hash_table *labels_ht;
|
||||
|
||||
bool is_switch_innermost; // if switch stmt is closest to break, ...
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue