[jit] Verify argument counts within gcc_jit_context_new_call

David Malcolm dmalcolm@redhat.com
Mon Jan 27 19:20:00 GMT 2014


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, &param_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, &param_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



More information about the Gcc-patches mailing list