summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/plugin.c254
-rw-r--r--gcc/testsuite/gcc.dg/plugin/empty_plugin.c31
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin-args-order-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin-args-order-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin-args-order-3.c5
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin-args-order-4.c5
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin-args-order-5.c5
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin-args-order-6.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin-args-order-7.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp45
-rw-r--r--gcc/testsuite/gcc.dg/plugin/pluginarg1.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/pluginarg2.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/pluginarg3.c5
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugindir1.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugindir2.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugindir3.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugindir4.c2
-rw-r--r--gcc/testsuite/lib/plugin-support.exp35
18 files changed, 353 insertions, 64 deletions
diff --git a/gcc/plugin.c b/gcc/plugin.c
index 60081a5a53b..a9ac58b6ff3 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -88,6 +88,10 @@ static int event_horizon = PLUGIN_EVENT_FIRST_DYNAMIC;
parsing. */
static htab_t plugin_name_args_tab = NULL;
+/* Hash table for the deferred plugin_name_args objects created during command-line
+ parsing. */
+static htab_t plugin_deferred_name_args_tab = NULL;
+
/* List node for keeping track of plugin-registered callback. */
struct callback_info
{
@@ -140,13 +144,54 @@ get_plugin_base_name (const char *full_name)
return base_name;
}
+/* Remove plugin from deferred hash table if found. */
+
+static void
+maybe_remove_deferred_plugin (void **new_plugin_slot)
+{
+ void **slot;
+ struct plugin_name_args *plugin;
+ struct plugin_name_args *defered_plugin;
+
+ gcc_assert (new_plugin_slot);
+ plugin = (struct plugin_name_args *)*new_plugin_slot;
+
+ /* If deferred plugin table is empty - do nothing. */
+ if (!plugin_deferred_name_args_tab
+ || !htab_elements (plugin_deferred_name_args_tab))
+ return;
+
+ gcc_assert (plugin);
+
+ slot = htab_find_slot_with_hash(plugin_deferred_name_args_tab,
+ plugin->base_name,
+ htab_hash_string(plugin->base_name),
+ NO_INSERT);
+
+ if (!slot)
+ return;
+
+ /* If slot is found - append plugin arguments and remove item from deferred
+ table. */
+ defered_plugin = (struct plugin_name_args *)*slot;
+
+ /* Transfer saved arguments. */
+ if (defered_plugin->argc) {
+ plugin->argc = defered_plugin->argc;
+ plugin->argv = defered_plugin->argv;
+ }
+
+ free (defered_plugin);
+ htab_clear_slot (plugin_deferred_name_args_tab, slot);
+}
+
/* Create a plugin_name_args object for the given plugin and insert it
to the hash table. This function is called when
-fplugin=/path/to/NAME.so or -fplugin=NAME option is processed. */
void
-add_new_plugin (const char* plugin_name)
+add_new_plugin (const char *plugin_name)
{
struct plugin_name_args *plugin;
void **slot;
@@ -205,9 +250,82 @@ add_new_plugin (const char* plugin_name)
plugin->full_name = plugin_name;
*slot = plugin;
+
+ /* Check if we already have newly added plugin inside deferred table, possibly
+ with saved args to transfer them back. */
+ maybe_remove_deferred_plugin (slot);
+}
+
+
+/* Append key-value to the plugin argumens, realloc storage if nessesary. */
+
+static void
+append_plugin_argv (struct plugin_name_args *plugin, char **key, char **value)
+{
+ gcc_assert (plugin);
+ /* Create a plugin_argument object for the parsed key-value pair.
+ If there are already arguments for this plugin, we will need to
+ adjust the argument array size by creating a new array and deleting
+ the old one. If the performance ever becomes an issue, we can
+ change the code by pre-allocating a larger array first. */
+ if (plugin->argc > 0)
+ {
+ struct plugin_argument *args = XNEWVEC (struct plugin_argument,
+ plugin->argc + 1);
+ memcpy (args, plugin->argv,
+ sizeof (struct plugin_argument) * plugin->argc);
+ XDELETEVEC (plugin->argv);
+ plugin->argv = args;
+ ++plugin->argc;
+ }
+ else
+ {
+ gcc_assert (plugin->argv == NULL);
+ plugin->argv = XNEWVEC (struct plugin_argument, 1);
+ plugin->argc = 1;
+ }
+
+ plugin->argv[plugin->argc - 1].key = *key;
+ plugin->argv[plugin->argc - 1].value = *value;
}
+/* Add plugin 'name' to deferred hash table if not already in, append given
+ key:value argument. */
+
+static void
+maybe_add_as_deferred_plugin (char **name, char **key, char **value)
+{
+ void **slot;
+ struct plugin_name_args *deferred_plugin;
+
+ gcc_assert (name && key && value);
+
+ /* Create hash table for the first time if not exists. */
+ if (!plugin_deferred_name_args_tab)
+ plugin_deferred_name_args_tab = htab_create (10, htab_hash_string,
+ htab_str_eq, NULL);
+
+ slot = htab_find_slot_with_hash(plugin_deferred_name_args_tab, *name,
+ htab_hash_string(*name), INSERT);
+
+ /* Check if memory allocation fails. */
+ gcc_assert (slot);
+
+ /* If plugin is already if deferred list - append key-val argument. */
+ deferred_plugin = (struct plugin_name_args *)*slot;
+
+ if (!*slot)
+ {
+ deferred_plugin = XCNEW(struct plugin_name_args);
+ deferred_plugin->base_name = *name;
+ }
+ append_plugin_argv (deferred_plugin, key, value);
+
+ *slot = deferred_plugin;
+ }
+
+
/* Parse the -fplugin-arg-<name>-<key>[=<value>] option and create a
'plugin_argument' object for the parsed key-value pair. ARG is
the <name>-<key>[=<value>] part of the option. */
@@ -270,6 +388,19 @@ parse_plugin_arg_opt (const char *arg)
strncpy (name, name_start, name_len);
name[name_len] = '\0';
+ key = XNEWVEC (char, key_len + 1);
+ strncpy (key, key_start, key_len);
+ key[key_len] = '\0';
+ if (value_start)
+ {
+ value = XNEWVEC (char, value_len + 1);
+ strncpy (value, value_start, value_len);
+ value[value_len] = '\0';
+ }
+ else
+ value = NULL;
+
+
/* Check if the named plugin has already been specified earlier in the
command-line. */
if (plugin_name_args_tab
@@ -278,49 +409,17 @@ parse_plugin_arg_opt (const char *arg)
{
struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
- key = XNEWVEC (char, key_len + 1);
- strncpy (key, key_start, key_len);
- key[key_len] = '\0';
- if (value_start)
- {
- value = XNEWVEC (char, value_len + 1);
- strncpy (value, value_start, value_len);
- value[value_len] = '\0';
- }
- else
- value = NULL;
-
- /* Create a plugin_argument object for the parsed key-value pair.
- If there are already arguments for this plugin, we will need to
- adjust the argument array size by creating a new array and deleting
- the old one. If the performance ever becomes an issue, we can
- change the code by pre-allocating a larger array first. */
- if (plugin->argc > 0)
- {
- struct plugin_argument *args = XNEWVEC (struct plugin_argument,
- plugin->argc + 1);
- memcpy (args, plugin->argv,
- sizeof (struct plugin_argument) * plugin->argc);
- XDELETEVEC (plugin->argv);
- plugin->argv = args;
- ++plugin->argc;
- }
- else
- {
- gcc_assert (plugin->argv == NULL);
- plugin->argv = XNEWVEC (struct plugin_argument, 1);
- plugin->argc = 1;
- }
+ append_plugin_argv (plugin, &key, &value);
- plugin->argv[plugin->argc - 1].key = key;
- plugin->argv[plugin->argc - 1].value = value;
+ /* We don't need the plugin's name anymore. Just release it. */
+ XDELETEVEC (name);
}
else
- error ("plugin %s should be specified before -fplugin-arg-%s "
- "in the command line", name, arg);
-
- /* We don't need the plugin's name anymore. Just release it. */
- XDELETEVEC (name);
+ {
+ /* Add 'name' to the deferred plugin list, this allows to resolve
+ plugin-args <-> plugin relations at the end of the input options. */
+ maybe_add_as_deferred_plugin(&name, &key, &value);
+ }
}
/* Register additional plugin information. NAME is the name passed to
@@ -635,14 +734,57 @@ init_one_plugin (void **slot, void * ARG_UNUSED (info))
#endif /* ENABLE_PLUGIN */
+
+/* Error printing routine for deferred plugins that were not found with
+ -fplugin= option. */
+
+static int
+htab_traverse_deferred_plugins (void **slot, void * ARG_UNUSED (info))
+{
+ int i;
+ struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
+
+ for (i = 0; i < plugin->argc; i++)
+ {
+ error("-fplugin-arg-%s-%s was specified, but -fplugin=%s "
+ "not found.", plugin->base_name, plugin->argv[i].key, plugin->base_name);
+ }
+ return 1;
+}
+
+
+/* Check if there are no deferred plugins left and if plugins were specified. */
+
+static bool
+plugins_were_specified (void)
+{
+ /* If deferred plugin table is not empty - then we have plugin arguments
+ without corresponding -fplugin=.. option. Traverse table and report an
+ error for each plugin name. */
+ if (plugin_deferred_name_args_tab
+ && htab_elements (plugin_deferred_name_args_tab))
+ {
+ htab_traverse_noresize (plugin_deferred_name_args_tab, htab_traverse_deferred_plugins, NULL);
+ return false;
+ }
+
+ /* If no plugin was specified in the command-line, simply return. */
+ if (!plugin_name_args_tab)
+ return false;
+
+ return true;
+}
+
+
/* Main plugin initialization function. Called from compile_file() in
toplev.c. */
void
initialize_plugins (void)
{
- /* If no plugin was specified in the command-line, simply return. */
- if (!plugin_name_args_tab)
+ /* If no plugin was specified in the command-line or not all plugin arguments
+ have needed plugins, simply return or raise an error. */
+ if (!plugins_were_specified ())
return;
timevar_push (TV_PLUGIN_INIT);
@@ -661,28 +803,38 @@ static int
finalize_one_plugin (void **slot, void * ARG_UNUSED (info))
{
struct plugin_name_args *plugin = (struct plugin_name_args *) *slot;
+ XDELETE (plugin->argv);
XDELETE (plugin);
return 1;
}
+/* Delete htab object, free table fields with callback. */
+
+static void
+free_plugin_hash_table (htab_t htab, htab_trav callback)
+{
+ if (!htab)
+ return;
+
+ htab_traverse_noresize(htab, callback, NULL);
+
+ htab_delete(htab);
+ htab = NULL;
+}
+
/* Free memory allocated by the plugin system. */
void
finalize_plugins (void)
{
- if (!plugin_name_args_tab)
- return;
-
/* We can now delete the plugin_name_args object as it will no longer
be used. Note that base_name and argv fields (both of which were also
dynamically allocated) are not freed as they could still be used by
the plugin code. */
+ free_plugin_hash_table (plugin_name_args_tab, finalize_one_plugin);
- htab_traverse_noresize (plugin_name_args_tab, finalize_one_plugin, NULL);
-
- /* PLUGIN_NAME_ARGS_TAB is no longer needed, just delete it. */
- htab_delete (plugin_name_args_tab);
- plugin_name_args_tab = NULL;
+ /* Free deferred plugins hash table, no longer needed. */
+ free_plugin_hash_table (plugin_deferred_name_args_tab, finalize_one_plugin);
}
/* Used to pass options to htab_traverse callbacks. */
diff --git a/gcc/testsuite/gcc.dg/plugin/empty_plugin.c b/gcc/testsuite/gcc.dg/plugin/empty_plugin.c
new file mode 100644
index 00000000000..8b6dabb6cdf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/empty_plugin.c
@@ -0,0 +1,31 @@
+/* Empty plugin for testing input options */
+#include "gcc-plugin.h"
+int plugin_is_GPL_compatible;
+
+static bool
+parse_args (struct plugin_name_args *plugin_info,
+ unsigned argc, struct plugin_argument *argv)
+{
+ while (argc--)
+ {
+ char *key = argv[argc].key;
+ while (*key == '-')
+ ++ key;
+
+ if ((strcmp(key, "x") == 0) || (strcmp(key, "y") == 0))
+ printf("%s: argument %s\n", plugin_info->base_name, key);
+ else
+ return false;
+ }
+ return true;
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+ if (! parse_args (plugin_info, plugin_info->argc, plugin_info->argv))
+ {
+ return 1;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin-args-order-1.c b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-1.c
new file mode 100644
index 00000000000..98477e6f258
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-1.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin=foo -fplugin-arg-foo-x" } */
+
+/* { dg-prune-output "foo: argument x" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin-args-order-2.c b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-2.c
new file mode 100644
index 00000000000..4407a570cae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-2.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-foo-x -fplugin=foo" } */
+
+/* { dg-prune-output "foo: argument x" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin-args-order-3.c b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-3.c
new file mode 100644
index 00000000000..c892489c41d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-3.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-foo-x -fplugin=foo -fplugin-arg-foo-y" } */
+
+/* { dg-prune-output "foo: argument x" } */
+/* { dg-prune-output "foo: argument y" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin-args-order-4.c b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-4.c
new file mode 100644
index 00000000000..b6196484172
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-4.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-foo-x -fplugin-arg-bar-y -fplugin=foo -fplugin=bar" } */
+
+/* { dg-prune-output "foo: argument x" } */
+/* { dg-prune-output "bar: argument y" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin-args-order-5.c b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-5.c
new file mode 100644
index 00000000000..282dd645bc3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-5.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-foo-x -fplugin=foo -fplugin-arg-bar-y -fplugin=bar" } */
+
+/* { dg-prune-output "foo: argument x" } */
+/* { dg-prune-output "bar: argument y" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin-args-order-6.c b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-6.c
new file mode 100644
index 00000000000..c1321e8fd39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-6.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-foo-x -fplugin-arg-bar-y -fplugin=foo" } */
+
+/* { dg-prune-output ".*-fplugin-arg-bar-.* were specified, but .*-fplugin=bar.* not found.*" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin-args-order-7.c b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-7.c
new file mode 100644
index 00000000000..42ef65c1bb4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/plugin-args-order-7.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-foo-x -fplugin=bar -fplugin-arg-bar-y " } */
+
+/* { dg-prune-output ".*-fplugin-arg-foo-.* were specified, but .*-fplugin=foo.* not found.*" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 0547a8d7ca3..5755905d20e 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -76,6 +76,40 @@ set plugin_test_list [list \
location-overflow-test-2.c } \
]
+# Minimal plugin source
+set empty_plugin_file empty_plugin.c
+# Full path to the minimal plugin implementation
+set empty_plugin $srcdir/$subdir/$empty_plugin_file
+
+# Build multiple plugins with 'plugin_src' source and run 'plugin_tests' without
+# specifying -fplugin= option directly (unlike plugin-test-execute that prepends
+# -fplugin= based on 'plugin_src' basename).
+# With this proc we could test -fplugin= and -fplugin-arg-... options order
+# handling.
+proc plugin-test-arguments-execute { plugin_tests } {
+ upvar empty_plugin empty_plugin
+ # We are going to use -fplugin=foo|bar in 'plugin_tests'
+ set output_plugin_names { foo bar }
+ set output_plugins {}
+
+ # Collect generated plugins for clean up
+ foreach output $output_plugin_names {
+ set plug [plugin-build-plugin ${empty_plugin} $output]
+ lappend $output_plugins $plug
+ }
+
+ global default_flags
+ # Path where $output_plugins were built.
+ set plugin_search_path_opt "-iplugindir=."
+
+ dg-runtest $plugin_tests $plugin_search_path_opt $default_flags
+
+ # Clean up
+ foreach plug $output_plugins {
+ remote_file build delete $plug
+ }
+}
+
foreach plugin_test $plugin_test_list {
# Replace each source file with its full-path name
for {set i 0} {$i < [llength $plugin_test]} {incr i} {
@@ -97,15 +131,24 @@ foreach plugin_test $plugin_test_list {
plugin-test-execute $plugin_src $plugin_input_tests
}
-# run the plugindir tests
# Initialize `dg'.
dg-init
# Main loop.
+
+# Run the plugindir tests
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/plugindir*.\[cSi\]]] \
"" $DEFAULT_CFLAGS
+# Run the -fplugin-arg-.. opts handling tests without -fplugin
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pluginarg*.\[cSi\]]] \
+ "" $DEFAULT_CFLAGS
+
+# Run plugin arguments order tests
+plugin-test-arguments-execute \
+ [lsort [glob -nocomplain $srcdir/$subdir/plugin-args-order-*.\[cSi\]]]
+
# All done.
dg-finish
diff --git a/gcc/testsuite/gcc.dg/plugin/pluginarg1.c b/gcc/testsuite/gcc.dg/plugin/pluginarg1.c
new file mode 100644
index 00000000000..51b27492f9c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/pluginarg1.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-foo-x" } */
+
+/* { dg-prune-output ".*-fplugin-arg-foo-.* were specified, but .*-fplugin=foo.* not found.*" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/pluginarg2.c b/gcc/testsuite/gcc.dg/plugin/pluginarg2.c
new file mode 100644
index 00000000000..983d78e38ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/pluginarg2.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-foo-x1 -fplugin-arg-foo-x2" } */
+
+/* { dg-prune-output ".*-fplugin-arg-foo-.* were specified, but .*-fplugin=foo.* not found.*" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/pluginarg3.c b/gcc/testsuite/gcc.dg/plugin/pluginarg3.c
new file mode 100644
index 00000000000..20b38aac36c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/pluginarg3.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-foo-x -fplugin-arg-bar-y" } */
+
+/* { dg-prune-output ".*-fplugin-arg-foo-.* were specified, but .*-fplugin=foo.* not found.*" } */
+/* { dg-prune-output ".*-fplugin-arg-bar-.* were specified, but .*-fplugin=bar.* not found.*" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugindir1.c b/gcc/testsuite/gcc.dg/plugin/plugindir1.c
index 72821ac9852..160e9232787 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugindir1.c
+++ b/gcc/testsuite/gcc.dg/plugin/plugindir1.c
@@ -1,4 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-c -fplugin=foo" } */
-/* { dg-prune-output ".*inaccessible plugin file.*foo\.so expanded from short plugin name.*" } */
+/* { dg-prune-output ".*inaccessible plugin file.*foo\.(so|dylib) expanded from short plugin name.*" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugindir2.c b/gcc/testsuite/gcc.dg/plugin/plugindir2.c
index 063b9d9e594..a0bdbb4f2bd 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugindir2.c
+++ b/gcc/testsuite/gcc.dg/plugin/plugindir2.c
@@ -1,4 +1,4 @@
/* { dg-do compile } */
/* { dg-options "-save-temps -c -fplugin=foo" } */
-/* { dg-prune-output ".*inaccessible plugin file.*foo\.so expanded from short plugin name.*" } */
+/* { dg-prune-output ".*inaccessible plugin file.*foo\.(so|dylib) expanded from short plugin name.*" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugindir3.c b/gcc/testsuite/gcc.dg/plugin/plugindir3.c
index 9b1c004cfd1..8528c2eba11 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugindir3.c
+++ b/gcc/testsuite/gcc.dg/plugin/plugindir3.c
@@ -1,4 +1,4 @@
/* { dg-do preprocess } */
/* { dg-options "-fplugin=foo" } */
-/* { dg-prune-output ".*inaccessible plugin file.*foo\.so expanded from short plugin name.*" } */
+/* { dg-prune-output ".*inaccessible plugin file.*foo\.(so|dylib) expanded from short plugin name.*" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugindir4.c b/gcc/testsuite/gcc.dg/plugin/plugindir4.c
index 8f1cb801621..6f23195f289 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugindir4.c
+++ b/gcc/testsuite/gcc.dg/plugin/plugindir4.c
@@ -1,4 +1,4 @@
/* { dg-do preprocess } */
/* { dg-options "-iplugindir=my-plugindir -fplugin=foo" } */
-/* { dg-prune-output ".*inaccessible plugin file.*my-plugindir/foo\.so expanded from short plugin name.*" } */
+/* { dg-prune-output ".*inaccessible plugin file.*my-plugindir/foo\.(so|dylib) expanded from short plugin name.*" } */
diff --git a/gcc/testsuite/lib/plugin-support.exp b/gcc/testsuite/lib/plugin-support.exp
index 8c100f44181..674433f73dd 100644
--- a/gcc/testsuite/lib/plugin-support.exp
+++ b/gcc/testsuite/lib/plugin-support.exp
@@ -53,22 +53,27 @@ proc plugin-get-options { src } {
}
#
-# plugin-test-execute -- build the plugin first and then compile the
-# test files with the plugin.
+# plugin-build-plugin -- build the plugin itself
#
# PLUGIN_SRC is the full pathname of the plugin source file.
-# PLUGIN_TESTS is a list of input test source files.
+# PLUGIN_OUTPUT_NAME is an optional output plugin name without library suffix. If
+# it's an empty string - use basename of plugin_src name.
#
-proc plugin-test-execute { plugin_src plugin_tests } {
+proc plugin-build-plugin { plugin_src { plugin_output_name "" } } {
global srcdir objdir
global verbose
global GMPINC
global PLUGINCC
global PLUGINCFLAGS
- set basename [file tail $plugin_src]
- set base [file rootname $basename]
- set plugin_lib $base.so
+ set plugin_lib ""
+ if { $plugin_output_name == "" } {
+ set basename [file tail $plugin_src]
+ set base [file rootname $basename]
+ set plugin_lib $base.so
+ } else {
+ set plugin_lib $plugin_output_name.so
+ }
set testcase [dg-trim-dirname $srcdir $plugin_src]
verbose "Test the plugin $testcase" 1
@@ -117,11 +122,25 @@ proc plugin-test-execute { plugin_src plugin_tests } {
fail "$testcase compilation"
# Strictly, this is wrong: the tests compiled with the plugin should
# become unresolved instead.
- return
+ return ""
} else {
pass "$testcase compilation"
}
+ return ${plugin_lib}
+}
+
+#
+# plugin-test-execute -- build the plugin first and then compile the
+# test files with the plugin.
+#
+# PLUGIN_SRC is the full pathname of the plugin source file.
+# PLUGIN_TESTS is a list of input test source files.
+#
+proc plugin-test-execute { plugin_src plugin_tests } {
+ # Build plugin_src as plugin
+ set plugin_lib [plugin-build-plugin ${plugin_src}]
+
# Compile the input source files with the plugin
global default_flags
set plugin_enabling_flags "-fplugin=./$plugin_lib"