public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] jit: check for void types [PR 95296]
@ 2020-05-26 15:05 David Malcolm
  0 siblings, 0 replies; only message in thread
From: David Malcolm @ 2020-05-26 15:05 UTC (permalink / raw)
  To: gcc-patches, jit

PR jit/95296 reports an ICE when using libgccjit to create a local of void
type.

This patch adds checking to various API entrypoints in libgccjit.c so that
they fail gracefully with an error if the client code attempts to create
various kinds of rvalues or types involving void types.
The patch documents these and various pre-existing restrictions on types
in the API.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to master as r11-636-g6f7585deedc140667fd496b48c9fc4f7d625605c.

gcc/jit/ChangeLog:
	PR jit/95296
	* docs/topics/expressions.rst (Unary Operations): Document that
	result_type of gcc_jit_context_new_unary_op must be a numeric type.
	(Binary Operations): Likewise for gcc_jit_context_new_binary_op.
	(Global variables): Document that "type" of
	gcc_jit_context_new_global must be non-`void`.
	* docs/topics/function-pointers.rst
	(gcc_jit_context_new_function_ptr_type): Document that the
	param_types must be non-void, but that return_type may be.
	* docs/topics/functions.rst (Params): Document that
	gcc_jit_context_new_param's type must be non-void.
	(Functions): Likewise for gcc_jit_function_new_local.
	* docs/topics/types.rst (gcc_jit_context_new_array_type): Document
	that the type must be non-void.
	(gcc_jit_context_new_field): Likewise.
	* docs/_build/texinfo/Makefile: Regenerate.
	* docs/_build/texinfo/libgccjit.texi: Regenerate.
	* libgccjit.c (gcc_jit_context_new_array_type): Fail if
	element_type is void.
	(gcc_jit_context_new_field): Likewise for "type".
	(gcc_jit_context_new_function_ptr_type): Likewise for each
	element of param_types.
	(gcc_jit_context_new_param): Likewise for "type".
	(gcc_jit_context_new_global): Likewise.
	(gcc_jit_function_new_local): Likewise.
	(gcc_jit_type_get_aligned): Likewise.

gcc/testsuite/ChangeLog:
	PR jit/95296
	* jit.dg/test-error-gcc_jit_context_new_global-void-type.c: New
	test.
	* jit.dg/test-error-gcc_jit_function_new_local-void-type.c: New
	test.
	* jit.dg/test-fuzzer.c (fuzzer_init): Allow for make_random_type
	to return NULL.
	(get_random_type): Allow for elements in f->types to be NULL.
---
 gcc/jit/docs/topics/expressions.rst           |  6 ++++
 gcc/jit/docs/topics/function-pointers.rst     |  2 ++
 gcc/jit/docs/topics/functions.rst             |  4 +++
 gcc/jit/docs/topics/types.rst                 |  6 ++--
 gcc/jit/libgccjit.c                           | 34 ++++++++++++++++---
 ...ror-gcc_jit_context_new_global-void-type.c | 25 ++++++++++++++
 ...ror-gcc_jit_function_new_local-void-type.c | 27 +++++++++++++++
 gcc/testsuite/jit.dg/test-fuzzer.c            |  2 --
 8 files changed, 98 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-void-type.c
 create mode 100644 gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-void-type.c

diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst
index db2f2ca2e9c..d783ceea51a 100644
--- a/gcc/jit/docs/topics/expressions.rst
+++ b/gcc/jit/docs/topics/expressions.rst
@@ -162,6 +162,8 @@ Unary Operations
 
    Build a unary operation out of an input rvalue.
 
+   The parameter ``result_type`` must be a numeric type.
+
 .. type:: enum gcc_jit_unary_op
 
 The available unary operations are:
@@ -227,6 +229,8 @@ Binary Operations
 
    Build a binary operation out of two constituent rvalues.
 
+   The parameter ``result_type`` must be a numeric type.
+
 .. type:: enum gcc_jit_binary_op
 
 The available binary operations are:
@@ -547,6 +551,8 @@ Global variables
 
    Add a new global variable of the given type and name to the context.
 
+   The parameter ``type`` must be non-`void`.
+
    The parameter ``name`` must be non-NULL.  The call takes a copy of the
    underlying string, so it is valid to pass in a pointer to an on-stack
    buffer.
