glsl: Track variable usage, use that to enforce semantics
In particular, variables cannot be redeclared invariant after being used. Fixes piglit test invariant-05.vert and bugzilla #29164. NOTE: This is a candidate for the 7.9 and 7.10 branches.
This commit is contained in:
@@ -1623,6 +1623,7 @@ ast_expression::hir(exec_list *instructions,
|
||||
result = new(ctx) ir_dereference_variable(var);
|
||||
|
||||
if (var != NULL) {
|
||||
var->used = true;
|
||||
type = result->type;
|
||||
} else {
|
||||
_mesa_glsl_error(& loc, state, "`%s' undeclared",
|
||||
@@ -1797,8 +1798,16 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
|
||||
struct _mesa_glsl_parse_state *state,
|
||||
YYLTYPE *loc)
|
||||
{
|
||||
if (qual->flags.q.invariant)
|
||||
if (qual->flags.q.invariant) {
|
||||
if (var->used) {
|
||||
_mesa_glsl_error(loc, state,
|
||||
"variable `%s' may not be redeclared "
|
||||
"`invariant' after being used",
|
||||
var->name);
|
||||
} else {
|
||||
var->invariant = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* FINISHME: Mark 'in' variables at global scope as read-only. */
|
||||
if (qual->flags.q.constant || qual->flags.q.attribute
|
||||
@@ -2005,6 +2014,11 @@ ast_declarator_list::hir(exec_list *instructions,
|
||||
_mesa_glsl_error(& loc, state,
|
||||
"`%s' cannot be marked invariant, fragment shader "
|
||||
"inputs only\n", decl->identifier);
|
||||
} else if (earlier->used) {
|
||||
_mesa_glsl_error(& loc, state,
|
||||
"variable `%s' may not be redeclared "
|
||||
"`invariant' after being used",
|
||||
earlier->name);
|
||||
} else {
|
||||
earlier->invariant = true;
|
||||
}
|
||||
|
@@ -1325,6 +1325,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
|
||||
this->constant_value = NULL;
|
||||
this->origin_upper_left = false;
|
||||
this->pixel_center_integer = false;
|
||||
this->used = false;
|
||||
|
||||
if (type && type->base_type == GLSL_TYPE_SAMPLER)
|
||||
this->read_only = true;
|
||||
|
@@ -294,6 +294,15 @@ public:
|
||||
unsigned centroid:1;
|
||||
unsigned invariant:1;
|
||||
|
||||
/**
|
||||
* Has this variable been used for reading or writing?
|
||||
*
|
||||
* Several GLSL semantic checks require knowledge of whether or not a
|
||||
* variable has been used. For example, it is an error to redeclare a
|
||||
* variable as invariant after it has been used.
|
||||
*/
|
||||
unsigned used:1;
|
||||
|
||||
/**
|
||||
* Storage class of the variable.
|
||||
*
|
||||
|
Reference in New Issue
Block a user