summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-08-06 11:15:55 -0600
committerBrian Paul <brian.paul@tungstengraphics.com>2008-08-06 11:15:55 -0600
commitb9be69b85e8955fa9f773a65e7c3de5c4bb6e507 (patch)
treec84546a8f55374233f305b96d7010208c6a5cae5
parent93ed8f9fc9edddff62bbe4720c0b9029a1f8b6f5 (diff)
mesa: glsl: more assignment type checking
Also that const declarations have initializers and that uniforms/samplers can't have initializers.
-rw-r--r--src/mesa/shader/slang/slang_codegen.c147
1 files changed, 87 insertions, 60 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 142e240802..edb060a23f 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -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) {
@@ -2847,61 +2917,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 (=).
*/
static slang_ir_node *
@@ -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) {