diff options
| -rw-r--r-- | gcc/jit/ChangeLog | 13 | ||||
| -rw-r--r-- | gcc/jit/dummy-frontend.c | 34 | ||||
| -rw-r--r-- | gcc/jit/jit-playback.c | 38 | ||||
| -rw-r--r-- | gcc/jit/jit-playback.h | 7 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
| -rw-r--r-- | gcc/testsuite/jit.dg/test-error-array-bounds.c | 72 |
6 files changed, 168 insertions, 0 deletions
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog index ae0a553..f9320ec 100644 --- a/gcc/jit/ChangeLog +++ b/gcc/jit/ChangeLog @@ -1,5 +1,18 @@ 2016-05-17 David Malcolm <dmalcolm@redhat.com> + * dummy-frontend.c: Include diagnostic.h. + (jit_begin_diagnostic): New function. + (jit_end_diagnostic): New function. + (jit_langhook_init): Register jit_begin_diagnostic + and jit_end_diagnostic with the global_dc. + * jit-playback.c: Include diagnostic.h. + (gcc::jit::playback::context::add_diagnostic): New method. + * jit-playback.h (struct diagnostic_context): Add forward + declaration. + (gcc::jit::playback::context::add_diagnostic): New method. + +2016-05-17 David Malcolm <dmalcolm@redhat.com> + * docs/topics/expressions.rst (Function calls): Document gcc_jit_context_new_call_through_ptr. * docs/_build/texinfo/libgccjit.texi: Regenerate. diff --git a/gcc/jit/dummy-frontend.c b/gcc/jit/dummy-frontend.c index 7194ba6..2631153 100644 --- a/gcc/jit/dummy-frontend.c +++ b/gcc/jit/dummy-frontend.c @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "debug.h" #include "langhooks.h" #include "langhooks-def.h" +#include "diagnostic.h" #include <mpfr.h> @@ -90,6 +91,35 @@ struct ggc_root_tab jit_root_tab[] = LAST_GGC_ROOT_TAB }; +/* JIT-specific implementation of diagnostic callbacks. */ + +/* Implementation of "begin_diagnostic". */ + +static void +jit_begin_diagnostic (diagnostic_context */*context*/, + diagnostic_info */*diagnostic*/) +{ + gcc_assert (gcc::jit::active_playback_ctxt); + JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ()); + + /* No-op (apart from logging); the real error-handling is done in the + "end_diagnostic" hook. */ +} + +/* Implementation of "end_diagnostic". */ + +static void +jit_end_diagnostic (diagnostic_context *context, + diagnostic_info *diagnostic) +{ + gcc_assert (gcc::jit::active_playback_ctxt); + JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ()); + + /* Delegate to the playback context (and thence to the + recording context). */ + gcc::jit::active_playback_ctxt->add_diagnostic (context, diagnostic); +} + /* Language hooks. */ static bool @@ -105,6 +135,10 @@ jit_langhook_init (void) registered_root_tab = true; } + gcc_assert (global_dc); + global_dc->begin_diagnostic = jit_begin_diagnostic; + global_dc->end_diagnostic = jit_end_diagnostic; + build_common_tree_nodes (false); /* I don't know why this has to be done explicitly. */ diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c index 579230d..156448d 100644 --- a/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "context.h" #include "fold-const.h" #include "gcc.h" +#include "diagnostic.h" #include <pthread.h> @@ -2833,6 +2834,43 @@ add_error_va (location *loc, const char *fmt, va_list ap) fmt, ap); } +/* Report a diagnostic up to the jit context as an error, + so that the compilation is treated as a failure. + For now, any kind of diagnostic is treated as an error by the jit + API. */ + +void +playback::context:: +add_diagnostic (struct diagnostic_context *diag_context, + struct diagnostic_info *diagnostic) +{ + /* At this point the text has been formatted into the pretty-printer's + output buffer. */ + pretty_printer *pp = diag_context->printer; + const char *text = pp_formatted_text (pp); + + /* Get location information (if any) from the diagnostic. + The recording::context::add_error[_va] methods require a + recording::location. We can't lookup the playback::location + from the file/line/column since any playback location instances + may have been garbage-collected away by now, so instead we create + another recording::location directly. */ + location_t gcc_loc = diagnostic_location (diagnostic); + recording::location *rec_loc = NULL; + if (gcc_loc) + { + expanded_location exploc = expand_location (gcc_loc); + if (exploc.file) + rec_loc = m_recording_ctxt->new_location (exploc.file, + exploc.line, + exploc.column, + false); + } + + m_recording_ctxt->add_error (rec_loc, "%s", text); + pp_clear_output_area (pp); +} + /* Dealing with the linemap API. */ /* Construct a playback::location for a recording::location, if it diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index 905747c..8f7a43d 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -27,6 +27,9 @@ along with GCC; see the file COPYING3. If not see #include "jit-recording.h" +struct diagnostic_context; +struct diagnostic_info; + namespace gcc { namespace jit { @@ -203,6 +206,10 @@ public: get_first_error () const; void + add_diagnostic (struct diagnostic_context *context, + struct diagnostic_info *diagnostic); + + void set_tree_location (tree t, location *loc); tree diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0e648e5..cb5940e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-05-17 David Malcolm <dmalcolm@redhat.com> + + * jit.dg/test-error-array-bounds.c: New test case. + 2016-05-17 Marc Glisse <marc.glisse@inria.fr> * gcc.dg/tree-ssa/and-1.c: New testcase. diff --git a/gcc/testsuite/jit.dg/test-error-array-bounds.c b/gcc/testsuite/jit.dg/test-error-array-bounds.c new file mode 100644 index 0000000..732ec87 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-array-bounds.c @@ -0,0 +1,72 @@ +#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: + char + test_array_bounds (void) + { + char buffer[10]; + return buffer[10]; + } + with -Warray-bounds and -ftree-vrp and verify that the + out-of-bounds access is detected and reported as a jit error. */ + gcc_jit_context_add_command_line_option (ctxt, "-Warray-bounds"); + gcc_jit_context_add_command_line_option (ctxt, "-ftree-vrp"); + + /* Ensure that the error message doesn't contain colorization codes, + even if run at a TTY. */ + gcc_jit_context_add_command_line_option (ctxt, "-fdiagnostics-color=never"); + + gcc_jit_type *char_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR); + gcc_jit_type *array_type = + gcc_jit_context_new_array_type (ctxt, NULL, + char_type, 10); + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + /* Build the test_fn. */ + gcc_jit_function *test_fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + char_type, + "test_array_bounds", + 0, NULL, + 0); + gcc_jit_lvalue *buffer = + gcc_jit_function_new_local (test_fn, NULL, array_type, "buffer"); + + /* tree-vrp.c:check_all_array_refs only checks array lookups that + have source locations. */ + gcc_jit_location *dummy_loc = + gcc_jit_context_new_location (ctxt, "dummy.c", 10, 4); + + gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); + gcc_jit_rvalue *index = + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 10); + gcc_jit_lvalue *read_of_the_buffer = + gcc_jit_context_new_array_access (ctxt, dummy_loc, + gcc_jit_lvalue_as_rvalue (buffer), + index); + gcc_jit_block_end_with_return ( + block, dummy_loc, + gcc_jit_lvalue_as_rvalue (read_of_the_buffer)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + /* Verify that the diagnostic led to the context failing... */ + CHECK_VALUE (result, NULL); + + /* ...and that the message was captured by the API. */ + CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt), + "array subscript is above array bounds [-Warray-bounds]"); +} |
