diff options
Diffstat (limited to 'gcc-4.8.1/gcc/testsuite/gcc.dg/plugin/selfassign.c')
-rw-r--r-- | gcc-4.8.1/gcc/testsuite/gcc.dg/plugin/selfassign.c | 369 |
1 files changed, 0 insertions, 369 deletions
diff --git a/gcc-4.8.1/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc-4.8.1/gcc/testsuite/gcc.dg/plugin/selfassign.c deleted file mode 100644 index 37a0a979c..000000000 --- a/gcc-4.8.1/gcc/testsuite/gcc.dg/plugin/selfassign.c +++ /dev/null @@ -1,369 +0,0 @@ -/* This plugin contains an analysis pass that detects and warns about - self-assignment statements. */ -/* { dg-options "-O" } */ - -#include "gcc-plugin.h" -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "toplev.h" -#include "basic-block.h" -#include "gimple.h" -#include "tree.h" -#include "tree-pass.h" -#include "intl.h" -#include "plugin-version.h" -#include "diagnostic.h" - -int plugin_is_GPL_compatible; - -/* Indicate whether to check overloaded operator '=', which is performed by - default. To disable it, use -fplugin-arg-NAME-no-check-operator-eq. */ -bool check_operator_eq = true; - -/* Given a rhs EXPR of a gimple assign statement, if it is - - SSA_NAME : returns its var decl, or, if it is a temp variable, - returns the rhs of its SSA def statement. - - VAR_DECL, PARM_DECL, FIELD_DECL, or a reference expression : - returns EXPR itself. - - any other expression : returns NULL_TREE. */ - -static tree -get_real_ref_rhs (tree expr) -{ - switch (TREE_CODE (expr)) - { - case SSA_NAME: - { - /* Given a self-assign statement, say foo.x = foo.x, - the IR (after SSA) looks like: - - D.1797_14 = foo.x; - foo.x ={v} D.1797_14; - - So if the rhs EXPR is an SSA_NAME of a temp variable, - e.g. D.1797_14, we need to grab the rhs of its SSA def - statement (i.e. foo.x). */ - tree vdecl = SSA_NAME_VAR (expr); - if ((!vdecl || DECL_ARTIFICIAL (vdecl)) - && !gimple_nop_p (SSA_NAME_DEF_STMT (expr))) - { - gimple def_stmt = SSA_NAME_DEF_STMT (expr); - /* We are only interested in an assignment with a single - rhs operand because if it is not, the original assignment - will not possibly be a self-assignment. */ - if (gimple_assign_single_p (def_stmt)) - return get_real_ref_rhs (gimple_assign_rhs1 (def_stmt)); - else - return NULL_TREE; - } - else - return vdecl; - } - case VAR_DECL: - case PARM_DECL: - case FIELD_DECL: - case COMPONENT_REF: - case MEM_REF: - case ARRAY_REF: - return expr; - default: - return NULL_TREE; - } -} - -/* Given an expression tree, EXPR, that may contains SSA names, returns an - equivalent tree with the SSA names converted to var/parm/field decls - so that it can be used with '%E' format modifier when emitting warning - messages. - - This function currently only supports VAR/PARM/FIELD_DECL, reference - expressions (COMPONENT_REF, INDIRECT_REF, ARRAY_REF), integer constant, - and SSA_NAME. If EXPR contains any other tree nodes (e.g. an arithmetic - expression appears in array index), NULL_TREE is returned. */ - -static tree -get_non_ssa_expr (tree expr) -{ - if (!expr) - return NULL_TREE; - switch (TREE_CODE (expr)) - { - case VAR_DECL: - case PARM_DECL: - case FIELD_DECL: - { - if (DECL_NAME (expr)) - return expr; - else - return NULL_TREE; - } - case COMPONENT_REF: - { - tree base, orig_base = TREE_OPERAND (expr, 0); - tree component, orig_component = TREE_OPERAND (expr, 1); - base = get_non_ssa_expr (orig_base); - if (!base) - return NULL_TREE; - component = get_non_ssa_expr (orig_component); - if (!component) - return NULL_TREE; - /* If either BASE or COMPONENT is converted, build a new - component reference tree. */ - if (base != orig_base || component != orig_component) - return build3 (COMPONENT_REF, TREE_TYPE (component), - base, component, NULL_TREE); - else - return expr; - } - case MEM_REF: - { - tree orig_base = TREE_OPERAND (expr, 0); - if (TREE_CODE (orig_base) == SSA_NAME) - { - tree base = get_non_ssa_expr (orig_base); - if (!base) - return NULL_TREE; - return fold_build2 (MEM_REF, TREE_TYPE (expr), - base, TREE_OPERAND (expr, 1)); - } - return expr; - } - case ARRAY_REF: - { - tree array, orig_array = TREE_OPERAND (expr, 0); - tree index, orig_index = TREE_OPERAND (expr, 1); - array = get_non_ssa_expr (orig_array); - if (!array) - return NULL_TREE; - index = get_non_ssa_expr (orig_index); - if (!index) - return NULL_TREE; - /* If either ARRAY or INDEX is converted, build a new array - reference tree. */ - if (array != orig_array || index != orig_index) - return build4 (ARRAY_REF, TREE_TYPE (expr), array, index, - TREE_OPERAND (expr, 2), TREE_OPERAND (expr, 3)); - else - return expr; - } - case SSA_NAME: - { - tree vdecl = SSA_NAME_VAR (expr); - if ((!vdecl || DECL_ARTIFICIAL (vdecl)) - && !gimple_nop_p (SSA_NAME_DEF_STMT (expr))) - { - gimple def_stmt = SSA_NAME_DEF_STMT (expr); - if (gimple_assign_single_p (def_stmt)) - vdecl = gimple_assign_rhs1 (def_stmt); - } - return get_non_ssa_expr (vdecl); - } - case INTEGER_CST: - return expr; - default: - /* Return NULL_TREE for any other kind of tree nodes. */ - return NULL_TREE; - } -} - -/* Given the LHS and (real) RHS of a gimple assign statement, STMT, check if - they are the same. If so, print a warning message about self-assignment. */ - -static void -compare_and_warn (gimple stmt, tree lhs, tree rhs) -{ - if (operand_equal_p (lhs, rhs, OEP_PURE_SAME)) - { - location_t location; - location = (gimple_has_location (stmt) - ? gimple_location (stmt) - : (DECL_P (lhs) - ? DECL_SOURCE_LOCATION (lhs) - : input_location)); - /* If LHS contains any tree node not currently supported by - get_non_ssa_expr, simply emit a generic warning without - specifying LHS in the message. */ - lhs = get_non_ssa_expr (lhs); - if (lhs) - warning_at (location, 0, G_("%qE is assigned to itself"), lhs); - else - warning_at (location, 0, G_("self-assignment detected")); - } -} - -/* Check and warn if STMT is a self-assign statement. */ - -static void -warn_self_assign (gimple stmt) -{ - tree rhs, lhs; - - /* Check assigment statement. */ - if (gimple_assign_single_p (stmt)) - { - rhs = get_real_ref_rhs (gimple_assign_rhs1 (stmt)); - if (!rhs) - return; - - lhs = gimple_assign_lhs (stmt); - if (TREE_CODE (lhs) == SSA_NAME) - { - lhs = SSA_NAME_VAR (lhs); - if (!lhs || DECL_ARTIFICIAL (lhs)) - return; - } - - compare_and_warn (stmt, lhs, rhs); - } - /* Check overloaded operator '=' (if enabled). */ - else if (check_operator_eq && is_gimple_call (stmt)) - { - tree fdecl = gimple_call_fndecl (stmt); - if (fdecl && (DECL_NAME (fdecl) == maybe_get_identifier ("operator="))) - { - /* If 'operator=' takes reference operands, the arguments will be - ADDR_EXPR trees. In this case, just remove the address-taken - operator before we compare the lhs and rhs. */ - lhs = gimple_call_arg (stmt, 0); - if (TREE_CODE (lhs) == ADDR_EXPR) - lhs = TREE_OPERAND (lhs, 0); - rhs = gimple_call_arg (stmt, 1); - if (TREE_CODE (rhs) == ADDR_EXPR) - rhs = TREE_OPERAND (rhs, 0); - - compare_and_warn (stmt, lhs, rhs); - } - } -} - -/* Entry point for the self-assignment detection pass. */ - -static unsigned int -execute_warn_self_assign (void) -{ - gimple_stmt_iterator gsi; - basic_block bb; - - FOR_EACH_BB (bb) - { - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - warn_self_assign (gsi_stmt (gsi)); - } - - return 0; -} - -/* Pass gate function. Currently always returns true. */ - -static bool -gate_warn_self_assign (void) -{ - return true; -} - -static struct gimple_opt_pass pass_warn_self_assign = -{ - { - GIMPLE_PASS, - "warn_self_assign", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - gate_warn_self_assign, /* gate */ - execute_warn_self_assign, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_NONE, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ - } -}; - -/* The initialization routine exposed to and called by GCC. The spec of this - function is defined in gcc/gcc-plugin.h. - - PLUGIN_NAME - name of the plugin (useful for error reporting) - ARGC - the size of the ARGV array - ARGV - an array of key-value argument pair - - Returns 0 if initialization finishes successfully. - - Note that this function needs to be named exactly "plugin_init". */ - -int -plugin_init (struct plugin_name_args *plugin_info, - struct plugin_gcc_version *version) -{ - struct register_pass_info pass_info; - const char *plugin_name = plugin_info->base_name; - int argc = plugin_info->argc; - struct plugin_argument *argv = plugin_info->argv; - bool enabled = true; - int i; - - if (!plugin_default_version_check (version, &gcc_version)) - return 1; - - /* Self-assign detection should happen after SSA is constructed. */ - pass_info.pass = &pass_warn_self_assign.pass; - pass_info.reference_pass_name = "ssa"; - pass_info.ref_pass_instance_number = 1; - pass_info.pos_op = PASS_POS_INSERT_AFTER; - - /* Process the plugin arguments. This plugin takes the following arguments: - check-operator-eq, no-check-operator-eq, enable, and disable. - By default, the analysis is enabled with 'operator=' checked. */ - for (i = 0; i < argc; ++i) - { - if (!strcmp (argv[i].key, "check-operator-eq")) - { - if (argv[i].value) - warning (0, G_("option '-fplugin-arg-%s-check-operator-eq=%s'" - " ignored (superfluous '=%s')"), - plugin_name, argv[i].value, argv[i].value); - else - check_operator_eq = true; - } - else if (!strcmp (argv[i].key, "no-check-operator-eq")) - { - if (argv[i].value) - warning (0, G_("option '-fplugin-arg-%s-no-check-operator-eq=%s'" - " ignored (superfluous '=%s')"), - plugin_name, argv[i].value, argv[i].value); - else - check_operator_eq = false; - } - else if (!strcmp (argv[i].key, "enable")) - { - if (argv[i].value) - warning (0, G_("option '-fplugin-arg-%s-enable=%s' ignored" - " (superfluous '=%s')"), - plugin_name, argv[i].value, argv[i].value); - else - enabled = true; - } - else if (!strcmp (argv[i].key, "disable")) - { - if (argv[i].value) - warning (0, G_("option '-fplugin-arg-%s-disable=%s' ignored" - " (superfluous '=%s')"), - plugin_name, argv[i].value, argv[i].value); - else - enabled = false; - } - else - warning (0, G_("plugin %qs: unrecognized argument %qs ignored"), - plugin_name, argv[i].key); - } - - /* Register this new pass with GCC if the analysis is enabled. */ - if (enabled) - register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, - &pass_info); - - return 0; -} |