catch broken vector member access

These kinds of expressions currently cannot be handled
without pionter support in the qcvm without scanning the
ast from within ast_member::codegen for an assignments as
seen in the added test case.

This change makes code like that return a pointer type which
will cause an error that we did not get a vector or field
back. With pointer support this pointer could actually be
used instead.

So at least it shouldn't silently produce broken code
anymore.

Signed-off-by: Wolfgang Bumiller <wry.git@bumiller.com>
This commit is contained in:
Wolfgang Bumiller 2018-01-14 10:58:29 +01:00
parent f84c8ea629
commit 97a74eb677
3 changed files with 22 additions and 4 deletions

18
ast.cpp
View file

@ -1932,6 +1932,7 @@ bool ast_binstore::codegen(ast_function *func, bool lvalue, ir_value **out)
if (!idx->codegen(func, false, &iridx))
return false;
}
if (!m_dest->codegen(func, false, &leftr))
return false;
@ -2153,19 +2154,28 @@ bool ast_member::codegen(ast_function *func, bool lvalue, ir_value **out)
else
m_outr = *out;
return (*out != nullptr);
} else {
if (!m_owner->codegen(func, false, &vec))
return false;
}
// Vector member access
if (!m_owner->codegen(func, lvalue, &vec))
return false;
if (vec->m_vtype != TYPE_VECTOR &&
!(vec->m_vtype == TYPE_FIELD && m_owner->m_next->m_vtype == TYPE_VECTOR))
{
compile_error(m_context, "vector member produced neither vector nor field");
return false;
}
*out = vec->vectorMember(m_field);
m_outl = *out;
if (!*out) {
compile_error(m_context, "internal error: failed to create vector member access");
return false;
}
if (lvalue)
m_outl = *out;
else
m_outr = *out;
return (*out != nullptr);
}

View file

@ -0,0 +1,4 @@
I: vecfields.qc
D: vector field member accesses
T: -fail
C: -std=gmqcc -fftepp -DBROKEN_ACCESS

View file

@ -10,4 +10,8 @@ void main() {
e.v1 = '1 2 3';
print(ftos(set(e, 42)), " => ");
print(vtos(e.v1), "\n");
#ifdef BROKEN_ACCESS
(e.v1 = '0 0 0').x += 1;
#endif
}