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>
if (!idx->codegen(func, false, &iridx))
return false;
}
if (!idx->codegen(func, false, &iridx))
return false;
}
if (!m_dest->codegen(func, false, &leftr))
return false;
if (!m_dest->codegen(func, false, &leftr))
return false;
else
m_outr = *out;
return (*out != nullptr);
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))
{
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);
return false;
}
*out = vec->vectorMember(m_field);
+ 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);
}
return (*out != nullptr);
}
--- /dev/null
+I: vecfields.qc
+D: vector field member accesses
+T: -fail
+C: -std=gmqcc -fftepp -DBROKEN_ACCESS
e.v1 = '1 2 3';
print(ftos(set(e, 42)), " => ");
print(vtos(e.v1), "\n");
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