[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