summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2013-09-28 07:45:00 -0700
committerPaul Berry <[email protected]>2013-10-10 14:27:35 -0700
commitfc2330b0be3d8461abc0a1a12a40df2c0bf831b8 (patch)
treefcef80f509d210dad9c7ac16f38039cc0db11257 /src
parent1b4a7378e993bb00426c79e5b7433b48b50a9090 (diff)
glsl: Catch redeclaration of interface block instance names at compile time.
From section 4.1.9 (Arrays) of the GLSL 4.40 spec (as of revision 7): However, unless noted otherwise, blocks cannot be redeclared; an unsized array in a user-declared block cannot be sized through redeclaration. The only place where the spec notes that interface blocks can be redeclared is to allow for redeclaration of built-in interface blocks such as gl_PerVertex. Therefore, user-defined interface blocks can never be redeclared. This is a clarification of previous intent (see Khronos bug 10659). We were already preventing interface block redeclaration using the same block name at compile time, but we weren't preventing interface block redeclaration using the same instance name (and different block names) at compile time. And we weren't preventing an instance name from conflicting with a previously-declared ordinary variable. In practice the problem would be caught at link time, but only because of a coincidence: since ast_interface_block::hir() wasn't doing any checking to see if the instance name already existed in the shader, it was creating a second ir_variable in the shader having the same name but a different type. Coincidentally, when the linker checked for intrastage consistency of global variable declarations, it treated the two declarations from the same shader as a conflict, so it reported a link error. But it seems dangerous to rely on that linker behaviour to catch illegal redeclarations that really ought to be detected at compile time. Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/glsl/ast_to_hir.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 2e73c4f041d..3c788de6f53 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -4813,8 +4813,14 @@ ast_interface_block::hir(exec_list *instructions,
var->init_interface_type(block_type);
if (state->target == geometry_shader && var_mode == ir_var_shader_in)
handle_geometry_shader_input_decl(state, loc, var);
- state->symbols->add_variable(var);
- instructions->push_tail(var);
+
+ if (state->symbols->get_variable(this->instance_name)) {
+ _mesa_glsl_error(&loc, state, "`%s' redeclared", this->instance_name);
+ delete var;
+ } else {
+ state->symbols->add_variable(var);
+ instructions->push_tail(var);
+ }
} else {
/* In order to have an array size, the block must also be declared with
* an instane name.