diff --git a/gcc/jit/docs/topics/function-pointers.rst b/gcc/jit/docs/topics/function-pointers.rst
index c8424ee17dc..7d2fa8b278d 100644
--- a/gcc/jit/docs/topics/function-pointers.rst
+++ b/gcc/jit/docs/topics/function-pointers.rst
@@ -78,3 +78,5 @@ Here's an example of creating a function pointer type corresponding to C's
 
    Generate a :c:type:`gcc_jit_type` for a function pointer with the
    given return type and parameters.
+
+   Each of `param_types` must be non-`void`; `return_type` may be `void`.
diff --git a/gcc/jit/docs/topics/functions.rst b/gcc/jit/docs/topics/functions.rst
index 74d479af1bb..29ce96c1e56 100644
--- a/gcc/jit/docs/topics/functions.rst
+++ b/gcc/jit/docs/topics/functions.rst
@@ -35,6 +35,8 @@ Params
    In preparation for creating a function, create a new parameter of the
    given type and name.
 
+   The parameter ``type`` must be non-`void`.
+
    The parameter ``name`` must be non-NULL.  The call takes a copy of the
    underlying string, so it is valid to pass in a pointer to an on-stack
    buffer.
@@ -148,6 +150,8 @@ Functions
    Create a new local variable within the function, of the given type and
    name.
 
+   The parameter ``type`` must be non-`void`.
+
    The parameter ``name`` must be non-NULL.  The call takes a copy of the
    underlying string, so it is valid to pass in a pointer to an on-stack
    buffer.
diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst
index d1a39eeaf3b..ea7c8ff4542 100644
--- a/gcc/jit/docs/topics/types.rst
+++ b/gcc/jit/docs/topics/types.rst
@@ -115,13 +115,13 @@ Pointers, `const`, and `volatile`
                                                gcc_jit_type *element_type, \
                                                int num_elements)
 
-   Given type "T", get type "T[N]" (for a constant N).
+   Given non-`void` type "T", get type "T[N]" (for a constant N).
 
 .. function::  gcc_jit_type *\
                gcc_jit_type_get_aligned (gcc_jit_type *type, \
                                          size_t alignment_in_bytes)
 
-   Given type "T", get type:
+   Given non-`void` type "T", get type:
 
    .. code-block:: c
 
@@ -243,6 +243,8 @@ You can model C `struct` types by creating :c:type:`gcc_jit_struct *` and
 
    Construct a new field, with the given type and name.
 
+   The parameter ``type`` must be non-`void`.
+
    The parameter ``name`` must be non-NULL.  The call takes a copy of the
    underlying string, so it is valid to pass in a pointer to an on-stack
    buffer.
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index a29e9885e59..3d04f6db3af 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -527,6 +527,8 @@ gcc_jit_context_new_array_type (gcc_jit_context *ctxt,
   /* LOC can be NULL.  */
   RETURN_NULL_IF_FAIL (element_type, ctxt, loc, "NULL type");
   RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size");
+  RETURN_NULL_IF_FAIL (!element_type->is_void (), ctxt, loc,
+		       "void type for elements");
 
   return (gcc_jit_type *)ctxt->new_array_type (loc,
 					       element_type,
@@ -556,6 +558,11 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt,
     "unknown size for field \"%s\" (type: %s)",
     name,
     type->get_debug_string ());
+  RETURN_NULL_IF_FAIL_PRINTF1 (
+    !type->is_void (),
+    ctxt, loc,
+    "void type for field \"%s\"",
+    name);
 
   return (gcc_jit_field *)ctxt->new_field (loc, type, name);
 }
@@ -786,10 +793,15 @@ gcc_jit_context_new_function_ptr_type (gcc_jit_context *ctxt,
     ctxt, loc,
     "NULL param_types creating function pointer type");
   for (int i = 0; i < num_params; i++)
