Commit 8ba50c2c by Le-Chun Wu Committed by Diego Novillo

plugin-support.exp: New file containing support procs for plugin testcases.

2009-05-06  Le-Chun Wu  <lcwu@google.com>

	* lib/plugin-support.exp: New file containing support procs for
	plugin testcases.
	* lib/target-supports.exp (check_plugin_available): New proc.
	* gcc.dg/plugin/plugin.exp: New driver script for gcc testcases.
	* gcc.dg/plugin/selfassign.c: New plugin source file.
	* gcc.dg/plugin/self-assign-test-1.c: New test.
	* gcc.dg/plugin/self-assign-test-2.c: Likewise.
	* g++.dg/README: Add description for plugin test.
	* g++.dg/dg.exp: Exclude plugin tests from the general test list.
	* g++.dg/plugin/plugin.exp: New driver script for g++ testcases.
	* g++.dg/plugin/selfassign.c: New plugin source file.
	* g++.dg/plugin/self-assign-test-1.C: New test.
	* g++.dg/plugin/self-assign-test-2.C: Likewise.
	* g++.dg/plugin/self-assign-test-3.C: Likewise.
	* g++.dg/plugin/dumb_plugin.c: New plugin source file.
	* g++.dg/plugin/dumb-plugin-test-1.C: New test.

