This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[jit] Verify argument counts within gcc_jit_context_new_call
- From: David Malcolm <dmalcolm at redhat dot com>
- To: jit at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Mon, 27 Jan 2014 14:18:57 -0500
- Subject: [jit] Verify argument counts within gcc_jit_context_new_call
- Authentication-results: sourceware.org; auth=none
Committed to dmalcolm/jit:
gcc/jit/
* internal-api (gcc::jit::recording::context::new_call): Verify
the argument count of the call against the parameter count of the
function, issuing an error if there's a mismatch.
* internal-api.h (gcc::jit::recording::function::get_name): New.
* (gcc::jit::recording::function::get_params): New.
* (gcc::jit::recording::function::is_variadic): New.
gcc/testsuite/
* jit.dg/test-error-call-with-not-enough-args.c: New test case.
* jit.dg/test-error-call-with-too-many-args.c: New test case.
* jit.dg/test-null-passed-to-api.c: Rename to...
* jit.dg/test-error-null-passed-to-api.c: ...this, so that
error-handling test cases are consistently named.
---
gcc/jit/internal-api.c | 20 +++++
gcc/jit/internal-api.h | 4 +
.../jit.dg/test-error-call-with-not-enough-args.c | 86 +++++++++++++++++++++
.../jit.dg/test-error-call-with-too-many-args.c | 88 ++++++++++++++++++++++
.../jit.dg/test-error-null-passed-to-api.c | 31 ++++++++
gcc/testsuite/jit.dg/test-null-passed-to-api.c | 31 --------
6 files changed, 229 insertions(+), 31 deletions(-)
create mode 100644 gcc/testsuite/jit.dg/test-error-call-with-not-enough-args.c
create mode 100644 gcc/testsuite/jit.dg/test-error-call-with-too-many-args.c
create mode 100644 gcc/testsuite/jit.dg/test-error-null-passed-to-api.c
delete mode 100644 gcc/testsuite/jit.dg/test-null-passed-to-api.c
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 64a0912..cf9195d0 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -278,6 +278,26 @@ recording::context::new_call (recording::location *loc,
function *func,
int numargs , recording::rvalue **args)
{
+ int min_num_params = func->get_params ().length ();
+ bool is_variadic = func->is_variadic ();
+ if (numargs < min_num_params)
+ {
+ add_error (("gcc_jit_context_new_call: "
+ "not enough arguments to function \"%s\""
+ " (got %i args, expected %i)"),
+ func->get_name ()->c_str (),
+ numargs, min_num_params);
+ return NULL;
+ }
+ if (numargs > min_num_params && !is_variadic)
+ {
+ add_error (("gcc_jit_context_new_call: "
+ "too many arguments to function \"%s\""
+ " (got %i args, expected %i)"),
+ func->get_name ()->c_str (),
+ numargs, min_num_params);
+ return NULL;
+ }
recording::rvalue *result = new call (this, loc, func, numargs, args);
record (result);
return result;
diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h
index 15f5918..94c149b 100644
--- a/gcc/jit/internal-api.h
+++ b/gcc/jit/internal-api.h
@@ -608,6 +608,10 @@ public:
new_loop (location *loc,
rvalue *boolval);
+ string * get_name () const { return m_name; }
+ vec<param *> get_params () const { return m_params; }
+ bool is_variadic () const { return m_is_variadic; }
+
private:
location *m_loc;
enum gcc_jit_function_kind m_kind;
diff --git a/gcc/testsuite/jit.dg/test-error-call-with-not-enough-args.c b/gcc/testsuite/jit.dg/test-error-call-with-not-enough-args.c
new file mode 100644
index 0000000..4cfa09e
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-call-with-not-enough-args.c
@@ -0,0 +1,86 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern void
+ called_function (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ extern void called_function (int p);
+
+ void
+ test_caller ()
+ {
+ called_function (); // missing arg
+ }
+
+ and verify that the API complains about the missing argument.
+ */
+ gcc_jit_type *void_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+ /* Declare the imported function. */
+ gcc_jit_param *param_p =
+ gcc_jit_context_new_param (ctxt, NULL, int_type, "p");
+ gcc_jit_function *called_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_IMPORTED,
+ void_type,
+ "called_function",
+ 1, ¶m_p,
+ 0);
+
+ /* Build the test_fn. */
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_type,
+ "test_caller",
+ 0, NULL,
+ 0);
+ /* called_function (); */
+ gcc_jit_function_add_eval (
+ test_fn, NULL,
+ gcc_jit_context_new_call (ctxt,
+ NULL,
+ called_fn,
+ 0, NULL));
+ /* the above has the wrong arg count. */
+
+}
+
+extern void
+called_function (void)
+{
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that mismatching arg count leads to the API giving a NULL
+ result back. */
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ ("gcc_jit_context_new_call:"
+ " not enough arguments to function \"called_function\""
+ " (got 0 args, expected 1)"));
+}
+
diff --git a/gcc/testsuite/jit.dg/test-error-call-with-too-many-args.c b/gcc/testsuite/jit.dg/test-error-call-with-too-many-args.c
new file mode 100644
index 0000000..bbfb99f
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-call-with-too-many-args.c
@@ -0,0 +1,88 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern void
+ called_function (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ extern void called_function ();
+
+ void
+ test_caller (int a)
+ {
+ called_function (a);
+ }
+
+ and verify that the API complains about the mismatching arg
+ counts.
+ */
+ gcc_jit_type *void_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+ /* Declare the imported function. */
+ gcc_jit_function *called_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_IMPORTED,
+ void_type,
+ "called_function",
+ 0, NULL,
+ 0);
+
+ /* Build the test_fn. */
+ gcc_jit_param *param_a =
+ gcc_jit_context_new_param (ctxt, NULL, int_type, "a");
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_type,
+ "test_caller",
+ 1, ¶m_a,
+ 0);
+ /* called_function (a); */
+ gcc_jit_rvalue *arg = gcc_jit_param_as_rvalue (param_a);
+ gcc_jit_function_add_eval (
+ test_fn, NULL,
+ gcc_jit_context_new_call (ctxt,
+ NULL,
+ called_fn,
+ 1, &arg));
+ /* the above has the wrong arg count. */
+
+}
+
+extern void
+called_function (void)
+{
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that mismatching arg count leads to the API giving a NULL
+ result back. */
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ ("gcc_jit_context_new_call:"
+ " too many arguments to function \"called_function\""
+ " (got 1 args, expected 0)"));
+}
+
diff --git a/gcc/testsuite/jit.dg/test-error-null-passed-to-api.c b/gcc/testsuite/jit.dg/test-error-null-passed-to-api.c
new file mode 100644
index 0000000..ea4390b
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-null-passed-to-api.c
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Trigger an API error by passing bad data. */
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ NULL, /* error: this must be non-NULL */
+ "hello_world",
+ 0, NULL,
+ 0);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_context_new_function: NULL return_type");
+}
+
diff --git a/gcc/testsuite/jit.dg/test-null-passed-to-api.c b/gcc/testsuite/jit.dg/test-null-passed-to-api.c
deleted file mode 100644
index ea4390b..0000000
--- a/gcc/testsuite/jit.dg/test-null-passed-to-api.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "libgccjit.h"
-
-#include "harness.h"
-
-void
-create_code (gcc_jit_context *ctxt, void *user_data)
-{
- /* Trigger an API error by passing bad data. */
- gcc_jit_context_new_function (ctxt, NULL,
- GCC_JIT_FUNCTION_EXPORTED,
- NULL, /* error: this must be non-NULL */
- "hello_world",
- 0, NULL,
- 0);
-}
-
-void
-verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
-{
- /* Ensure that the bad API usage prevents the API giving a bogus
- result back. */
- CHECK_VALUE (result, NULL);
-
- /* Verify that the correct error message was emitted. */
- CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
- "gcc_jit_context_new_function: NULL return_type");
-}
-
--
1.7.11.7