[Mesa-dev] [PATCH 3/4] glsl: Emit extra errors for l-value violations in 'out' or 'inout' parameters

Paul Berry stereotype441 at gmail.com
Fri Jan 6 11:21:30 PST 2012


On 23 December 2011 14:35, Ian Romanick <idr at freedesktop.org> wrote:

> From: Ian Romanick <ian.d.romanick at intel.com>
>
> Somethings, like pre-increment operations, were not previously caught.
> After the 8.0 release, this code needs some major refactoring and
> clean-up.  It's a mess. :(
>
> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42755
> ---
>  src/glsl/ast_function.cpp |   57
> +++++++++++++++++++++++++++++++++++++++++---
>  1 files changed, 53 insertions(+), 4 deletions(-)
>
> diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
> index 126b610..4471c76 100644
> --- a/src/glsl/ast_function.cpp
> +++ b/src/glsl/ast_function.cpp
> @@ -96,6 +96,7 @@ prototype_string(const glsl_type *return_type, const
> char *name,
>  static ir_rvalue *
>  generate_call(exec_list *instructions, ir_function_signature *sig,
>              YYLTYPE *loc, exec_list *actual_parameters,
> +             ir_call **call_ir,
>              struct _mesa_glsl_parse_state *state)
>

Another minor suggestion:  The semantics of call_ir are:

- If generate_call is successful, it is set to the ir_call that is
generated.
- If an error occurred, it is unchanged.

This means that in order for the caller to be robust in the case of error
conditions, it must remember to set call_ir to NULL before calling this
function.

You're doing that, so there's no bug, but I'd feel better about the
situation if we set *call_ir to NULL at the top of generate_call rather
than in the caller.  That way call_ir would behave like a true out
parameter even in the case of error.

As with my other comment, I'm not married to the idea; either way the
series is:

Reviewed-by: Paul Berry <stereotype441 at gmail.com>


>  {
>    void *ctx = state;
> @@ -256,10 +257,12 @@ generate_call(exec_list *instructions,
> ir_function_signature *sig,
>       deref = new(ctx) ir_dereference_variable(var);
>       ir_assignment *assign = new(ctx) ir_assignment(deref, call, NULL);
>       instructions->push_tail(assign);
> +      *call_ir = call;
>
>       deref = new(ctx) ir_dereference_variable(var);
>    } else {
>       instructions->push_tail(call);
> +      *call_ir = call;
>       deref = NULL;
>    }
>    instructions->append_list(&post_call_conversions);
> @@ -269,6 +272,7 @@ generate_call(exec_list *instructions,
> ir_function_signature *sig,
>  static ir_rvalue *
>  match_function_by_name(exec_list *instructions, const char *name,
>                       YYLTYPE *loc, exec_list *actual_parameters,
> +                      ir_call **call_ir,
>                       struct _mesa_glsl_parse_state *state)
>  {
>    void *ctx = state;
> @@ -342,7 +346,8 @@ done:
>       }
>
>       /* Finally, generate a call instruction. */
> -      return generate_call(instructions, sig, loc, actual_parameters,
> state);
> +      return generate_call(instructions, sig, loc, actual_parameters,
> +                          call_ir, state);
>    } else {
>       char *str = prototype_string(NULL, name, actual_parameters);
>
> @@ -1442,9 +1447,53 @@ ast_function_expression::hir(exec_list
> *instructions,
>       process_parameters(instructions, &actual_parameters,
> &this->expressions,
>                         state);
>
> -      return match_function_by_name(instructions,
> -                                   id->primary_expression.identifier, &
> loc,
> -                                   &actual_parameters, state);
> +      ir_call *call = NULL;
> +      ir_rvalue *const value =
> +        match_function_by_name(instructions,
> +                               id->primary_expression.identifier,
> +                               &loc, &actual_parameters, &call, state);
> +
> +      if (call != NULL) {
> +        /* If a function was found, make sure that none of the 'out' or
> 'inout'
> +         * parameters violate the extra l-value rules.
> +         */
> +        ir_function_signature *f = call->get_callee();
> +        assert(f != NULL);
> +
> +        exec_node *formal_node = f->parameters.head;
> +
> +        foreach_list (actual_node, &this->expressions) {
> +           /* Both parameter lists had better be the same length!
> +            */
> +           assert(!actual_node->is_tail_sentinel());
> +
> +           const ir_variable *const formal_parameter =
> +              (ir_variable *) formal_node;
> +           const ast_expression *const actual_parameter =
> +              exec_node_data(ast_expression, actual_node, link);
> +
> +           if ((formal_parameter->mode == ir_var_out
> +                || formal_parameter->mode == ir_var_inout)
> +               && actual_parameter->non_lvalue_description != NULL) {
> +              YYLTYPE loc = actual_parameter->get_location();
> +
> +              _mesa_glsl_error(&loc, state,
> +                               "function parameter '%s %s' references a
> %s",
> +                               (formal_parameter->mode == ir_var_out)
> +                               ? "out" : "inout",
> +                               formal_parameter->name,
> +                               actual_parameter->non_lvalue_description);
> +              return ir_call::get_error_instruction(ctx);
> +           }
> +
> +           /* Only advance the formal_node pointer here because the
> +            * foreach_list business already advances actual_node.
> +            */
> +           formal_node = formal_node->next;
> +        }
> +      }
> +
> +      return value;
>    }
>
>    return ir_call::get_error_instruction(ctx);
> --
> 1.7.6.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20120106/3f094b8d/attachment.htm>


More information about the mesa-dev mailing list