[Mesa-dev] [PATCH 5/6] glsl: Throw an error when faced with a duplicated switch() case label.
Eric Anholt
eric at anholt.net
Mon Jan 30 09:58:06 PST 2012
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.
---
src/glsl/ast_to_hir.cpp | 23 +++++++++++++++++++++++
src/glsl/glsl_parser_extras.h | 4 ++++
2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 28aff39..4f328ad 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -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 =
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 35d1e3a..d5d5101 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -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, ...
};
--
1.7.7.3
More information about the mesa-dev
mailing list