Module: wine Branch: master Commit: 237558f6499ba30524fade1c42ffcf6b36db352f URL: http://source.winehq.org/git/wine.git/?a=commit;h=237558f6499ba30524fade1c42...
Author: Matteo Bruni mbruni@codeweavers.com Date: Mon Sep 17 15:32:05 2012 +0200
d3dcompiler: Postincrement/decrement expressions are const.
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;