@@ -1,5 +1,17 @@
2014-11-05 David Malcolm <dmalcolm@redhat.com>
+ * libgccjit.c (gcc_jit_context_get_type): Verify that "type"
+ is valid immediately, rather than relying on called code.
+ (gcc_jit_context_new_function): Likewise for "kind".
+ (gcc_jit_context_new_unary_op): Likewise for "op".
+ (valid_binary_op_p): New.
+ (gcc_jit_context_new_binary_op): Verify that "op" is valid
+ immediately, rather than relying on called code.
+ (gcc_jit_context_new_comparison): Likewise.
+ (gcc_jit_block_add_assignment_op): Likewise.
+
+2014-11-05 David Malcolm <dmalcolm@redhat.com>
+
* libgccjit.c: Include safe-ctype.h from libiberty.
(IS_ASCII_ALPHA): Delete.
(IS_ASCII_DIGIT): Delete.
@@ -316,7 +316,11 @@ gcc_jit_context_get_type (gcc_jit_context *ctxt,
enum gcc_jit_types type)
{
RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
- /* The inner function checks "type" for us. */
+ RETURN_NULL_IF_FAIL_PRINTF1 (
+ (type >= GCC_JIT_TYPE_VOID
+ && type <= GCC_JIT_TYPE_FILE_PTR),
+ ctxt, NULL,
+ "unrecognized value for enum gcc_jit_types: %i", type);
return (gcc_jit_type *)ctxt->get_type (type);
}
@@ -574,6 +578,12 @@ gcc_jit_context_new_function (gcc_jit_context *ctxt,
int is_variadic)
{
RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+ RETURN_NULL_IF_FAIL_PRINTF1 (
+ ((kind >= GCC_JIT_FUNCTION_EXPORTED)
+ && (kind <= GCC_JIT_FUNCTION_ALWAYS_INLINE)),
+ ctxt, loc,
+ "unrecognized value for enum gcc_jit_function_kind: %i",
+ kind);
RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
/* The assembler can only handle certain names, so for now, enforce
@@ -835,13 +845,29 @@ gcc_jit_context_new_unary_op (gcc_jit_context *ctxt,
gcc_jit_rvalue *rvalue)
{
RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
- /* op is checked by the inner function. */
+ RETURN_NULL_IF_FAIL_PRINTF1 (
+ (op >= GCC_JIT_UNARY_OP_MINUS
+ && op <= GCC_JIT_UNARY_OP_LOGICAL_NEGATE),
+ ctxt, loc,
+ "unrecognized value for enum gcc_jit_unary_op: %i",
+ op);
RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
return (gcc_jit_rvalue *)ctxt->new_unary_op (loc, op, result_type, rvalue);
}
+/* Determine if OP is a valid value for enum gcc_jit_binary_op.
+ For use by both gcc_jit_context_new_binary_op and
+ gcc_jit_block_add_assignment_op. */
+
+static bool
+valid_binary_op_p (enum gcc_jit_binary_op op)
+{
+ return (op >= GCC_JIT_BINARY_OP_PLUS
+ && op <= GCC_JIT_BINARY_OP_RSHIFT);
+}
+
gcc_jit_rvalue *
gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
gcc_jit_location *loc,
@@ -850,7 +876,11 @@ gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
gcc_jit_rvalue *a, gcc_jit_rvalue *b)
{
RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
- /* op is checked by the inner function. */
+ RETURN_NULL_IF_FAIL_PRINTF1 (
+ valid_binary_op_p (op),
+ ctxt, loc,
+ "unrecognized value for enum gcc_jit_binary_op: %i",
+ op);
RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
@@ -874,7 +904,12 @@ gcc_jit_context_new_comparison (gcc_jit_context *ctxt,
gcc_jit_rvalue *a, gcc_jit_rvalue *b)
{
RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
- /* op is checked by the inner function. */
+ RETURN_NULL_IF_FAIL_PRINTF1 (
+ (op >= GCC_JIT_COMPARISON_EQ
+ && op <= GCC_JIT_COMPARISON_GE),
+ ctxt, loc,
+ "unrecognized value for enum gcc_jit_comparison: %i",
+ op);
RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
RETURN_NULL_IF_FAIL_PRINTF4 (
@@ -1281,7 +1316,11 @@ gcc_jit_block_add_assignment_op (gcc_jit_block *block,
RETURN_IF_NOT_VALID_BLOCK (block, loc);
gcc::jit::recording::context *ctxt = block->get_context ();
RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
- /* FIXME: op is checked by new_binary_op */
+ RETURN_IF_FAIL_PRINTF1 (
+ valid_binary_op_p (op),
+ ctxt, loc,
+ "unrecognized value for enum gcc_jit_binary_op: %i",
+ op);
RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
return block->add_assignment_op (loc, lvalue, op, rvalue);
@@ -1,3 +1,10 @@
+2014-11-05 David Malcolm <dmalcolm@redhat.com>
+
+ * jit.dg/test-error-get-type-bad-enum.c: New test case.
+ * jit.dg/test-error-new-binary-op-bad-op.c: Likewise.
+ * jit.dg/test-error-new-function-bad-kind.c: Likewise.
+ * jit.dg/test-error-new-unary-op-bad-op.c: Likewise.
+
2014-10-22 David Malcolm <dmalcolm@redhat.com>
* jit.dg/jit.exp (DEFAULT_CFLAGS): Add -fgnu89-inline since
new file mode 100644
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Trigger an API error by passing bad data. */
+ gcc_jit_context_get_type (ctxt, 42);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_get_type:"
+ " unrecognized value for enum gcc_jit_types: 42"));
+}
+
new file mode 100644
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Trigger an API error by passing bad data. */
+ (void)gcc_jit_context_new_binary_op (
+ ctxt,
+ NULL,
+
+ /* Non-valid enum value: */
+ (enum gcc_jit_binary_op) 42,
+
+ /* These aren't valid either: */
+ NULL, /* gcc_jit_type *result_type, */
+ NULL, NULL); /* gcc_jit_rvalue *a, gcc_jit_rvalue *b */
+
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_binary_op:"
+ " unrecognized value for enum gcc_jit_binary_op: 42"));
+}
+
new file mode 100644
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+ /* Trigger an API error by passing bad data. */
+ (void)gcc_jit_context_new_function (
+ ctxt,
+ NULL,
+
+ /* Non-valid enum value: */
+ (enum gcc_jit_function_kind)42,
+
+ int_type, /* gcc_jit_type *return_type, */
+ "foo", /* const char *name, */
+ 0, /* int num_params, */
+ NULL, /* gcc_jit_param **params, */
+ 0); /* int is_variadic */
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_function:"
+ " unrecognized value for enum gcc_jit_function_kind: 42"));
+}
+
new file mode 100644
@@ -0,0 +1,36 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Trigger an API error by passing bad data. */
+ (void)gcc_jit_context_new_unary_op (
+ ctxt,
+ NULL,
+
+ /* Non-valid enum value: */
+ (enum gcc_jit_unary_op) 42,
+
+ /* These aren't valid either: */
+ NULL, /* gcc_jit_type *result_type, */
+ NULL); /* gcc_jit_rvalue *rvalue */
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_unary_op:"
+ " unrecognized value for enum gcc_jit_unary_op: 42"));
+}
+