diff mbox

[jit] Add type-checking for API calls that expect numeric types

Message ID 1406299781-51341-1-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm July 25, 2014, 2:49 p.m. UTC
Committed to branch dmalcolm/jit:

gcc/jit/
	* TODO.rst (error-checking): Remove various items that either
	already were implemented, or are implemented by this commit.
	* internal-api.h (gcc::jit::recording::type::is_numeric): New.
	* libgccjit.c (RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE): New macro.
        (gcc_jit_context_new_rvalue_from_int): Verify that numeric_type is
	indeed numeric.
	(gcc_jit_context_zero): Likewise.
	(gcc_jit_context_one): Likewise.
	(gcc_jit_context_new_rvalue_from_double): Likewise.
	(gcc_jit_context_new_array_access): Likewise for type of "index".

gcc/testsuite/
	* jit.dg/test-error-index-not-a-numeric-type.c: New test case.
	* jit.dg/test-error-value-not-a-numeric-type.c: New test case.
---
 gcc/jit/ChangeLog.jit                              | 13 +++++++++
 gcc/jit/TODO.rst                                   | 16 ----------
 gcc/jit/internal-api.h                             |  5 ++++
 gcc/jit/libgccjit.c                                | 23 +++++++++++----
 gcc/testsuite/ChangeLog.jit                        |  5 ++++
 .../jit.dg/test-error-index-not-a-numeric-type.c   | 34 ++++++++++++++++++++++
 .../jit.dg/test-error-value-not-a-numeric-type.c   | 29 ++++++++++++++++++
 7 files changed, 104 insertions(+), 21 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-error-index-not-a-numeric-type.c
 create mode 100644 gcc/testsuite/jit.dg/test-error-value-not-a-numeric-type.c
diff mbox

Patch

diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index 65fba51..3db15e8 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,3 +1,16 @@ 
+2014-07-25  David Malcolm  <dmalcolm@redhat.com>
+
+	* TODO.rst (error-checking): Remove various items that either
+	already were implemented, or are implemented by this commit.
+	* internal-api.h (gcc::jit::recording::type::is_numeric): New.
+	* libgccjit.c (RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE): New macro.
+        (gcc_jit_context_new_rvalue_from_int): Verify that numeric_type is
+	indeed numeric.
+	(gcc_jit_context_zero): Likewise.
+	(gcc_jit_context_one): Likewise.
+	(gcc_jit_context_new_rvalue_from_double): Likewise.
+	(gcc_jit_context_new_array_access): Likewise for type of "index".
+
 2014-07-14  David Malcolm  <dmalcolm@redhat.com>
 
 	* internal-api.c (gcc::jit::recording::context::new_array_type):
diff --git a/gcc/jit/TODO.rst b/gcc/jit/TODO.rst
index b2d8c04..caf78e3 100644
--- a/gcc/jit/TODO.rst
+++ b/gcc/jit/TODO.rst
@@ -75,20 +75,6 @@  Initial Release
 
 * error-checking:
 
-    * gcc_jit_context_new_field: type must not be void
-
-    * gcc_jit_context_new_param: type must not be void
-
-    * gcc_jit_context_new_global: type must not be void
-
-    * gcc_jit_context_new_rvalue_from_int: must be a numeric type
-
-    * gcc_jit_context_zero: must be a numeric type
-
-    * gcc_jit_context_one: must be a numeric type
-
-    * gcc_jit_context_new_rvalue_from_double: must be a numeric type
-
     * gcc_jit_context_new_unary_op: various checks needed
 
     * gcc_jit_context_new_binary_op: various checks needed
@@ -101,8 +87,6 @@  Initial Release
 
     * gcc_jit_rvalue_access_field: must be field of correct struct
 
-    * gcc_jit_function_new_local: type must not be void
-
     * gcc_jit_block_add_assignment_op: check the types
 
 * Currently each function has a single stmt_list, which is built in
diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h
index 1612a22..331edd5 100644
--- a/gcc/jit/internal-api.h
+++ b/gcc/jit/internal-api.h
@@ -500,6 +500,11 @@  public:
   virtual type *is_pointer () = 0;
   virtual type *is_array () = 0;
 
+  bool is_numeric () const
+  {
+    return is_int () || is_float () || is_bool ();
+  }
+
   playback::type *
   playback_type ()
   {
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index c9805de..bbc1941 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -671,13 +671,20 @@  gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
   return static_cast <gcc_jit_type *> (rvalue->get_type ());
 }
 
