summaryrefslogtreecommitdiff
path: root/src/glsl/ir_function.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl/ir_function.cpp')
-rw-r--r--src/glsl/ir_function.cpp32
1 files changed, 27 insertions, 5 deletions
diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp
index caee9296af9..0f2f1a0eea4 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;
}