Committed to branch dmalcolm/jit:

gcc/jit/
        * internal-api.c (gcc::jit::recording::memento_of_get_pointer::
        accepts_writes_from): Avoid segfaulting when the argument is not
        of pointer type.
        * internal-api.h (gcc::jit::recording::accepts_writes_from): Add
        an assertion.
        * libgccjit.c (gcc_jit_context_new_comparison): Strip away const
        and volatile when comparing input types.

gcc/testsuite/
        * jit.dg/test-error-mismatching-types-in-call.c: New test case,
        to ensure that a (struct foo *) vs (struct foo) type error is
        gracefully handled.
---
 gcc/jit/ChangeLog.jit                              | 10 +++
 gcc/jit/internal-api.c                             |  7 +-
 gcc/jit/internal-api.h                             |  1 +
 gcc/jit/libgccjit.c                                |  2 +-
 gcc/testsuite/ChangeLog.jit                        |  6 ++
 .../jit.dg/test-error-mismatching-types-in-call.c  | 80 ++++++++++++++++++++++
 6 files changed, 104 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c

diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index 56f7b85..b9172a1 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,5 +1,15 @@
 2014-03-04  David Malcolm  <dmalc...@redhat.com>
 
+       * internal-api.c (gcc::jit::recording::memento_of_get_pointer::
+       accepts_writes_from): Avoid segfaulting when the argument is not
+       of pointer type.
+       * internal-api.h (gcc::jit::recording::accepts_writes_from): Add
+       an assertion.
+       * libgccjit.c (gcc_jit_context_new_comparison): Strip away const
+       and volatile when comparing input types.
+
+2014-03-04  David Malcolm  <dmalc...@redhat.com>
+
        * libgccjit.h (gcc_jit_type_get_volatile): New.
        * libgccjit.map (gcc_jit_type_get_volatile): New.
        * libgccjit.c (gcc_jit_type_get_volatile): New.
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 539ba5e..835aa7f 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -891,9 +891,14 @@ recording::memento_of_get_type::make_debug_string ()
 bool
 recording::memento_of_get_pointer::accepts_writes_from (type *rtype)
 {
+  /* Must be a pointer type: */
+  type *rtype_points_to = rtype->dereference ();
+  if (!rtype_points_to)
+    return false;
+
   /* It's OK to assign to a (const T *) from a (T *).  */
   return m_other_type->unqualified ()
-    ->accepts_writes_from (rtype->dereference ());
+    ->accepts_writes_from (rtype_points_to);
 }
 
 void
diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h
index dd760c7..5c11085 100644
--- a/gcc/jit/internal-api.h
+++ b/gcc/jit/internal-api.h
@@ -480,6 +480,7 @@ public:
   /* Is it typesafe to copy to this type from rtype?  */
   virtual bool accepts_writes_from (type *rtype)
   {
+    gcc_assert (rtype);
     return this == rtype->unqualified ();
   }
 
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index b4c7d44..75fdfeb 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -784,7 +784,7 @@ gcc_jit_context_new_comparison (gcc_jit_context *ctxt,
   RETURN_NULL_IF_FAIL (a, ctxt, "NULL a");
   RETURN_NULL_IF_FAIL (b, ctxt, "NULL b");
   RETURN_NULL_IF_FAIL_PRINTF4 (
-    a->get_type () == b->get_type (),
+    a->get_type ()->unqualified () == b->get_type ()->unqualified (),
     ctxt,
     "mismatching types for comparison:"
     " a: %s (type: %s) b: %s (type: %s)",
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index f0548f4..f66a844 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,5 +1,11 @@
 2014-03-04  David Malcolm  <dmalc...@redhat.com>
 
+       * jit.dg/test-error-mismatching-types-in-call.c: New test case,
+       to ensure that a (struct foo *) vs (struct foo) type error is
+       gracefully handled.
+
+2014-03-04  David Malcolm  <dmalc...@redhat.com>
+
        * jit.dg/test-volatile.c: New testcase, to exercise
        gcc_jit_type_get_volatile, and show a way to work with pre-existing
        global variables.
diff --git a/gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c 
b/gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c
new file mode 100644
index 0000000..203c4ca
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c
@@ -0,0 +1,80 @@
+#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 inject the equivalent of:
+
+       struct foo;
+
+       extern void called_function (struct foo *ptr);
+
+       void
+       test_fn ()
+       {
+         struct foo f;
+        called_function (f);
+     }
+
+     and verify that we get a type error (foo * vs foo).
+  */
+  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_type *foo_ptr =
+    gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_foo));
+  gcc_jit_param *param =
+    gcc_jit_context_new_param (ctxt, NULL, foo_ptr, "ptr");
+
+  gcc_jit_function *called_function =
+    gcc_jit_context_new_function (ctxt, NULL,
+                                  GCC_JIT_FUNCTION_IMPORTED,
+                                  void_type,
+                                  "called_function",
+                                  1, &param,
+                                  0);
+
+  gcc_jit_function *test_fn =
+    gcc_jit_context_new_function (ctxt, NULL,
+                                  GCC_JIT_FUNCTION_EXPORTED,
+                                  void_type,
+                                  "test_fn",
+                                  0, NULL,
+                                  0);
+  gcc_jit_lvalue *f =
+    gcc_jit_function_new_local (
+      test_fn, NULL, gcc_jit_struct_as_type (struct_foo), "f");
+
+  gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
+
+  gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (f);
+
+  gcc_jit_block_add_eval (
+    block, NULL,
+    gcc_jit_context_new_call (
+      ctxt, NULL,
+      called_function,
+      1, &arg));
+  gcc_jit_block_end_with_void_return (block, NULL);
+}
+
+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_call:"
+                     " mismatching types for argument 1"
+                     " of function \"called_function\":"
+                     " assignment to param ptr (type: struct foo *)"
+                     " from f (type: struct foo)");
+}
+
-- 
1.7.11.7

Reply via email to