Don't allow code like: v * '0 1 0' = 3; to actually work...

This commit is contained in:
Wolfgang Bumiller 2012-12-29 15:13:54 +01:00
parent fda4f4d027
commit 33be9d4559
3 changed files with 13 additions and 2 deletions

6
ast.c
View file

@ -570,6 +570,7 @@ ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int fiel
self->expression.next = ast_shallow_type(ctx, TYPE_FLOAT); self->expression.next = ast_shallow_type(ctx, TYPE_FLOAT);
} }
self->rvalue = false;
self->owner = owner; self->owner = owner;
ast_propagate_effects(self, owner); ast_propagate_effects(self, owner);
@ -2082,7 +2083,10 @@ bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_va
ir_value *vec; ir_value *vec;
/* in QC this is always an lvalue */ /* in QC this is always an lvalue */
(void)lvalue; if (lvalue && self->rvalue) {
compile_error(ast_ctx(self), "not an l-value (member access)");
return false;
}
if (self->expression.outl) { if (self->expression.outl) {
*out = self->expression.outl; *out = self->expression.outl;
return true; return true;

1
ast.h
View file

@ -324,6 +324,7 @@ struct ast_member_s
ast_expression *owner; ast_expression *owner;
unsigned int field; unsigned int field;
const char *name; const char *name;
bool rvalue;
}; };
ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int field, const char *name); ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int field, const char *name);
void ast_member_delete(ast_member*); void ast_member_delete(ast_member*);

View file

@ -806,6 +806,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS]; ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[1], 0, NULL); out = (ast_expression*)ast_member_new(ctx, exprs[1], 0, NULL);
out->expression.node.keep = false; out->expression.node.keep = false;
((ast_member*)out)->rvalue = true;
if (vec.x != 1) if (vec.x != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.x), out); out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.x), out);
} }
@ -813,6 +814,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS]; ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[1], 1, NULL); out = (ast_expression*)ast_member_new(ctx, exprs[1], 1, NULL);
out->expression.node.keep = false; out->expression.node.keep = false;
((ast_member*)out)->rvalue = true;
if (vec.y != 1) if (vec.y != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.y), out); out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.y), out);
} }
@ -820,6 +822,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS]; ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[1], 2, NULL); out = (ast_expression*)ast_member_new(ctx, exprs[1], 2, NULL);
out->expression.node.keep = false; out->expression.node.keep = false;
((ast_member*)out)->rvalue = true;
if (vec.z != 1) if (vec.z != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.z), out); out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, (ast_expression*)parser_const_float(parser, vec.z), out);
} }
@ -832,6 +835,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS]; ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, NULL); out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, NULL);
out->expression.node.keep = false; out->expression.node.keep = false;
((ast_member*)out)->rvalue = true;
if (vec.x != 1) if (vec.x != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.x)); out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.x));
} }
@ -839,6 +843,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS]; ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, NULL); out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, NULL);
out->expression.node.keep = false; out->expression.node.keep = false;
((ast_member*)out)->rvalue = true;
if (vec.y != 1) if (vec.y != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.y)); out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.y));
} }
@ -846,6 +851,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS]; ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, NULL); out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, NULL);
out->expression.node.keep = false; out->expression.node.keep = false;
((ast_member*)out)->rvalue = true;
if (vec.z != 1) if (vec.z != 1)
out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.z)); out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.z));
} }