[PATCH 4/5] d3dcompiler: Verify a returned value against the function's type and cast it if necessary.

Zebediah Figura z.figura12 at gmail.com
Sun Mar 1 22:55:26 CST 2020


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/d3dcompiler_43/d3dcompiler_private.h |  3 +++
 dlls/d3dcompiler_43/hlsl.y                | 24 ++++++++++++++++-------
 dlls/d3dcompiler_43/tests/hlsl_d3d9.c     |  2 +-
 dlls/d3dcompiler_43/utils.c               |  2 +-
 4 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 22cc41db56a..ab712c8d963 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -1046,6 +1046,7 @@ struct hlsl_parse_ctx
 
     struct list types;
     struct wine_rb_tree functions;
+    const struct hlsl_ir_function_decl *cur_function;
 
     enum hlsl_matrix_majority matrix_majority;
 };
@@ -1138,6 +1139,8 @@ struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **ope
         struct source_location *loc) DECLSPEC_HIDDEN;
 struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type,
 	struct source_location *loc) DECLSPEC_HIDDEN;
+struct hlsl_ir_node *implicit_conversion(struct hlsl_ir_node *node, struct hlsl_type *type,
+        struct source_location *loc) DECLSPEC_HIDDEN;
 struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var) DECLSPEC_HIDDEN;
 struct hlsl_ir_deref *new_record_deref(struct hlsl_ir_node *record, struct hlsl_struct_field *field) DECLSPEC_HIDDEN;
 struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *left, enum parse_assign_op assign_op,
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 0f9676df16e..34adab2855b 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -492,13 +492,22 @@ static struct hlsl_ir_jump *new_return(struct hlsl_ir_node *value, struct source
     jump->node.type = HLSL_IR_JUMP;
     jump->node.loc = loc;
     jump->type = HLSL_IR_JUMP_RETURN;
-    jump->node.data_type = value ? value->data_type
-            : new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1);
-    jump->return_value = value;
-
-    FIXME("Check for valued return on void function.\n");
-    FIXME("Implicit conversion to the return type if needed, "
-            "error out if conversion not possible.\n");
+    jump->node.data_type = hlsl_ctx.cur_function->return_type;
+    if (value)
+    {
+        if (!(jump->return_value = implicit_conversion(value, jump->node.data_type, &loc)))
+        {
+            d3dcompiler_free(jump);
+            return NULL;
+        }
+    }
+    else if (jump->node.data_type->base_type != HLSL_TYPE_VOID)
+    {
+        hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
+                "non-void function must return a value");
+        d3dcompiler_free(jump);
+        return NULL;
+    }
 
     return jump;
 }
@@ -1336,6 +1345,7 @@ func_prototype:           var_modifiers type var_identifier '(' parameters ')' c
                                 $$.name = $3;
                                 $$.decl->semantic = $7.semantic;
                                 set_location(&$$.decl->loc, &@3);
+                                hlsl_ctx.cur_function = $$.decl;
                             }
 
 compound_statement:       '{' '}'
diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c
index f1ce5dc5bca..c673e2be327 100644
--- a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c
+++ b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c
@@ -730,7 +730,7 @@ static void test_fail(void)
             compiled = errors = NULL;
             hr = ppD3DCompile(tests[i], strlen(tests[i]), NULL, NULL, NULL, "test", targets[j], 0, 0, &compiled, &errors);
             todo_wine ok(hr == E_FAIL, "Test %u, target %s, got unexpected hr %#x.\n", i, targets[j], hr);
-            todo_wine_if (i == 1 || i >= 7) ok(!!errors, "Test %u, target %s, expected non-NULL error blob.\n", i, targets[j]);
+            todo_wine_if (i == 1) ok(!!errors, "Test %u, target %s, expected non-NULL error blob.\n", i, targets[j]);
             ok(!compiled, "Test %u, target %s, expected no compiled shader blob.\n", i, targets[j]);
             if (errors)
                 ID3D10Blob_Release(errors);
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 65f5ead333d..28ec47423ab 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -1275,7 +1275,7 @@ static struct hlsl_type *expr_common_type(struct hlsl_type *t1, struct hlsl_type
     return new_hlsl_type(NULL, type, base, dimx, dimy);
 }
 
-static struct hlsl_ir_node *implicit_conversion(struct hlsl_ir_node *node, struct hlsl_type *dst_type,
+struct hlsl_ir_node *implicit_conversion(struct hlsl_ir_node *node, struct hlsl_type *dst_type,
         struct source_location *loc)
 {
     struct hlsl_type *src_type = node->data_type;
-- 
2.25.1




More information about the wine-devel mailing list