summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2011-07-09 00:20:34 -0700
committerKenneth Graunke <kenneth@whitecape.org>2011-07-11 10:53:28 -0700
commit7304909d6537e00252347a10d0bae54ffd77ff91 (patch)
tree8800ef4f4233335d259a8fda7b70f48beae2cb4e
parent186e37c75454965e1a58298e878a9585f4866749 (diff)
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@anholt.net> Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--src/glsl/ir_function.cpp33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp
index 1255072a571..0f2f1a0eea4 100644
--- a/src/glsl/ir_function.cpp
+++ b/src/glsl/ir_function.cpp
@@ -165,8 +165,18 @@ ir_function_signature *
ir_function::matching_signature(const exec_list *actual_parameters)
{
ir_function_signature *match = NULL;
- int matched_score = 0;
-
+ 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();
@@ -178,13 +188,24 @@ ir_function::matching_signature(const exec_list *actual_parameters)
if (score == 0)
return sig;
- /* If we found a match with fewer conversions, use that instead */
- if (score > 0 && (match == NULL || score < matched_score)) {
- match = sig;
- matched_score = score;
+ if (score > 0) {
+ 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;
}