aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2014-12-01 15:58:11 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2014-12-01 15:58:11 +0000
commitc985705ae91243bdabd4d828365017ef264bbd91 (patch)
treeb68a1a2418f0312b0d2fcf8079fb1e32fefd48aa /gcc
parent81f263694d6451a17f7d6d3753fae85a01243619 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/jit/jit-playback.c9
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/jit.dg/harness.h31
-rw-r--r--gcc/testsuite/jit.dg/test-error-pr63969-missing-driver.c38
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");
+}