Mesa (7.11): glsl: Correctly handle function matching when there are multiple inexact matches

Ian Romanick idr at kemper.freedesktop.org
Tue Jul 19 23:41:07 UTC 2011


Module: Mesa
Branch: 7.11
Commit: 2826e3a000792ef58e99ce07add43453003dad11
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2826e3a000792ef58e99ce07add43453003dad11

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Jun 14 16:28:32 2011 -0700

glsl: Correctly handle function matching when there are multiple inexact matches

This is a squash cherry pick commit of:

    glsl: Find the "closest" signature when there are multiple matches.

    Previously, ir_function::matching_signature had a fatal bug: if a
    function had more than one non-exact match, it would simply return NULL.

    This occured, for example, when looking for max(uvec3, uvec3):
    - max(vec3, vec3)   -> score 1 (found first)
    - max(ivec3, ivec3) -> score 1 (found second...used to return NULL here)
    - max(uvec3, uvec3) -> score 0 (exact match...the right answer)

    This did not occur for max(ivec3, ivec3) since the second match found
    was an exact match.

    The new behavior is to return a match with the lowest score.  If there
    is an exact match, that will be returned.  Otherwise, a match with the
    least number of implicit conversions is chosen.

    Fixes piglit tests max-uvec3.vert and glsl-inexact-overloads.shader_test.

    NOTE: This is a candidate for the 7.10 and 7.11 branches.

    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    (cherry picked from commit 60eb63a855cb89962f2d5bb91e238ff2d1ab8702)

    glsl: Suppress warning from matching_signature change.

    gcc isn't smart enough to see that we only look at matched_score after
    we've initialized it (because match != NULL happens at the same time)
    (cherry picked from commit b043409adfa6ffa6dc78331258de52f7fa6d59aa)

    glsl: Reject ambiguous function calls (multiple inexact matches).

    According to the GLSL 1.20 specification, "it is a semantic error if
    there are multiple ways to apply [implicit] conversions [...] such that
    the call can be made to match multiple signatures."

    Fixes a regression caused by 60eb63a855cb89962f2d5bb91e238ff2d1ab8702,
    which implemented the wrong policy of finding a "closest" match.
    However, this is not a revert, since the original code failed to
    continue looking for an exact match once it found two inexact matches.

    It's OK to have multiple inexact matches if there's also an exact match.

    NOTE: This is a candidate for the 7.10 and 7.11 branches.

    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38971
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
    (cherry picked from commit 7304909d6537e00252347a10d0bae54ffd77ff91)

---

 src/glsl/ir_function.cpp |   32 +++++++++++++++++++++++++++-----
 1 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp
index caee929..0f2f1a0 100644
--- a/src/glsl/ir_function.cpp
+++ b/src/glsl/ir_function.cpp
@@ -165,7 +165,18 @@ ir_function_signature *
 ir_function::matching_signature(const exec_list *actual_parameters)
 {
    ir_function_signature *match = NULL;
-
+   bool multiple_inexact_matches = false;
+
+   /* From page 42 (page 49 of the PDF) of the GLSL 1.20 spec:
+    *
+    * "If an exact match is found, the other signatures are ignored, and
+    *  the exact match is used.  Otherwise, if no exact match is found, then
+    *  the implicit conversions in Section 4.1.10 "Implicit Conversions" will
+    *  be applied to the calling arguments if this can make their types match
+    *  a signature.  In this case, it is a semantic error if there are
+    *  multiple ways to apply these conversions to the actual arguments of a
+    *  call such that the call can be made to match multiple signatures."
+    */
    foreach_iter(exec_list_iterator, iter, signatures) {
       ir_function_signature *const sig =
 	 (ir_function_signature *) iter.get();
@@ -173,17 +184,28 @@ ir_function::matching_signature(const exec_list *actual_parameters)
       const int score = parameter_lists_match(& sig->parameters,
 					      actual_parameters);
 
+      /* If we found an exact match, simply return it */
       if (score == 0)
 	 return sig;
 
       if (score > 0) {
-	 if (match != NULL)
-	    return NULL;
-
-	 match = sig;
+	 if (match == NULL)
+	    match = sig;
+	 else
+	    multiple_inexact_matches = true;
       }
    }
 
+   /* There is no exact match (we would have returned it by now).  If there
+    * are multiple inexact matches, the call is ambiguous, which is an error.
+    *
+    * FINISHME: Report a decent error.  Returning NULL will likely result in
+    * FINISHME: a "no matching signature" error; it should report that the
+    * FINISHME: call is ambiguous.  But reporting errors from here is hard.
+    */
+   if (multiple_inexact_matches)
+      return NULL;
+
    return match;
 }
 




More information about the mesa-commit mailing list