On 23 December 2011 14:35, Ian Romanick <span dir="ltr">&lt;<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


From: Ian Romanick &lt;<a href="mailto:ian.d.romanick@intel.com" target="_blank">ian.d.romanick@intel.com</a>&gt;<br>
<br>
Somethings, like pre-increment operations, were not previously caught.<br>
After the 8.0 release, this code needs some major refactoring and<br>
clean-up.  It&#39;s a mess. :(<br>
<br>
Signed-off-by: Ian Romanick &lt;<a href="mailto:ian.d.romanick@intel.com" target="_blank">ian.d.romanick@intel.com</a>&gt;<br>
Bugzilla: <a href="https://bugs.freedesktop.org/show_bug.cgi?id=42755" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=42755</a><br>
---<br>
 src/glsl/ast_function.cpp |   57 +++++++++++++++++++++++++++++++++++++++++---<br>
 1 files changed, 53 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp<br>
index 126b610..4471c76 100644<br>
--- a/src/glsl/ast_function.cpp<br>
+++ b/src/glsl/ast_function.cpp<br>
@@ -96,6 +96,7 @@ prototype_string(const glsl_type *return_type, const char *name,<br>
 static ir_rvalue *<br>
 generate_call(exec_list *instructions, ir_function_signature *sig,<br>
              YYLTYPE *loc, exec_list *actual_parameters,<br>
+             ir_call **call_ir,<br>
              struct _mesa_glsl_parse_state *state)<br></blockquote><div><br>Another minor suggestion:  The semantics of call_ir are:<br><br>- If generate_call is successful, it is set to the ir_call that is generated.<br>
- If an error occurred, it is unchanged.<br>

<br>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.<br><br>You&#39;re doing that, so there&#39;s no bug, but I&#39;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.<br>


<br>As with my other comment, I&#39;m not married to the idea; either way the series is:<br><br>Reviewed-by: Paul Berry &lt;<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.com</a>&gt;<br> </div>

<blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

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