mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/hlsl: Validate break/continue context.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
parent
9a6e4a0c58
commit
72623031a2
Notes:
Alexandre Julliard
2023-10-31 22:37:53 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Zebediah Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/361
@ -727,6 +727,8 @@ struct hlsl_scope
|
|||||||
struct hlsl_scope *upper;
|
struct hlsl_scope *upper;
|
||||||
/* The scope was created for the loop statement. */
|
/* The scope was created for the loop statement. */
|
||||||
bool loop;
|
bool loop;
|
||||||
|
/* The scope was created for the switch statement. */
|
||||||
|
bool _switch;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hlsl_profile_info
|
struct hlsl_profile_info
|
||||||
|
@ -4640,12 +4640,31 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hlsl_scope *get_loop_scope(struct hlsl_scope *scope)
|
static bool check_continue(struct hlsl_ctx *ctx, const struct hlsl_scope *scope, const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
if (scope->loop)
|
if (scope->_switch)
|
||||||
return scope;
|
{
|
||||||
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
||||||
|
"The 'continue' statement is not allowed in 'switch' statements.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return scope->upper ? get_loop_scope(scope->upper) : NULL;
|
if (scope->loop)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (scope->upper)
|
||||||
|
return check_continue(ctx, scope->upper, loc);
|
||||||
|
|
||||||
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "The 'continue' statement is only allowed in loops.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_break_allowed(const struct hlsl_scope *scope)
|
||||||
|
{
|
||||||
|
if (scope->loop || scope->_switch)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return scope->upper ? is_break_allowed(scope->upper) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_duplicated_switch_cases(struct hlsl_ctx *ctx, const struct hlsl_ir_switch_case *check, struct list *cases)
|
static void check_duplicated_switch_cases(struct hlsl_ctx *ctx, const struct hlsl_ir_switch_case *check, struct list *cases)
|
||||||
@ -5407,6 +5426,8 @@ loop_scope_start:
|
|||||||
switch_scope_start:
|
switch_scope_start:
|
||||||
%empty
|
%empty
|
||||||
{
|
{
|
||||||
|
hlsl_push_scope(ctx);
|
||||||
|
ctx->cur_scope->_switch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var_identifier:
|
var_identifier:
|
||||||
@ -6244,12 +6265,10 @@ jump_statement:
|
|||||||
{
|
{
|
||||||
struct hlsl_ir_node *jump;
|
struct hlsl_ir_node *jump;
|
||||||
|
|
||||||
/* TODO: allow 'break' in the 'switch' statements. */
|
if (!is_break_allowed(ctx->cur_scope))
|
||||||
|
|
||||||
if (!get_loop_scope(ctx->cur_scope))
|
|
||||||
{
|
{
|
||||||
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
||||||
"The 'break' statement must be used inside of a loop.");
|
"The 'break' statement must be used inside of a loop or a switch.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($$ = make_empty_block(ctx)))
|
if (!($$ = make_empty_block(ctx)))
|
||||||
@ -6261,13 +6280,8 @@ jump_statement:
|
|||||||
| KW_CONTINUE ';'
|
| KW_CONTINUE ';'
|
||||||
{
|
{
|
||||||
struct hlsl_ir_node *jump;
|
struct hlsl_ir_node *jump;
|
||||||
struct hlsl_scope *scope;
|
|
||||||
|
|
||||||
if (!(scope = get_loop_scope(ctx->cur_scope)))
|
check_continue(ctx, ctx->cur_scope, &@1);
|
||||||
{
|
|
||||||
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
|
||||||
"The 'continue' statement must be used inside of a loop.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!($$ = make_empty_block(ctx)))
|
if (!($$ = make_empty_block(ctx)))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
@ -6411,6 +6425,8 @@ switch_statement:
|
|||||||
|
|
||||||
$$ = $5;
|
$$ = $5;
|
||||||
hlsl_block_add_instr($$, s);
|
hlsl_block_add_instr($$, s);
|
||||||
|
|
||||||
|
hlsl_pop_scope(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_case:
|
switch_case:
|
||||||
|
@ -211,7 +211,7 @@ float4 main() : sv_target
|
|||||||
}
|
}
|
||||||
|
|
||||||
% unterminated cases
|
% unterminated cases
|
||||||
[pixel shader fail(sm<6)]
|
[pixel shader fail(sm<6) todo]
|
||||||
uint4 v;
|
uint4 v;
|
||||||
|
|
||||||
float4 main() : sv_target
|
float4 main() : sv_target
|
||||||
@ -455,7 +455,7 @@ todo draw quad
|
|||||||
probe all rgba (1.0, 2.0, 3.0, 4.0)
|
probe all rgba (1.0, 2.0, 3.0, 4.0)
|
||||||
|
|
||||||
% 'continue' is not supported in switches
|
% 'continue' is not supported in switches
|
||||||
[pixel shader fail(sm<6) todo]
|
[pixel shader fail(sm<6)]
|
||||||
uint4 v;
|
uint4 v;
|
||||||
|
|
||||||
float4 main() : sv_target
|
float4 main() : sv_target
|
||||||
|
Loading…
Reference in New Issue
Block a user