[PATCH vkd3d 4/5] vkd3d-shader/hlsl: Return false from hlsl_offset_from_deref() if the offset falls out of bounds.

Giovanni Mascellani gmascellani at codeweavers.com
Thu Feb 17 07:49:28 CST 2022


Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
Though maybe the error message "Dereference is out of array bounds." is 
not completely appropriate, as it also applies to types that are not 
arrays, right?

Thanks, Giovanni.


Il 16/02/22 06:29, Zebediah Figura ha scritto:
> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
> ---
>   libs/vkd3d-shader/hlsl.h                 |  2 +-
>   libs/vkd3d-shader/hlsl_codegen.c         | 25 ++++++++++++++++--------
>   libs/vkd3d-shader/vkd3d_shader_private.h |  1 +
>   3 files changed, 19 insertions(+), 9 deletions(-)
> 
> diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
> index 3a69165e..9b1c9ad3 100644
> --- a/libs/vkd3d-shader/hlsl.h
> +++ b/libs/vkd3d-shader/hlsl.h
> @@ -788,7 +788,7 @@ unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second);
>   unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask);
>   unsigned int hlsl_swizzle_from_writemask(unsigned int writemask);
>   
> -bool hlsl_offset_from_deref(const struct hlsl_deref *deref, unsigned int *offset);
> +bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset);
>   unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl_deref *deref);
>   struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
>           const struct hlsl_type *type);
> diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
> index 20d4ffe9..25f038d4 100644
> --- a/libs/vkd3d-shader/hlsl_codegen.c
> +++ b/libs/vkd3d-shader/hlsl_codegen.c
> @@ -362,15 +362,16 @@ static void copy_propagation_set_value(struct copy_propagation_var_def *var_def,
>       }
>   }
>   
> -static struct hlsl_ir_node *copy_propagation_compute_replacement(const struct copy_propagation_state *state,
> -        const struct hlsl_deref *deref, unsigned int count, unsigned int *swizzle)
> +static struct hlsl_ir_node *copy_propagation_compute_replacement(struct hlsl_ctx *ctx,
> +        const struct copy_propagation_state *state, const struct hlsl_deref *deref,
> +        unsigned int count, unsigned int *swizzle)
>   {
>       const struct hlsl_ir_var *var = deref->var;
>       struct copy_propagation_var_def *var_def;
>       struct hlsl_ir_node *node = NULL;
>       unsigned int offset, i;
>   
> -    if (!hlsl_offset_from_deref(deref, &offset))
> +    if (!hlsl_offset_from_deref(ctx, deref, &offset))
>           return NULL;
>   
>       if (!(var_def = copy_propagation_get_var_def(state, var)))
> @@ -427,7 +428,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
>               return false;
>       }
>   
> -    if (!(new_node = copy_propagation_compute_replacement(state, &load->src, dimx, &swizzle)))
> +    if (!(new_node = copy_propagation_compute_replacement(ctx, state, &load->src, dimx, &swizzle)))
>           return false;
>   
>       if (type->type != HLSL_CLASS_OBJECT)
> @@ -448,7 +449,7 @@ static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx,
>       struct hlsl_ir_node *node;
>       unsigned int swizzle;
>   
> -    if (!(node = copy_propagation_compute_replacement(state, deref, 1, &swizzle)))
> +    if (!(node = copy_propagation_compute_replacement(ctx, state, deref, 1, &swizzle)))
>           return false;
>   
>       /* Only HLSL_IR_LOAD can produce an object. */
> @@ -481,7 +482,7 @@ static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_s
>       if (!(var_def = copy_propagation_create_var_def(ctx, state, var)))
>           return;
>   
> -    if (hlsl_offset_from_deref(lhs, &offset))
> +    if (hlsl_offset_from_deref(ctx, lhs, &offset))
>       {
>           unsigned int writemask = store->writemask;
>   
> @@ -1673,7 +1674,7 @@ static bool type_is_single_reg(const struct hlsl_type *type)
>       return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR;
>   }
>   
> -bool hlsl_offset_from_deref(const struct hlsl_deref *deref, unsigned int *offset)
> +bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset)
>   {
>       struct hlsl_ir_node *offset_node = deref->offset.node;
>   
> @@ -1691,6 +1692,14 @@ bool hlsl_offset_from_deref(const struct hlsl_deref *deref, unsigned int *offset
>           return false;
>   
>       *offset = hlsl_ir_constant(offset_node)->value[0].u;
> +
> +    if (*offset >= deref->var->data_type->reg_size)
> +    {
> +        hlsl_error(ctx, &deref->offset.node->loc, VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS,
> +                "Dereference is out of array bounds.");
> +        return false;
> +    }
> +
>       return true;
>   }
>   
> @@ -1698,7 +1707,7 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl
>   {
>       unsigned int offset;
>   
> -    if (hlsl_offset_from_deref(deref, &offset))
> +    if (hlsl_offset_from_deref(ctx, deref, &offset))
>           return offset;
>   
>       hlsl_fixme(ctx, &deref->offset.node->loc, "Dereference with non-constant offset of type %s.",
> diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
> index 1de67f45..5ab8494c 100644
> --- a/libs/vkd3d-shader/vkd3d_shader_private.h
> +++ b/libs/vkd3d-shader/vkd3d_shader_private.h
> @@ -115,6 +115,7 @@ enum vkd3d_shader_error
>       VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION         = 5016,
>       VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED             = 5017,
>       VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET        = 5018,
> +    VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS        = 5019,
>   
>       VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION       = 5300,
>   



More information about the wine-devel mailing list