PR jit/66783: prevent use of opaque structs
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 7 Jul 2015 19:29:58 +0000 (19:29 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Tue, 7 Jul 2015 19:29:58 +0000 (19:29 +0000)
gcc/jit/ChangeLog:
PR jit/66783
* jit-recording.h: Within namespace gcc:jit::recording...
(type::has_known_size): New virtual function.
(struct_has_known_size): New function.
* libgccjit.c (gcc_jit_context_new_field): Verify that the type
has a known size.
(gcc_jit_context_new_global): Likewise.
(gcc_jit_function_new_local): Likewise.

gcc/testsuite/ChangeLog:
PR jit/66783
* jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c: New
test case.
* jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c:
New test case.
* jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c:
New test case.
* jit.dg/test-error-mismatching-types-in-call.c (create_code):
Avoid using an opaque struct for local "f".

From-SVN: r225523

gcc/jit/ChangeLog
gcc/jit/jit-recording.h
gcc/jit/libgccjit.c
gcc/testsuite/ChangeLog
gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c [new file with mode: 0644]
gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c [new file with mode: 0644]
gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c [new file with mode: 0644]
gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c

index c38fd5092faa5baba090e6b3f223a21826e14b44..dbead11e0e28d40716b91393a9f0db36056129f7 100644 (file)
@@ -1,3 +1,14 @@
+2015-07-07  David Malcolm  <dmalcolm@redhat.com>
+
+       PR jit/66783
+       * jit-recording.h: Within namespace gcc:jit::recording...
+       (type::has_known_size): New virtual function.
+       (struct_has_known_size): New function.
+       * libgccjit.c (gcc_jit_context_new_field): Verify that the type
+       has a known size.
+       (gcc_jit_context_new_global): Likewise.
+       (gcc_jit_function_new_local): Likewise.
+
 2015-07-07  David Malcolm  <dmalcolm@redhat.com>
 
        PR jit/66779
index acd69e9b78c29fa49021ca2f267569cde18a185a..884304b0ff832a91cd8474fd9b4e92be03221e85 100644 (file)
@@ -497,6 +497,7 @@ public:
   virtual type *is_pointer () = 0;
   virtual type *is_array () = 0;
   virtual bool is_void () const { return false; }
+  virtual bool has_known_size () const { return true; }
 
   bool is_numeric () const
   {
@@ -795,6 +796,8 @@ public:
   type *is_pointer () { return NULL; }
   type *is_array () { return NULL; }
 
+  bool has_known_size () const { return m_fields != NULL; }
+
   playback::compound_type *
   playback_compound_type ()
   {
index 4d7dd8cf40f66bc642f98a5a33a2ca5145367768..85d9f62f041f801a7f30b2a1881e5595dd8a491c 100644 (file)
@@ -543,6 +543,11 @@ gcc_jit_context_new_field (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->has_known_size (),
+    ctxt, loc,
+    "type has unknown size (type: %s)",
+    type->get_debug_string ());
 
   return (gcc_jit_field *)ctxt->new_field (loc, type, name);
 }
@@ -1033,6 +1038,11 @@ gcc_jit_context_new_global (gcc_jit_context *ctxt,
     kind);
   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
+  RETURN_NULL_IF_FAIL_PRINTF1 (
+    type->has_known_size (),
+    ctxt, loc,
+    "type has unknown size (type: %s)",
+    type->get_debug_string ());
 
   return (gcc_jit_lvalue *)ctxt->new_global (loc, kind, type, name);
 }
@@ -1829,6 +1839,11 @@ gcc_jit_function_new_local (gcc_jit_function *func,
                       "Cannot add locals to an imported function");
   RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
   RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
+  RETURN_NULL_IF_FAIL_PRINTF1 (
+    type->has_known_size (),
+    ctxt, loc,
+    "type has unknown size (type: %s)",
+    type->get_debug_string ());
 
   return (gcc_jit_lvalue *)func->new_local (loc, type, name);
 }
index fb5d57fbc0ee73d370876c0c4848bc78d34293f2..ca13429495f222b0982c7f44185c5d929ecfd27b 100644 (file)
@@ -1,3 +1,15 @@
+2015-07-07  David Malcolm  <dmalcolm@redhat.com>
+
+       PR jit/66783
+       * jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c: New
+       test case.
+       * jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c:
+       New test case.
+       * jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c:
+       New test case.
+       * jit.dg/test-error-mismatching-types-in-call.c (create_code):
+       Avoid using an opaque struct for local "f".
+
 2015-07-07  David Malcolm  <dmalcolm@redhat.com>
 
        PR jit/66779
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c
new file mode 100644 (file)
index 0000000..c4e1448
--- /dev/null
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/* Try to put an opaque struct inside another struct
+   (or union); the API ought to complain.  */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  gcc_jit_struct *t_opaque =
+    gcc_jit_context_new_opaque_struct (ctxt, NULL, "opaque");
+
+  (void)gcc_jit_context_new_field (ctxt, NULL,
+                                  gcc_jit_struct_as_type (t_opaque),
+                                  "f_opaque");
+}
+
+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_field:"
+                     " type has unknown size (type: struct opaque)");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c
new file mode 100644 (file)
index 0000000..5f096af
--- /dev/null
@@ -0,0 +1,32 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/* Try to create a global of an opaque struct;
+   the API ought to complain.  */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  gcc_jit_struct *t_opaque =
+    gcc_jit_context_new_opaque_struct (ctxt, NULL, "opaque");
+
+  (void)gcc_jit_context_new_global (ctxt, NULL,
+                                   GCC_JIT_GLOBAL_EXPORTED,
+                                   gcc_jit_struct_as_type (t_opaque),
+                                   "instance_of_opaque");
+}
+
+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:"
+                     " type has unknown size (type: struct opaque)");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c
new file mode 100644 (file)
index 0000000..f263d67
--- /dev/null
@@ -0,0 +1,42 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/* Try to create a local of an opaque struct;
+   the API ought to complain.  */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  gcc_jit_type *t_void =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+
+  gcc_jit_struct *t_opaque =
+    gcc_jit_context_new_opaque_struct (ctxt, NULL, "opaque");
+
+  gcc_jit_function *func =
+    gcc_jit_context_new_function (ctxt, NULL,
+                                  GCC_JIT_FUNCTION_EXPORTED,
+                                  t_void,
+                                  "test_fn",
+                                 0, NULL,
+                                  0);
+
+  (void)gcc_jit_function_new_local (func, NULL,
+                                   gcc_jit_struct_as_type (t_opaque),
+                                   "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:"
+                     " type has unknown size (type: struct opaque)");
+}
index 203c4cae5323be2e7e4ec775bf54fd89b23404f5..e89c281699a0815b1f5e8757c6bac48242c7c1ee 100644 (file)
@@ -26,7 +26,7 @@ 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_struct *struct_foo =
-    gcc_jit_context_new_opaque_struct (ctxt, NULL, "foo");
+    gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 0, NULL);
   gcc_jit_type *foo_ptr =
     gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_foo));
   gcc_jit_param *param =