mesa: glsl: more assignment type checking
Also that const declarations have initializers and that uniforms/samplers can't have initializers.
This commit is contained in:
@@ -2704,6 +2704,62 @@ _slang_is_constant_expr(const slang_operation *oper)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if an assignment of type t1 to t0 is legal.
|
||||
* XXX more cases needed.
|
||||
*/
|
||||
static GLboolean
|
||||
_slang_assignment_compatible(slang_assemble_ctx *A,
|
||||
slang_operation *op0,
|
||||
slang_operation *op1)
|
||||
{
|
||||
slang_typeinfo t0, t1;
|
||||
GLuint sz0, sz1;
|
||||
|
||||
|
||||
slang_typeinfo_construct(&t0);
|
||||
_slang_typeof_operation(A, op0, &t0);
|
||||
|
||||
slang_typeinfo_construct(&t1);
|
||||
_slang_typeof_operation(A, op1, &t1);
|
||||
|
||||
sz0 = _slang_sizeof_type_specifier(&t0.spec);
|
||||
sz1 = _slang_sizeof_type_specifier(&t1.spec);
|
||||
|
||||
#if 1
|
||||
if (sz0 != sz1) {
|
||||
/*printf("assignment size mismatch %u vs %u\n", sz0, sz1);*/
|
||||
return GL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (t0.spec.type == SLANG_SPEC_STRUCT &&
|
||||
t1.spec.type == SLANG_SPEC_STRUCT &&
|
||||
t0.spec._struct->a_name != t1.spec._struct->a_name)
|
||||
return GL_FALSE;
|
||||
|
||||
if (t0.spec.type == SLANG_SPEC_FLOAT &&
|
||||
t1.spec.type == SLANG_SPEC_BOOL)
|
||||
return GL_FALSE;
|
||||
|
||||
#if 0 /* not used just yet - causes problems elsewhere */
|
||||
if (t0.spec.type == SLANG_SPEC_INT &&
|
||||
t1.spec.type == SLANG_SPEC_FLOAT)
|
||||
return GL_FALSE;
|
||||
#endif
|
||||
|
||||
if (t0.spec.type == SLANG_SPEC_BOOL &&
|
||||
t1.spec.type == SLANG_SPEC_FLOAT)
|
||||
return GL_FALSE;
|
||||
|
||||
if (t0.spec.type == SLANG_SPEC_BOOL &&
|
||||
t1.spec.type == SLANG_SPEC_INT)
|
||||
return GL_FALSE;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generate IR tree for a variable declaration.
|
||||
@@ -2717,7 +2773,8 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
|
||||
const char *varName = (char *) oper->a_id;
|
||||
slang_operation *initializer;
|
||||
|
||||
assert(oper->num_children == 0 || oper->num_children == 1);
|
||||
assert(oper->type == SLANG_OPER_VARIABLE_DECL);
|
||||
assert(oper->num_children <= 1);
|
||||
|
||||
v = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE);
|
||||
/*printf("Declare %s at %p\n", varName, (void *) v);*/
|
||||
@@ -2731,6 +2788,8 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
|
||||
#endif
|
||||
|
||||
varDecl = _slang_gen_var_decl(A, v);
|
||||
if (!varDecl)
|
||||
return NULL;
|
||||
|
||||
/* check if the var has an initializer */
|
||||
if (oper->num_children > 0) {
|
||||
@@ -2744,11 +2803,22 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
|
||||
initializer = NULL;
|
||||
}
|
||||
|
||||
if (v->type.qualifier == SLANG_QUAL_CONST && !initializer) {
|
||||
slang_info_log_error(A->log,
|
||||
"const-qualified variable '%s' requires initializer",
|
||||
varName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (initializer) {
|
||||
slang_ir_node *var, *init;
|
||||
|
||||
/* XXX todo: type check/compare var and initializer */
|
||||
|
||||
/* type check/compare var and initializer */
|
||||
if (!_slang_assignment_compatible(A, oper, initializer)) {
|
||||
slang_info_log_error(A->log, "illegal types in assignment");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
var = new_var(A, oper, oper->a_id);
|
||||
if (!var) {
|
||||
@@ -2846,61 +2916,6 @@ _slang_gen_swizzle(slang_ir_node *child, GLuint swizzle)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if an assignment of type t1 to t0 is legal.
|
||||
* XXX more cases needed.
|
||||
*/
|
||||
static GLboolean
|
||||
_slang_assignment_compatible(slang_assemble_ctx *A,
|
||||
slang_operation *op0,
|
||||
slang_operation *op1)
|
||||
{
|
||||
slang_typeinfo t0, t1;
|
||||
GLuint sz0, sz1;
|
||||
|
||||
|
||||
slang_typeinfo_construct(&t0);
|
||||
_slang_typeof_operation(A, op0, &t0);
|
||||
|
||||
slang_typeinfo_construct(&t1);
|
||||
_slang_typeof_operation(A, op1, &t1);
|
||||
|
||||
sz0 = _slang_sizeof_type_specifier(&t0.spec);
|
||||
sz1 = _slang_sizeof_type_specifier(&t1.spec);
|
||||
|
||||
#if 1
|
||||
if (sz0 != sz1) {
|
||||
printf("size mismatch %u vs %u\n", sz0, sz1);
|
||||
return GL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (t0.spec.type == SLANG_SPEC_STRUCT &&
|
||||
t1.spec.type == SLANG_SPEC_STRUCT &&
|
||||
t0.spec._struct->a_name != t1.spec._struct->a_name)
|
||||
return GL_FALSE;
|
||||
|
||||
if (t0.spec.type == SLANG_SPEC_FLOAT &&
|
||||
t1.spec.type == SLANG_SPEC_BOOL)
|
||||
return GL_FALSE;
|
||||
|
||||
if (t0.spec.type == SLANG_SPEC_INT &&
|
||||
t1.spec.type == SLANG_SPEC_FLOAT)
|
||||
return GL_FALSE;
|
||||
|
||||
#if 0 /* not used just yet - causes problems elsewhere */
|
||||
if (t0.spec.type == SLANG_SPEC_BOOL &&
|
||||
t1.spec.type == SLANG_SPEC_FLOAT)
|
||||
return GL_FALSE;
|
||||
|
||||
if (t0.spec.type == SLANG_SPEC_BOOL &&
|
||||
t1.spec.type == SLANG_SPEC_INT)
|
||||
return GL_FALSE;
|
||||
#endif
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate IR tree for an assignment (=).
|
||||
*/
|
||||
@@ -3606,14 +3621,26 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
||||
* store->Index = sampler number (0..7, typically)
|
||||
* store->Size = texture type index (1D, 2D, 3D, cube, etc)
|
||||
*/
|
||||
GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
|
||||
store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex);
|
||||
if (var->initializer) {
|
||||
slang_info_log_error(A->log, "illegal assignment to '%s'", varName);
|
||||
return GL_FALSE;
|
||||
}
|
||||
else {
|
||||
GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
|
||||
store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex);
|
||||
}
|
||||
if (dbg) printf("SAMPLER ");
|
||||
}
|
||||
else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
|
||||
/* Uniform variable */
|
||||
const GLint totalSize = array_size(size, var->array_len);
|
||||
const GLuint swizzle = _slang_var_swizzle(totalSize, 0);
|
||||
|
||||
if (var->initializer) {
|
||||
slang_info_log_error(A->log, "illegal assignment to '%s'", varName);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
if (prog) {
|
||||
/* user-defined uniform */
|
||||
if (datatype == GL_NONE) {
|
||||
|
||||
Reference in New Issue
Block a user