diff options
author | David Malcolm <dmalcolm@redhat.com> | 2014-12-01 15:58:11 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2014-12-01 15:58:11 +0000 |
commit | c985705ae91243bdabd4d828365017ef264bbd91 (patch) | |
tree | b68a1a2418f0312b0d2fcf8079fb1e32fefd48aa /gcc | |
parent | 81f263694d6451a17f7d6d3753fae85a01243619 (diff) | |
download | gcc-c985705ae91243bdabd4d828365017ef264bbd91.zip gcc-c985705ae91243bdabd4d828365017ef264bbd91.tar.gz gcc-c985705ae91243bdabd4d828365017ef264bbd91.tar.bz2 |
PR jit/63969: Fix segfault in error-handling when driver isn't found
gcc/jit/ChangeLog:
PR jit/63969
* jit-playback.c: Ensure that ctxt_progname is non-NULL.
gcc/testsuite/ChangeLog:
PR jit/63969
* jit.dg/harness.h (CHECK_STRING_STARTS_WITH): New.
(check_string_starts_with): New.
* jit.dg/test-error-pr63969-missing-driver.c: New.
From-SVN: r218226
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/jit/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/jit/jit-playback.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/jit.dg/harness.h | 31 | ||||
-rw-r--r-- | gcc/testsuite/jit.dg/test-error-pr63969-missing-driver.c | 38 |
5 files changed, 88 insertions, 2 deletions
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog index f0136b4..9555e72 100644 --- a/gcc/jit/ChangeLog +++ b/gcc/jit/ChangeLog @@ -1,3 +1,8 @@ +2014-12-01 David Malcolm <dmalcolm@redhat.com> + + PR jit/63969 + * jit-playback.c: Ensure that ctxt_progname is non-NULL. + 2014-11-19 David Malcolm <dmalcolm@redhat.com> PR jit/63854 diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c index 8fdfa29..584a8e6 100644 --- a/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -1571,9 +1571,11 @@ compile () /* Pass in user-provided program name as argv0, if any, so that it makes it into GCC's "progname" global, used in various diagnostics. */ ctxt_progname = get_str_option (GCC_JIT_STR_OPTION_PROGNAME); - fake_args[0] = - (ctxt_progname ? ctxt_progname : "libgccjit.so"); + if (!ctxt_progname) + ctxt_progname = "libgccjit.so"; + + fake_args[0] = ctxt_progname; fake_args[1] = m_path_c_file; num_args = 2; @@ -1689,6 +1691,9 @@ compile () /* pex argv arrays are NULL-terminated. */ argv[6] = NULL; + /* pex_one's error-handling requires pname to be non-NULL. */ + gcc_assert (ctxt_progname); + errmsg = pex_one (PEX_SEARCH, /* int flags, */ gcc_driver_name, const_cast<char * const *> (argv), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 94ca3b6..d86e406 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2014-12-01 David Malcolm <dmalcolm@redhat.com> + PR jit/63969 + * jit.dg/harness.h (CHECK_STRING_STARTS_WITH): New. + (check_string_starts_with): New. + * jit.dg/test-error-pr63969-missing-driver.c: New. + +2014-12-01 David Malcolm <dmalcolm@redhat.com> + * jit.dg/jit.exp (jit-dg-test): Use $name rathen than $prog when calling jit_check_compile to avoid embedding the full path of the testcase into the test results. diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h index f326891..bff64de 100644 --- a/gcc/testsuite/jit.dg/harness.h +++ b/gcc/testsuite/jit.dg/harness.h @@ -81,6 +81,9 @@ static char test[1024]; #define CHECK_STRING_VALUE(ACTUAL, EXPECTED) \ check_string_value ((ACTUAL), (EXPECTED)); +#define CHECK_STRING_STARTS_WITH(ACTUAL, EXPECTED_PREFIX) \ + check_string_starts_with ((ACTUAL), (EXPECTED_PREFIX)); + #define CHECK(COND) \ do { \ if (COND) \ @@ -103,6 +106,10 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result); extern void check_string_value (const char *actual, const char *expected); +extern void +check_string_starts_with (const char *actual, + const char *expected_prefix); + /* Implement framework needed for turning the testcase hooks into an executable. test-combination.c and test-threads.c each combine multiple testcases into larger testcases, so we have COMBINED_TEST as a way of @@ -137,6 +144,30 @@ void check_string_value (const char *actual, const char *expected) pass ("%s: actual: NULL == expected: NULL"); } +void +check_string_starts_with (const char *actual, + const char *expected_prefix) +{ + if (!actual) + { + fail ("%s: actual: NULL != expected prefix: \"%s\"", + test, expected_prefix); + fprintf (stderr, "incorrect value\n"); + abort (); + } + + if (strncmp (actual, expected_prefix, strlen (expected_prefix))) + { + fail ("%s: actual: \"%s\" did not begin with expected prefix: \"%s\"", + test, actual, expected_prefix); + fprintf (stderr, "incorrect value\n"); + abort (); + } + + pass ("%s: actual: \"%s\" begins with expected prefix: \"%s\"", + test, actual, expected_prefix); +} + static void set_options (gcc_jit_context *ctxt, const char *argv0) { /* Set up options. */ diff --git a/gcc/testsuite/jit.dg/test-error-pr63969-missing-driver.c b/gcc/testsuite/jit.dg/test-error-pr63969-missing-driver.c new file mode 100644 index 0000000..13f5e3b --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-pr63969-missing-driver.c @@ -0,0 +1,38 @@ +/* PR jit/63969: libgccjit would segfault inside gcc_jit_context_compile + if the driver wasn't found on PATH if GCC_JIT_STR_OPTION_PROGNAME was + NULL. */ + +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Create nothing within the context. */ + + /* harness.h's set_options has set a sane value for + GCC_JIT_STR_OPTION_PROGNAME, but PR jit/63969 only segfaulted if it's + NULL. + + Unset it. */ + gcc_jit_context_set_str_option (ctxt, GCC_JIT_STR_OPTION_PROGNAME, NULL); + + /* Break PATH, so that the driver can't be found + by gcc::jit::playback::context::compile () + within gcc_jit_context_compile. */ + unsetenv ("PATH"); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_VALUE (result, NULL); + + /* Verify that a sane error message was emitted. */ + CHECK_STRING_STARTS_WITH (gcc_jit_context_get_first_error (ctxt), + "error invoking gcc driver"); +} |