From-SVN: r147185
parent b050b2de
......@@ -816,7 +816,6 @@ bool
plugin_default_version_check (struct plugin_gcc_version *gcc_version,
struct plugin_gcc_version *plugin_version)
{
/* version is NULL if the plugin was not linked with plugin-version.o */
if (!gcc_version || !plugin_version)
return false;
......
2009-05-06 Le-Chun Wu <lcwu@google.com>
* lib/plugin-support.exp: New file containing support procs for
plugin testcases.
* lib/target-supports.exp (check_plugin_available): New proc.
* gcc.dg/plugin/plugin.exp: New driver script for gcc testcases.
* gcc.dg/plugin/selfassign.c: New plugin source file.
* gcc.dg/plugin/self-assign-test-1.c: New test.
* gcc.dg/plugin/self-assign-test-2.c: Likewise.
* g++.dg/README: Add description for plugin test.
* g++.dg/dg.exp: Exclude plugin tests from the general test list.
* g++.dg/plugin/plugin.exp: New driver script for g++ testcases.
* g++.dg/plugin/selfassign.c: New plugin source file.
* g++.dg/plugin/self-assign-test-1.C: New test.
* g++.dg/plugin/self-assign-test-2.C: Likewise.
* g++.dg/plugin/self-assign-test-3.C: Likewise.
* g++.dg/plugin/dumb_plugin.c: New plugin source file.
* g++.dg/plugin/dumb-plugin-test-1.C: New test.
2009-05-06 Tobias Burnus <burnus@net-b.de>
PR fortran/40041
......
......@@ -18,6 +18,7 @@ opt Tests for fixes of bugs with particular optimizations.
overload Tests for overload resolution and conversions.
parse Tests for parsing.
pch Tests for precompiled headers.
plugin Tests for plugin support.
rtti Tests for run-time type identification (typeid, dynamic_cast, etc.)
template Tests for templates.
tc1 Tests for Technical Corrigendum 1 conformance.
......
......@@ -37,6 +37,7 @@ set tests [prune $tests $srcdir/$subdir/compat/*]
set tests [prune $tests $srcdir/$subdir/debug/*]
set tests [prune $tests $srcdir/$subdir/gcov/*]
set tests [prune $tests $srcdir/$subdir/pch/*]
set tests [prune $tests $srcdir/$subdir/plugin/*]
set tests [prune $tests $srcdir/$subdir/special/*]
set tests [prune $tests $srcdir/$subdir/tls/*]
set tests [prune $tests $srcdir/$subdir/vect/*]
......
// Test case for the dumb plugin.
// { dg-do compile }
// { dg-options "-O -fplugin-arg-dumb_plugin-ref-pass-name=ccp -fplugin-arg-dumb_plugin-ref-pass-instance-num=1" }
class Foo {
private:
int a_;
public:
Foo() : a_(a_) {} // { dg-warning "Before genericizing function" }
void setA(int a) {
a_ = a_;
} // { dg-warning "Before genericizing function" }
void operator=(Foo& rhs) {
this->a_ = rhs.a_;
} // { dg-warning "Before genericizing function" }
}; // { dg-warning "Process struct Foo" }
struct Bar {
int b_;
int c_;
}; // { dg-warning "Process struct Bar" }
int g = g;
Foo foo = foo;
int func()
{
Bar *bar1, bar2;
Foo local_foo;
int x = x;
static int y = y;
float *f;
Bar bar_array[5];
char n;
int overflow;
*f = *f;
bar1->b_ = bar1->b_;
bar2.c_ = bar2.c_;
local_foo = local_foo;
foo = foo;
foo.setA(5);
bar_array[3].c_ = bar_array[3].c_;
bar_array[x+g].b_ = bar_array[x+g].b_;
y = x;
x = y;
} // { dg-warning "Before genericizing function" }
// { dg-warning "Analyze function" "" { target *-*-* } 50 }
// { dg-warning "End of compilation unit" "" { target *-*-* } 50 }
/* A trivial (dumb) plugin example that shows how to use the GCC plugin
mechanism. */
#include <stdlib.h>
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "tree-pass.h"
#include "intl.h"
#include "gcc-plugin.h"
/* Callback function to invoke after GCC finishes parsing a struct. */
void
handle_struct (void *event_data, void *data)
{
tree type = (tree) event_data;
warning (0, G_("Process struct %s"),
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
}
/* Callback function to invoke before the program is genericized. */
void
handle_pre_generic (void *event_data, void *data)
{
tree fndecl = (tree) event_data;
warning (0, G_("Before genericizing function %s"),
IDENTIFIER_POINTER (DECL_NAME (fndecl)));
}
/* Callback function to invoke after GCC finishes the compilation unit. */
void
handle_end_of_compilation_unit (void *event_data, void *data)
{
warning (0, G_("End of compilation unit"));
}
static unsigned int
execute_dumb_plugin_example (void)
{
warning (0, G_("Analyze function %s"),
IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
return 0;
}
static bool
gate_dumb_plugin_example (void)
{
return true;
}
static struct gimple_opt_pass pass_dumb_plugin_example =
{
{
GIMPLE_PASS,
"dumb_plugin_example", /* name */
gate_dumb_plugin_example, /* gate */
execute_dumb_plugin_example, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
0, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func /* todo_flags_finish */
}
};
/* Initialization function that GCC calls. This plugin takes an argument
that specifies the name of the reference pass and an instance number,
both of which determine where the plugin pass should be inserted. */
int
plugin_init (const char *plugin_name,
struct plugin_gcc_version *version __attribute__((unused)),
int argc, struct plugin_argument *argv)
{
struct plugin_pass pass_info;
char *ref_pass_name = NULL;
int ref_instance_number = 0;
int i;
/* Process the plugin arguments. This plugin takes the following arguments:
ref-pass-name=<PASS_NAME> and ref-pass-instance-num=<NUM>. */
for (i = 0; i < argc; ++i)
{
if (!strcmp (argv[i].key, "ref-pass-name"))
{
if (argv[i].value)
ref_pass_name = argv[i].value;
else
warning (0, G_("option '-fplugin-arg-%s-ref-pass-name'"
" requires a pass name"), plugin_name);
}
else if (!strcmp (argv[i].key, "ref-pass-instance-num"))
{
if (argv[i].value)
ref_instance_number = strtol (argv[i].value, NULL, 0);
else
warning (0, G_("option '-fplugin-arg-%s-ref-pass-instance-num'"
" requires an integer value"), plugin_name);
}
else
warning (0, G_("plugin %qs: unrecognized argument %qs ignored"),
plugin_name, argv[i].key);
}
if (!ref_pass_name)
{
error (G_("plugin %qs requires a reference pass name"), plugin_name);
return 1;
}
pass_info.pass = &pass_dumb_plugin_example.pass;
pass_info.reference_pass_name = ref_pass_name;
pass_info.ref_pass_instance_number = ref_instance_number;
pass_info.pos_op = PASS_POS_INSERT_AFTER;
register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
register_callback (plugin_name, PLUGIN_FINISH_TYPE, handle_struct, NULL);
register_callback (plugin_name, PLUGIN_CXX_CP_PRE_GENERICIZE,
handle_pre_generic, NULL);
register_callback (plugin_name, PLUGIN_FINISH_UNIT,
handle_end_of_compilation_unit, NULL);
return 0;
}
# Copyright (C) 2009 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
# Test the functionality of the GCC plugin support
load_lib target-supports.exp
load_lib g++-dg.exp
global TESTING_IN_BUILD_TREE
global ENABLE_PLUGIN
# The plugin testcases currently only work when the build tree is available.
# Also check whether the host supports plugins.
if { ![info exists TESTING_IN_BUILD_TREE] || ![info exists ENABLE_PLUGIN] } {
return
}
# If a testcase doesn't have special options, use these.
global DEFAULT_CXXFLAGS
if ![info exists DEFAULT_CXXFLAGS] then {
set DEFAULT_CXXFLAGS " -ansi -pedantic-errors -Wno-long-long"
}
# The procedures in plugin-support.exp need these parameters.
set default_flags $DEFAULT_CXXFLAGS
if $tracelevel then {
strace $tracelevel
}
# Load support procs.
load_lib plugin-support.exp
# Specify the plugin source file and the associated test files in a list.
# plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... }
set plugin_test_list [list \
{ selfassign.c self-assign-test-1.C self-assign-test-2.C self-assign-test-3.C } \
{ dumb_plugin.c dumb-plugin-test-1.C } ]
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} {
set basename [lindex $plugin_test $i]
set plugin_test [lreplace $plugin_test $i $i $srcdir/$subdir/$basename]
}
set plugin_src [lindex $plugin_test 0]
# If we're only testing specific files and this isn't one of them, skip it.
if ![runtest_file_p $runtests $plugin_src] then {
continue
}
set plugin_input_tests [lreplace $plugin_test 0 0]
plugin-test-execute $plugin_src $plugin_input_tests
}
// Test the self-assignemnt detection plugin.
// { dg-do compile }
// { dg-options "-O" }
class Foo {
private:
int a_;
public:
Foo() : a_(a_) {} // { dg-warning "assigned to itself" }
void setA(int a) {
a_ = a_; // { dg-warning "assigned to itself" }
}
void operator=(Foo& rhs) {
this->a_ = rhs.a_;
}
};
struct Bar {
int b_;
int c_;
};
int g = g; // { dg-warning "assigned to itself" }
Foo foo = foo; // { dg-warning "assigned to itself" }
int func()
{
Bar *bar1, bar2;
Foo local_foo;
int x = x; // { dg-warning "assigned to itself" }
static int y = y; // { dg-warning "assigned to itself" }
float *f;
Bar bar_array[5];
char n;
int overflow;
*f = *f; // { dg-warning "assigned to itself" }
bar1->b_ = bar1->b_; // { dg-warning "assigned to itself" }
bar2.c_ = bar2.c_; // { dg-warning "assigned to itself" }
local_foo = local_foo; // { dg-warning "assigned to itself" }
foo = foo; // { dg-warning "assigned to itself" }
foo.setA(5);
bar_array[3].c_ = bar_array[3].c_; // { dg-warning "assigned to itself" }
bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" }
y = x;
x = y;
}
// Test the self-assignemnt detection plugin without checking of operator-eq.
// { dg-do compile }
// { dg-options "-O -fplugin-arg-selfassign-no-check-operator-eq" }
class Foo {
private:
int a_;
public:
Foo() : a_(a_) {} // { dg-warning "assigned to itself" }
void setA(int a) {
a_ = a_; // { dg-warning "assigned to itself" }
}
void operator=(Foo& rhs) {
this->a_ = rhs.a_;
}
};
struct Bar {
int b_;
int c_;
};
int g = g; // { dg-warning "assigned to itself" }
Foo foo = foo; // { dg-warning "assigned to itself" }
int func()
{
Bar *bar1, bar2;
Foo local_foo;
int x = x; // { dg-warning "assigned to itself" }
static int y = y; // { dg-warning "assigned to itself" }
float *f;
Bar bar_array[5];
char n;
int overflow;
*f = *f; // { dg-warning "assigned to itself" }
bar1->b_ = bar1->b_; // { dg-warning "assigned to itself" }
bar2.c_ = bar2.c_; // { dg-warning "assigned to itself" }
local_foo = local_foo; // { dg-bogus "assigned to itself" }
foo = foo; // { dg-bogus "assigned to itself" }
foo.setA(5);
bar_array[3].c_ = bar_array[3].c_; // { dg-warning "assigned to itself" }
bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" }
y = x;
x = y;
}
// Test the self-assignemnt detection plugin with the 'disable' argument.
// { dg-do compile }
// { dg-options "-O -fplugin-arg-selfassign-disable" }
class Foo {
private:
int a_;
public:
Foo() : a_(a_) {} // { dg-bogus "assigned to itself" }
void setA(int a) {
a_ = a_; // { dg-bogus "assigned to itself" }
}
void operator=(Foo& rhs) {
this->a_ = rhs.a_;
}
};
struct Bar {
int b_;
int c_;
};
int g = g; // { dg-bogus "assigned to itself" }
Foo foo = foo; // { dg-bogus "assigned to itself" }
int func()
{
Bar *bar1, bar2;
Foo local_foo;
int x = x; // { dg-bogus "assigned to itself" }
static int y = y; // { dg-bogus "assigned to itself" }
float *f;
Bar bar_array[5];
char n;
int overflow;
*f = *f; // { dg-bogus "assigned to itself" }
bar1->b_ = bar1->b_; // { dg-bogus "assigned to itself" }
bar2.c_ = bar2.c_; // { dg-bogus "assigned to itself" }
local_foo = local_foo; // { dg-bogus "assigned to itself" }
foo = foo; // { dg-bogus "assigned to itself" }
foo.setA(5);
bar_array[3].c_ = bar_array[3].c_; // { dg-bogus "assigned to itself" }
bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-bogus "self-assignment detected" }
y = x;
x = y;
}
# Copyright (C) 2009 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
# Test the functionality of the GCC plugin support
load_lib target-supports.exp
load_lib gcc-dg.exp
global TESTING_IN_BUILD_TREE
global ENABLE_PLUGIN
# The plugin testcases currently only work when the build tree is available.
# Also check whether the host supports plugins.
if { ![info exists TESTING_IN_BUILD_TREE] || ![info exists ENABLE_PLUGIN] } {
return
}
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then {
set DEFAULT_CFLAGS " -ansi -pedantic-errors"
}
# The procedures in plugin-support.exp need these parameters.
set default_flags $DEFAULT_CFLAGS
if $tracelevel then {
strace $tracelevel
}
# Load support procs.
load_lib plugin-support.exp
# Specify the plugin source file and the associated test files in a list.
# plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... }
set plugin_test_list [list \
{ selfassign.c self-assign-test-1.c self-assign-test-2.c } ]
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} {
set basename [lindex $plugin_test $i]
set plugin_test [lreplace $plugin_test $i $i $srcdir/$subdir/$basename]
}
set plugin_src [lindex $plugin_test 0]
# If we're only testing specific files and this isn't one of them, skip it.
if ![runtest_file_p $runtests $plugin_src] then {
continue
}
set plugin_input_tests [lreplace $plugin_test 0 0]
plugin-test-execute $plugin_src $plugin_input_tests
}
/* Test the self-assignemnt detection plugin. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct Bar {
int b_;
int c_;
};
int g;
int main()
{
struct Bar *bar;
int x = x; /* { dg-warning "assigned to itself" } */
static int y;
struct Bar b_array[5];
b_array[x+g].b_ = b_array[x+g].b_; /* { dg-warning "self-assignment detected" } */
g = g; /* { dg-warning "assigned to itself" } */
y = y; /* { dg-warning "assigned to itself" } */
bar->b_ = bar->b_; /* { dg-warning "assigned to itself" } */
}
/* Test the self-assignemnt detection plugin with the 'disable' argument. */
/* { dg-do compile } */
/* { dg-options "-O -fplugin-arg-selfassign-disable" } */
struct Bar {
int b_;
int c_;
};
int g;
int main()
{
struct Bar *bar;
int x = x; /* { dg-bogus "assigned to itself" } */
static int y;
struct Bar b_array[5];
b_array[x+g].b_ = b_array[x+g].b_; /* { dg-bogus "self-assignment detected" } */
g = g; /* { dg-bogus "assigned to itself" } */
y = y; /* { dg-bogus "assigned to itself" } */
bar->b_ = bar->b_; /* { dg-bogus "assigned to itself" } */
}
# Copyright (C) 2009 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
#
# This file contains the support procedures for testing the plugin mechanism.
load_lib dg.exp
load_lib gcc.exp
#
# plugin-get-options -- process test directives
#
# SRC is the full pathname of the plugin source file.
#
proc plugin-get-options { src } {
# dg-options sets a variable called dg-extra-tool-flags.
set dg-extra-tool-flags ""
# dg-require-* sets dg-do-what.
upvar dg-do-what dg-do-what
set tmp [dg-get-options $src]
foreach op $tmp {
set cmd [lindex $op 0]
if { ![string compare "dg-options" $cmd] } {
set status [catch "$op" errmsg]
if { $status != 0 } {
perror "src: $errmsg for \"$op\"\n"
unresolved "$src: $errmsg for \"$op\""
return
}
} else {
# Ignore unrecognized dg- commands, but warn about them.
warning "plugin.exp does not support $cmd"
}
}
# Return flags to use for compiling the plugin source file
return ${dg-extra-tool-flags}
}
#
# 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 } {
global srcdir objdir
global verbose
global GMPINC
set basename [file tail $plugin_src]
set base [file rootname $basename]
set plugin_lib $base.so
verbose "Test the plugin $basename" 1
# Build the plugin itself
set extra_flags [plugin-get-options $plugin_src]
# Note that the plugin test support currently only works when the GCC
# build tree is available. (We make sure that is the case in plugin.exp.)
# Once we have figured out how/where to package/install GCC header files
# for general plugin support, we should modify the following include paths
# accordingly.
set gcc_srcdir "$srcdir/../.."
set gcc_objdir "$objdir/../../.."
set includes "-I. -I${srcdir} -I${gcc_srcdir}/gcc -I${gcc_objdir}/gcc \
-I${gcc_srcdir}/include -I${gcc_srcdir}/libcpp/include \
-I$GMPINC"
set optstr "$includes $extra_flags -DIN_GCC -fPIC -shared"
set status [target_compile "$optstr $plugin_src" "$plugin_lib" executable ""]
if { "$status" != "" } {
unresolved "$basename compilation, $optstr"
return
}
# Compile the input source files with the plugin
global default_flags
set plugin_enabling_flags "-fplugin=./$plugin_lib"
dg-runtest $plugin_tests $plugin_enabling_flags $default_flags
# Clean up
remote_file build delete $plugin_lib
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment