d3dcompiler: Postincrement/decrement expressions are const.
Also check for const expressions used as l-values.
This commit is contained in:
parent
7cce71a0c3
commit
237558f649
|
@ -1027,6 +1027,7 @@ BOOL add_func_parameter(struct list *list, struct parse_parameter *param,
|
|||
struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class,
|
||||
enum hlsl_base_type base_type, unsigned dimx, unsigned dimy) DECLSPEC_HIDDEN;
|
||||
struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size) DECLSPEC_HIDDEN;
|
||||
struct hlsl_type *clone_hlsl_type(struct hlsl_type *old) DECLSPEC_HIDDEN;
|
||||
struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) DECLSPEC_HIDDEN;
|
||||
BOOL find_function(const char *name) DECLSPEC_HIDDEN;
|
||||
unsigned int components_count_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -1026,20 +1026,38 @@ postfix_expr: primary_expr
|
|||
struct hlsl_ir_node *operands[3];
|
||||
struct source_location loc;
|
||||
|
||||
set_location(&loc, &@2);
|
||||
if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
|
||||
{
|
||||
hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
|
||||
"modifying a const expression");
|
||||
return 1;
|
||||
}
|
||||
operands[0] = $1;
|
||||
operands[1] = operands[2] = NULL;
|
||||
set_location(&loc, &@2);
|
||||
$$ = &new_expr(HLSL_IR_BINOP_POSTINC, operands, &loc)->node;
|
||||
/* Post increment/decrement expressions are considered const */
|
||||
$$->data_type = clone_hlsl_type($$->data_type);
|
||||
$$->data_type->modifiers |= HLSL_MODIFIER_CONST;
|
||||
}
|
||||
| postfix_expr OP_DEC
|
||||
{
|
||||
struct hlsl_ir_node *operands[3];
|
||||
struct source_location loc;
|
||||
|
||||
set_location(&loc, &@2);
|
||||
if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
|
||||
{
|
||||
hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
|
||||
"modifying a const expression");
|
||||
return 1;
|
||||
}
|
||||
operands[0] = $1;
|
||||
operands[1] = operands[2] = NULL;
|
||||
set_location(&loc, &@2);
|
||||
$$ = &new_expr(HLSL_IR_BINOP_POSTDEC, operands, &loc)->node;
|
||||
/* Post increment/decrement expressions are considered const */
|
||||
$$->data_type = clone_hlsl_type($$->data_type);
|
||||
$$->data_type->modifiers |= HLSL_MODIFIER_CONST;
|
||||
}
|
||||
| postfix_expr '.' any_identifier
|
||||
{
|
||||
|
@ -1113,9 +1131,15 @@ unary_expr: postfix_expr
|
|||
struct hlsl_ir_node *operands[3];
|
||||
struct source_location loc;
|
||||
|
||||
set_location(&loc, &@1);
|
||||
if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
|
||||
{
|
||||
hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
|
||||
"modifying a const expression");
|
||||
return 1;
|
||||
}
|
||||
operands[0] = $2;
|
||||
operands[1] = operands[2] = NULL;
|
||||
set_location(&loc, &@1);
|
||||
$$ = &new_expr(HLSL_IR_BINOP_PREINC, operands, &loc)->node;
|
||||
}
|
||||
| OP_DEC unary_expr
|
||||
|
@ -1123,9 +1147,15 @@ unary_expr: postfix_expr
|
|||
struct hlsl_ir_node *operands[3];
|
||||
struct source_location loc;
|
||||
|
||||
set_location(&loc, &@1);
|
||||
if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
|
||||
{
|
||||
hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
|
||||
"modifying a const expression");
|
||||
return 1;
|
||||
}
|
||||
operands[0] = $2;
|
||||
operands[1] = operands[2] = NULL;
|
||||
set_location(&loc, &@1);
|
||||
$$ = &new_expr(HLSL_IR_BINOP_PREDEC, operands, &loc)->node;
|
||||
}
|
||||
| unary_op unary_expr
|
||||
|
@ -1335,10 +1365,19 @@ assignment_expr: conditional_expr
|
|||
}
|
||||
| unary_expr assign_op assignment_expr
|
||||
{
|
||||
struct source_location loc;
|
||||
|
||||
set_location(&loc, &@2);
|
||||
if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
|
||||
{
|
||||
hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
|
||||
"l-value is const");
|
||||
return 1;
|
||||
}
|
||||
$$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
|
||||
if (!$$)
|
||||
return 1;
|
||||
set_location(&$$->loc, &@2);
|
||||
$$->loc = loc;
|
||||
}
|
||||
|
||||
assign_op: '='
|
||||
|
|
|
@ -947,6 +947,79 @@ static BOOL compare_hlsl_types(const struct hlsl_type *t1, const struct hlsl_typ
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
struct hlsl_type *clone_hlsl_type(struct hlsl_type *old)
|
||||
{
|
||||
struct hlsl_type *type;
|
||||
struct hlsl_struct_field *old_field, *field;
|
||||
|
||||
type = d3dcompiler_alloc(sizeof(*type));
|
||||
if (!type)
|
||||
{
|
||||
ERR("Out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
if (old->name)
|
||||
{
|
||||
type->name = d3dcompiler_strdup(old->name);
|
||||
if (!type->name)
|
||||
{
|
||||
d3dcompiler_free(type);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
type->type = old->type;
|
||||
type->base_type = old->base_type;
|
||||
type->dimx = old->dimx;
|
||||
type->dimy = old->dimy;
|
||||
type->modifiers = old->modifiers;
|
||||
type->sampler_dim = old->sampler_dim;
|
||||
switch (old->type)
|
||||
{
|
||||
case HLSL_CLASS_ARRAY:
|
||||
type->e.array.type = old->e.array.type;
|
||||
type->e.array.elements_count = old->e.array.elements_count;
|
||||
break;
|
||||
case HLSL_CLASS_STRUCT:
|
||||
type->e.elements = d3dcompiler_alloc(sizeof(*type->e.elements));
|
||||
if (!type->e.elements)
|
||||
{
|
||||
d3dcompiler_free((void *)type->name);
|
||||
d3dcompiler_free(type);
|
||||
return NULL;
|
||||
}
|
||||
list_init(type->e.elements);
|
||||
LIST_FOR_EACH_ENTRY(old_field, old->e.elements, struct hlsl_struct_field, entry)
|
||||
{
|
||||
field = d3dcompiler_alloc(sizeof(*field));
|
||||
if (!field)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY_SAFE(field, old_field, type->e.elements, struct hlsl_struct_field, entry)
|
||||
{
|
||||
d3dcompiler_free((void *)field->semantic);
|
||||
d3dcompiler_free((void *)field->name);
|
||||
d3dcompiler_free(field);
|
||||
}
|
||||
d3dcompiler_free(type->e.elements);
|
||||
d3dcompiler_free((void *)type->name);
|
||||
d3dcompiler_free(type);
|
||||
return NULL;
|
||||
}
|
||||
field->type = clone_hlsl_type(old_field->type);
|
||||
field->name = d3dcompiler_strdup(old_field->name);
|
||||
if (old_field->semantic)
|
||||
field->semantic = d3dcompiler_strdup(old_field->semantic);
|
||||
field->modifiers = old_field->modifiers;
|
||||
list_add_tail(type->e.elements, &field->entry);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
list_add_tail(&hlsl_ctx.types, &type->entry);
|
||||
return type;
|
||||
}
|
||||
|
||||
static BOOL convertible_data_type(struct hlsl_type *type)
|
||||
{
|
||||
return type->type != HLSL_CLASS_OBJECT;
|
||||
|
|
Loading…
Reference in New Issue