[PATCH 2/3] d3dcompiler: Postincrement/decrement expressions are const.
Matteo Bruni
mbruni at codeweavers.com
Mon Sep 17 08:32:05 CDT 2012
Also check for const expressions used as l-values.
---
dlls/d3dcompiler_43/d3dcompiler_private.h | 1 +
dlls/d3dcompiler_43/hlsl.y | 49 +++++++++++++++++--
dlls/d3dcompiler_43/utils.c | 73 +++++++++++++++++++++++++++++
3 files changed, 118 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 01c31ef..a191529 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -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;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index c003754..7ed50b4 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -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: '='
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index c416060..ad7887a 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -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;
--
1.7.8.6
More information about the wine-patches
mailing list