This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, committed] jit: prevent ICE with type mismatch in gcc_jit_block_add_assignment_op


gcc_jit_block_add_assignment_op was missing type-checking on the params,
which could lead to an ICE deep inside gimplification in fold-const.c:
10339   gcc_assert (TYPE_PRECISION (atype) == TYPE_PRECISION (type));

Takes jit.sum's # of expected passes from 7494 to 7514.

Committed to trunk as r219681.

(FWIW I generated the test case using
gcc_jit_context_dump_reproducer_to_file and minimized it by hand)

gcc/jit/ChangeLog:
	* libgccjit.c (gcc_jit_block_add_assignment_op): Check that the
	lvalue and the rvalue are of compatible type.

gcc/testsuite/ChangeLog:
	* jit.dg/test-error-mismatching-types-in-assignment-op.c: New
	test case.
---
 gcc/jit/libgccjit.c                                | 10 ++++
 ...test-error-mismatching-types-in-assignment-op.c | 64 ++++++++++++++++++++++
 2 files changed, 74 insertions(+)
 create mode 100644 gcc/testsuite/jit.dg/test-error-mismatching-types-in-assignment-op.c

diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index a78b3e7..0faf0f9 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -1900,6 +1900,16 @@ gcc_jit_block_add_assignment_op (gcc_jit_block *block,
     "unrecognized value for enum gcc_jit_binary_op: %i",
     op);
   RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
+  RETURN_IF_FAIL_PRINTF4 (
+    compatible_types (lvalue->get_type (),
+		      rvalue->get_type ()),
+    ctxt, loc,
+    "mismatching types:"
+    " assignment to %s (type: %s) involving %s (type: %s)",
+    lvalue->get_debug_string (),
+    lvalue->get_type ()->get_debug_string (),
+    rvalue->get_debug_string (),
+    rvalue->get_type ()->get_debug_string ());
 
   gcc::jit::recording::statement *stmt = block->add_assignment_op (loc, lvalue, op, rvalue);
 
diff --git a/gcc/testsuite/jit.dg/test-error-mismatching-types-in-assignment-op.c b/gcc/testsuite/jit.dg/test-error-mismatching-types-in-assignment-op.c
new file mode 100644
index 0000000..c86d334
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-mismatching-types-in-assignment-op.c
@@ -0,0 +1,64 @@
+#include <libgccjit.h>
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+  /* Try to inject the equivalent of:
+        static int idx;
+        void test_func (void)
+	{
+	  idx += (unsigned char)1; // mismatching type
+	}
+     and verify that we don't get an ICE inside gimplification
+     due to the type mismatch.  */
+  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);
+  gcc_jit_type *unsigned_char_type =
+    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR);
+  gcc_jit_function *test_func =
+    gcc_jit_context_new_function (ctxt, /* gcc_jit_context *ctxt */
+                                  NULL, /* gcc_jit_location *loc */
+                                  GCC_JIT_FUNCTION_EXPORTED, /* enum gcc_jit_function_kind kind */
+                                  void_type, /* gcc_jit_type *return_type */
+                                  "test_func", /* const char *name */
+                                  0, /* int num_params */
+                                  NULL, /* gcc_jit_param **params */
+                                  0); /* int is_variadic */
+  gcc_jit_block *block =
+    gcc_jit_function_new_block (test_func, "initial");
+
+  gcc_jit_rvalue *unsigned_char_1 =
+    gcc_jit_context_new_rvalue_from_int (ctxt, /* gcc_jit_context *ctxt */
+                                         unsigned_char_type, /* gcc_jit_type *numeric_type */
+                                         1); /* int value */
+  gcc_jit_lvalue *idx =
+    gcc_jit_context_new_global (ctxt, /* gcc_jit_context *ctxt */
+                                NULL, /* gcc_jit_location *loc */
+                                GCC_JIT_GLOBAL_INTERNAL, /* enum gcc_jit_global_kind kind */
+                                int_type, /* gcc_jit_type *type */
+                                "idx"); /* const char *name */
+
+  gcc_jit_block_add_assignment_op (block, /*gcc_jit_block *block */
+                                   NULL, /* gcc_jit_location *loc */
+                                   idx, /* gcc_jit_lvalue *lvalue */
+                                   GCC_JIT_BINARY_OP_PLUS, /* enum gcc_jit_binary_op op */
+                                   unsigned_char_1); /* gcc_jit_rvalue *rvalue */
+  gcc_jit_block_end_with_void_return (block, /*gcc_jit_block *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_block_add_assignment_op:"
+		      " mismatching types:"
+		      " assignment to idx (type: int)"
+		      " involving (unsigned char)1 (type: unsigned char)")
+}
-- 
1.8.5.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]