From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5979 invoked by alias); 5 Nov 2014 18:00:24 -0000 Mailing-List: contact jit-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Subscribe: Sender: jit-owner@gcc.gnu.org Received: (qmail 5893 invoked by uid 89); 5 Nov 2014 18:00:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.98.4 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com From: David Malcolm To: gcc-patches@gcc.gnu.org, jit@gcc.gnu.org Cc: David Malcolm Subject: [jit] Verify enum values earlier Date: Wed, 01 Jan 2014 00:00:00 -0000 Message-Id: <1415210151-3228-1-git-send-email-dmalcolm@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-SW-Source: 2014-q4/txt/msg00124.txt.bz2 It wasn't clear to me that all of these enum values were being fully validated by the internals, and it's better to fail early (so we can report which function was at fault), so explicitly validate enum values at the API entrypoints. The new testcases bring the # of expected passes in jit.sum from 4663 to 4711. Committed to the dmalcolm/jit branch. gcc/jit/ChangeLog.jit: * 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. gcc/testsuite/ChangeLog.jit: * 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. --- gcc/jit/ChangeLog.jit | 12 ++++++ gcc/jit/libgccjit.c | 49 +++++++++++++++++++--- gcc/testsuite/ChangeLog.jit | 7 ++++ .../jit.dg/test-error-get-type-bad-enum.c | 27 ++++++++++++ .../jit.dg/test-error-new-binary-op-bad-op.c | 37 ++++++++++++++++ .../jit.dg/test-error-new-function-bad-kind.c | 41 ++++++++++++++++++ .../jit.dg/test-error-new-unary-op-bad-op.c | 36 ++++++++++++++++ 7 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-error-get-type-bad-enum.c create mode 100644 gcc/testsuite/jit.dg/test-error-new-binary-op-bad-op.c create mode 100644 gcc/testsuite/jit.dg/test-error-new-function-bad-kind.c create mode 100644 gcc/testsuite/jit.dg/test-error-new-unary-op-bad-op.c diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index 3d6361c..ce927d6 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,5 +1,17 @@ 2014-11-05 David Malcolm + * 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 + * libgccjit.c: Include safe-ctype.h from libiberty. (IS_ASCII_ALPHA): Delete. (IS_ASCII_DIGIT): Delete. diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index d9f259e..c109ba6 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -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); diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit index 2d6acdb..a850c6f 100644 --- a/gcc/testsuite/ChangeLog.jit +++ b/gcc/testsuite/ChangeLog.jit @@ -1,3 +1,10 @@ +2014-11-05 David Malcolm + + * 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 * jit.dg/jit.exp (DEFAULT_CFLAGS): Add -fgnu89-inline since diff --git a/gcc/testsuite/jit.dg/test-error-get-type-bad-enum.c b/gcc/testsuite/jit.dg/test-error-get-type-bad-enum.c new file mode 100644 index 0000000..67b712e --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-get-type-bad-enum.c @@ -0,0 +1,27 @@ +#include +#include + +#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")); +} + diff --git a/gcc/testsuite/jit.dg/test-error-new-binary-op-bad-op.c b/gcc/testsuite/jit.dg/test-error-new-binary-op-bad-op.c new file mode 100644 index 0000000..0592f55 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-new-binary-op-bad-op.c @@ -0,0 +1,37 @@ +#include +#include + +#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")); +} + diff --git a/gcc/testsuite/jit.dg/test-error-new-function-bad-kind.c b/gcc/testsuite/jit.dg/test-error-new-function-bad-kind.c new file mode 100644 index 0000000..f9772de --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-new-function-bad-kind.c @@ -0,0 +1,41 @@ +#include +#include + +#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")); +} + diff --git a/gcc/testsuite/jit.dg/test-error-new-unary-op-bad-op.c b/gcc/testsuite/jit.dg/test-error-new-unary-op-bad-op.c new file mode 100644 index 0000000..faab139 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-new-unary-op-bad-op.c @@ -0,0 +1,36 @@ +#include +#include + +#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")); +} + -- 1.7.11.7