d3dcompiler: Ensure that the lhs of an assignment is reducible to a variable.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2020-03-15 16:25:13 -05:00 committed by Alexandre Julliard
parent 18b8393ff9
commit aaa625217b
1 changed files with 29 additions and 0 deletions

View File

@ -1456,6 +1456,29 @@ static unsigned int invert_swizzle(unsigned int *swizzle, unsigned int writemask
return new_writemask; return new_writemask;
} }
static BOOL validate_lhs_deref(const struct hlsl_ir_node *lhs)
{
struct hlsl_ir_deref *deref;
if (lhs->type != HLSL_IR_DEREF)
{
hlsl_report_message(lhs->loc, HLSL_LEVEL_ERROR, "invalid lvalue");
return FALSE;
}
deref = deref_from_node(lhs);
if (deref->src.type == HLSL_IR_DEREF_VAR)
return TRUE;
if (deref->src.type == HLSL_IR_DEREF_ARRAY)
return validate_lhs_deref(deref->src.v.array.array);
if (deref->src.type == HLSL_IR_DEREF_RECORD)
return validate_lhs_deref(deref->src.v.record.record);
assert(0);
return FALSE;
}
struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *lhs, enum parse_assign_op assign_op, struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *lhs, enum parse_assign_op assign_op,
struct hlsl_ir_node *rhs) struct hlsl_ir_node *rhs)
{ {
@ -1509,6 +1532,12 @@ struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *lhs, enum parse_assign
lhs = lhs_inner; lhs = lhs_inner;
} }
if (!validate_lhs_deref(lhs))
{
d3dcompiler_free(assign);
return NULL;
}
TRACE("Creating proper assignment expression.\n"); TRACE("Creating proper assignment expression.\n");
if (writemask == BWRITERSP_WRITEMASK_ALL) if (writemask == BWRITERSP_WRITEMASK_ALL)
type = lhs->data_type; type = lhs->data_type;