-    RETURN_NULL_IF_FAIL_PRINTF1 (
-      param_types[i],
-      ctxt, loc,
-      "NULL parameter type %i creating function pointer type", i);
+    {
+      RETURN_NULL_IF_FAIL_PRINTF1 (param_types[i],
+				   ctxt, loc,
+				   "NULL parameter type %i"
+				   " creating function pointer type", i);
+      RETURN_NULL_IF_FAIL_PRINTF1 (!param_types[i]->is_void (),
+				   ctxt, loc,
+				   "void type for param %i", i);
+    }
 
   return (gcc_jit_type*)
     ctxt->new_function_ptr_type (loc, return_type,
@@ -816,6 +828,9 @@ gcc_jit_context_new_param (gcc_jit_context *ctxt,
   /* LOC can be NULL.  */
   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
+  RETURN_NULL_IF_FAIL_PRINTF1 (!type->is_void (),
+			       ctxt, loc,
+			       "void type for param \"%s\"", name);
 
   return (gcc_jit_param *)ctxt->new_param (loc, type, name);
 }
@@ -1093,6 +1108,11 @@ gcc_jit_context_new_global (gcc_jit_context *ctxt,
     "unknown size for global \"%s\" (type: %s)",
     name,
     type->get_debug_string ());
+  RETURN_NULL_IF_FAIL_PRINTF1 (
+    !type->is_void (),
+    ctxt, loc,
+    "void type for global \"%s\"",
+    name);
 
   return (gcc_jit_lvalue *)ctxt->new_global (loc, kind, type, name);
 }
@@ -1911,6 +1931,11 @@ gcc_jit_function_new_local (gcc_jit_function *func,
     "unknown size for local \"%s\" (type: %s)",
     name,
     type->get_debug_string ());
+  RETURN_NULL_IF_FAIL_PRINTF1 (
+    !type->is_void (),
+    ctxt, loc,
+    "void type for local \"%s\"",
+    name);
 
   return (gcc_jit_lvalue *)func->new_local (loc, type, name);
 }
@@ -3068,6 +3093,7 @@ gcc_jit_type_get_aligned (gcc_jit_type *type,
     (pow2_or_zerop (alignment_in_bytes), ctxt, NULL,
      "alignment not a power of two: %zi",
      alignment_in_bytes);
+  RETURN_NULL_IF_FAIL (!type->is_void (), ctxt, NULL, "void type");
 
   return (gcc_jit_type *)type->get_aligned (alignment_in_bytes);
 }
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-void-type.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-void-type.c
new file mode 100644
index 00000000000..c310da6a885
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-void-type.c
@@ -0,0 +1,25 @@
+#include <libgccjit.h>
+
+#include "harness.h"
+
+/* Try to create a "void" global; the API ought to complain.  */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  gcc_jit_type *void_type
+    = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+  gcc_jit_context_new_global (ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED,
+			      void_type, "i");
+}
+
+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_global:"
+		      " void type for global \"i\"");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-void-type.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-void-type.c
new file mode 100644
index 00000000000..254abc0c146
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-void-type.c
@@ -0,0 +1,27 @@
+#include <libgccjit.h>
+
+#include "harness.h"
+
+/* Try to create a "void" local; the API ought to complain.  */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+    gcc_jit_type *void_type
+      = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+    gcc_jit_function *func
+      = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED,
+				      void_type, "test_fn", 0, NULL, 0);
+    gcc_jit_function_new_local(func, NULL, void_type, "i");
+}
+
+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_function_new_local:"
+		      " void type for local \"i\"");
+}
diff --git a/gcc/testsuite/jit.dg/test-fuzzer.c b/gcc/testsuite/jit.dg/test-fuzzer.c
index 6943d3ed232..4fd49dacf6d 100644
--- a/gcc/testsuite/jit.dg/test-fuzzer.c
+++ b/gcc/testsuite/jit.dg/test-fuzzer.c
@@ -96,7 +96,6 @@ fuzzer_init (fuzzer *f, gcc_jit_context *ctxt, unsigned int seed)
   for (i = 0; i < num_types; i++)
     {
       gcc_jit_type *type = make_random_type (f);
-      assert (type);
       f->types[f->num_types++] = type;
     }
 
@@ -188,7 +187,6 @@ get_random_type (fuzzer *f)
   if (i < NUM_TYPES)
     return gcc_jit_context_get_type (f->ctxt, types[i]);
   assert ((i - NUM_TYPES) < f->num_types);
-  assert (f->types[i - NUM_TYPES]);
   return f->types[i - NUM_TYPES];
 }
 
-- 
2.21.0


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-05-26 15:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-26 15:05 [committed] jit: check for void types [PR 95296] David Malcolm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).