+#define RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE(CTXT, NUMERIC_TYPE) \
+  RETURN_NULL_IF_FAIL (NUMERIC_TYPE, CTXT, NULL, "NULL type"); \
+  RETURN_NULL_IF_FAIL_PRINTF1 (                                \
+    NUMERIC_TYPE->is_numeric (), ctxt, NULL,                   \
+    "not a numeric type: %s",                                  \
+    NUMERIC_TYPE->get_debug_string ());
+
 gcc_jit_rvalue *
 gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
 				     gcc_jit_type *numeric_type,
 				     int value)
 {
   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (numeric_type, ctxt, NULL, "NULL type");
+  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
 
   return (gcc_jit_rvalue *)ctxt->new_rvalue_from_int (numeric_type, value);
 }
@@ -687,7 +694,7 @@  gcc_jit_context_zero (gcc_jit_context *ctxt,
 		      gcc_jit_type *numeric_type)
 {
   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (numeric_type, ctxt, NULL, "NULL type");
+  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
 
   return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
 }
@@ -697,7 +704,7 @@  gcc_jit_context_one (gcc_jit_context *ctxt,
 		     gcc_jit_type *numeric_type)
 {
   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (numeric_type, ctxt, NULL, "NULL type");
+  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
 
   return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
 }
@@ -708,7 +715,7 @@  gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt,
 					double value)
 {
   RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (numeric_type, ctxt, NULL, "NULL type");
+  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);
 
   return (gcc_jit_rvalue *)ctxt->new_rvalue_from_double (numeric_type, value);
 }
@@ -946,9 +953,15 @@  gcc_jit_context_new_array_access (gcc_jit_context *ctxt,
   RETURN_NULL_IF_FAIL_PRINTF2 (
     ptr->get_type ()->dereference (),
     ctxt, loc,
-    "%s (type: %s) is not a pointer or array",
+    "ptr: %s (type: %s) is not a pointer or array",
     ptr->get_debug_string (),
     ptr->get_type ()->get_debug_string ());
+  RETURN_NULL_IF_FAIL_PRINTF2 (
+    index->get_type ()->is_numeric (),
+    ctxt, loc,
+    "index: %s (type: %s) is not of numeric type",
+    index->get_debug_string (),
+    index->get_type ()->get_debug_string ());
 
   return (gcc_jit_lvalue *)ctxt->new_array_access (loc, ptr, index);
 }
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index 393bd8f..39eed72 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,3 +1,8 @@ 
+2014-07-25  David Malcolm  <dmalcolm@redhat.com>
+
+	* jit.dg/test-error-index-not-a-numeric-type.c: New test case.
+	* jit.dg/test-error-value-not-a-numeric-type.c: New test case.
+
 2014-03-19  David Malcolm  <dmalcolm@redhat.com>
 
 	* jit.dg/test-array-as-pointer.c: New test case, verifying that
diff --git a/gcc/testsuite/jit.dg/test-error-index-not-a-numeric-type.c b/gcc/testsuite/jit.dg/test-error-index-not-a-numeric-type.c
new file mode 100644
index 0000000..a3540b2
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-index-not-a-numeric-type.c
@@ -0,0 +1,34 @@ 
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Let's try to access an array at an index that isn't of a numeric
+     type and verify that the API complains about the bad type.
+  */
+  gcc_jit_rvalue *string =
+    gcc_jit_context_new_string_literal (ctxt,
+					"hello world");
+
+  (void)gcc_jit_context_new_array_access (
+    ctxt, NULL,
+    string, /* ptr */
+    string /* index, not of numeric type */);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  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_array_access:"
+		      " index: \"hello world\" (type: const char *)"
+		      " is not of numeric type");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-value-not-a-numeric-type.c b/gcc/testsuite/jit.dg/test-error-value-not-a-numeric-type.c
new file mode 100644
index 0000000..46f4f48
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-value-not-a-numeric-type.c
@@ -0,0 +1,29 @@ 
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Let's try to build an rvalue from a double with a non-numeric type
+     and verify that the API complains about the bad type.
+  */
+  gcc_jit_type *void_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+
+  (void)gcc_jit_context_new_rvalue_from_double (ctxt, void_type, 42.0);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+  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_rvalue_from_double:"
+		      " not a numeric type: void");
+}