Don't allow code like: v * '0 1 0' = 3; to actually work...
authorWolfgang Bumiller <blub@speed.at>
Sat, 29 Dec 2012 14:13:54 +0000 (15:13 +0100)
committerWolfgang Bumiller <blub@speed.at>
Sat, 29 Dec 2012 14:13:54 +0000 (15:13 +0100)
ast.c
ast.h
parser.c

diff --git a/ast.c b/ast.c
index ff105cc0dac2bd25700765f0aea427e67a031292..fb86b85e3e5514afb0ed8c8e9faf0ff3a92b65ba 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -570,7 +570,8 @@ ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int fiel
         self->expression.next = ast_shallow_type(ctx, TYPE_FLOAT);
     }
 
-    self->owner = owner;
+    self->rvalue = false;
+    self->owner  = owner;
     ast_propagate_effects(self, owner);
 
     self->field = field;
@@ -2082,7 +2083,10 @@ bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_va
     ir_value *vec;
 
     /* 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) {
         *out = self->expression.outl;
         return true;
diff --git a/ast.h b/ast.h
index b9b2ab875a6df7dcf1f6fd1c1e8ade2bfd93d695..eeba63626da652bd9af021801121646ecfb6f772 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -324,6 +324,7 @@ struct ast_member_s
     ast_expression *owner;
     unsigned int    field;
     const char     *name;
+    bool            rvalue;
 };
 ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int field, const char *name);
 void ast_member_delete(ast_member*);
index c780dc26e1de0e09879c897fe0e60db2c37f2fba..5aa980d5ef0c315e1d3bb6b039ebc159821c5a6f 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -806,6 +806,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                                 ++opts_optimizationcount[OPTIM_VECTOR_COMPONENTS];
                                 out = (ast_expression*)ast_member_new(ctx, exprs[1], 0, NULL);
                                 out->expression.node.keep = false;
+                                ((ast_member*)out)->rvalue = true;
                                 if (vec.x != 1)
                                     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];
                                 out = (ast_expression*)ast_member_new(ctx, exprs[1], 1, NULL);
                                 out->expression.node.keep = false;
+                                ((ast_member*)out)->rvalue = true;
                                 if (vec.y != 1)
                                     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];
                                 out = (ast_expression*)ast_member_new(ctx, exprs[1], 2, NULL);
                                 out->expression.node.keep = false;
+                                ((ast_member*)out)->rvalue = true;
                                 if (vec.z != 1)
                                     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];
                                 out = (ast_expression*)ast_member_new(ctx, exprs[0], 0, NULL);
                                 out->expression.node.keep = false;
+                                ((ast_member*)out)->rvalue = true;
                                 if (vec.x != 1)
                                     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];
                                 out = (ast_expression*)ast_member_new(ctx, exprs[0], 1, NULL);
                                 out->expression.node.keep = false;
+                                ((ast_member*)out)->rvalue = true;
                                 if (vec.y != 1)
                                     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];
                                 out = (ast_expression*)ast_member_new(ctx, exprs[0], 2, NULL);
                                 out->expression.node.keep = false;
+                                ((ast_member*)out)->rvalue = true;
                                 if (vec.z != 1)
                                     out = (ast_expression*)ast_binary_new(ctx, INSTR_MUL_F, out, (ast_expression*)parser_const_float(parser, vec.z));
                             }