From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 113468 invoked by alias); 22 Sep 2015 21:09:59 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 113407 invoked by uid 89); 22 Sep 2015 21:09:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.0 required=5.0 tests=AWL,BAYES_50,KAM_LAZY_DOMAIN_SECURITY autolearn=no version=3.3.2 X-HELO: eggs.gnu.org Received: from eggs.gnu.org (HELO eggs.gnu.org) (208.118.235.92) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 22 Sep 2015 21:09:53 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZeUor-0007sU-Ok for gcc-patches@gcc.gnu.org; Tue, 22 Sep 2015 17:09:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59613) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZeUor-0007s9-Hy for gcc-patches@gcc.gnu.org; Tue, 22 Sep 2015 17:09:45 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id CA6508EA3B for ; Tue, 22 Sep 2015 21:09:44 +0000 (UTC) Received: from c64.redhat.com (vpn-225-110.phx2.redhat.com [10.3.225.110]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8ML9egB026723; Tue, 22 Sep 2015 17:09:44 -0400 From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 5/5] Add plugin to recursively dump the source-ranges in a tree (v2) Date: Tue, 22 Sep 2015 21:10:00 -0000 Message-Id: <1442957171-22904-6-git-send-email-dmalcolm@redhat.com> In-Reply-To: <1442957171-22904-1-git-send-email-dmalcolm@redhat.com> References: <1442957171-22904-1-git-send-email-dmalcolm@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 X-IsSubscribed: yes X-SW-Source: 2015-09/txt/msg01700.txt.bz2 This patch adds a test plugin that recurses down an expression tree, printing diagnostics showing the ranges of each node in the tree. It corresponds to: [PATCH 15/22] Add plugin to recursively dump the source-ranges in a tree https://gcc.gnu.org/ml/gcc-patches/2015-09/msg00741.html from v1 of the patch kit. Changes in v2: * the output no longer contains the PARAM_DECL and INTEGER_CST leaves since we no longer have range data for them; updated the expected output accordingly. * slightly updated to eliminate use of SOURCE_RANGE Updated screenshot: https://dmalcolm.fedorapeople.org/gcc/2015-09-22/diagnostic-test-show-trees-1.html gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic-test-show-trees-1.c: New file. * gcc.dg/plugin/diagnostic_plugin_show_trees.c: New file. * gcc.dg/plugin/plugin.exp (plugin_test_list): Add diagnostic_plugin_show_trees.c and diagnostic-test-show-trees-1.c. --- .../gcc.dg/plugin/diagnostic-test-show-trees-1.c | 65 ++++++++ .../gcc.dg/plugin/diagnostic_plugin_show_trees.c | 174 +++++++++++++++++++++ gcc/testsuite/gcc.dg/plugin/plugin.exp | 2 + 3 files changed, 241 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c new file mode 100644 index 0000000..7473a07 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdiagnostics-show-caret" } */ + +/* This is an example file for use with + diagnostic_plugin_show_trees.c. + + The plugin handles "__show_tree" by recursively dumping + the internal structure of the second input argument. + + We want to accept an expression of any type. To do this in C, we + use variadic arguments, but C requires at least one argument before + the ellipsis, so we have a dummy one. */ + +extern void __show_tree (int dummy, ...); + +extern double sqrt (double x); + +void test_quadratic (double a, double b, double c) +{ + __show_tree (0, + (-b + sqrt (b * b - 4 * a * c)) + / (2 * a)); + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + / (2 * a)); + ^~~~~~~~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ^~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~~~~~^~~~~~~~~~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~^~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~~~~~^~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + (-b + sqrt (b * b - 4 * a * c)) + ~~^~~ + { dg-end-multiline-output "" } */ + +/* { dg-begin-multiline-output "" } + / (2 * a)); + ~~~^~~~ + { dg-end-multiline-output "" } */ +} diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c new file mode 100644 index 0000000..5a911c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c @@ -0,0 +1,174 @@ +/* This plugin recursively dumps the source-code location ranges of + expressions, at the pre-gimplification tree stage. */ +/* { dg-options "-O" } */ + +#include "gcc-plugin.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "stringpool.h" +#include "toplev.h" +#include "basic-block.h" +#include "hash-table.h" +#include "vec.h" +#include "ggc.h" +#include "basic-block.h" +#include "tree-ssa-alias.h" +#include "internal-fn.h" +#include "gimple-fold.h" +#include "tree-eh.h" +#include "gimple-expr.h" +#include "is-a.h" +#include "gimple.h" +#include "gimple-iterator.h" +#include "tree.h" +#include "tree-pass.h" +#include "intl.h" +#include "plugin-version.h" +#include "diagnostic.h" +#include "context.h" +#include "gcc-rich-location.h" +#include "print-tree.h" + +/* + Hack: fails with linker error: +./diagnostic_plugin_show_trees.so: undefined symbol: _ZN17gcc_rich_location8add_exprEP9tree_node + since nothing in the tree is using gcc_rich_location::add_expr yet. + + I've tried various workarounds (adding DEBUG_FUNCTION to the + method, taking its address), but can't seem to fix it that way. + So as a nasty workaround, the following material is copied&pasted + from gcc-rich-location.c: */ + +static bool +get_range_for_expr (tree expr, location_range *r) +{ + if (EXPR_HAS_RANGE (expr)) + { + source_range sr = EXPR_LOCATION_RANGE (expr); + + /* Do we have meaningful data? */ + if (sr.m_start && sr.m_finish) + { + r->m_start = expand_location (sr.m_start); + r->m_finish = expand_location (sr.m_finish); + return true; + } + } + + return false; +} + +/* Add a range to the rich_location, covering expression EXPR. */ + +void +gcc_rich_location::add_expr (tree expr) +{ + gcc_assert (expr); + + location_range r; + r.m_show_caret_p = false; + if (get_range_for_expr (expr, &r)) + add_range (&r); +} + +/* FIXME: end of material taken from gcc-rich-location.c */ + +int plugin_is_GPL_compatible; + +static void +show_tree (tree node) +{ + if (!CAN_HAVE_RANGE_P (node)) + return; + + gcc_rich_location richloc (EXPR_LOCATION (node)); + richloc.add_expr (node); + + if (richloc.get_num_locations () < 2) + { + error_at_rich_loc (&richloc, "range not found"); + return; + } + + enum tree_code code = TREE_CODE (node); + + location_range *range = richloc.get_range (1); + inform_at_rich_loc (&richloc, + "%s at range %i:%i-%i:%i", + get_tree_code_name (code), + range->m_start.line, + range->m_start.column, + range->m_finish.line, + range->m_finish.column); + + /* Recurse. */ + int min_idx = 0; + int max_idx = TREE_OPERAND_LENGTH (node); + switch (code) + { + case CALL_EXPR: + min_idx = 3; + break; + + default: + break; + } + + for (int i = min_idx; i < max_idx; i++) + show_tree (TREE_OPERAND (node, i)); +} + +tree +cb_walk_tree_fn (tree * tp, int * walk_subtrees, + void * data ATTRIBUTE_UNUSED) +{ + if (TREE_CODE (*tp) != CALL_EXPR) + return NULL_TREE; + + tree call_expr = *tp; + tree fn = CALL_EXPR_FN (call_expr); + if (TREE_CODE (fn) != ADDR_EXPR) + return NULL_TREE; + fn = TREE_OPERAND (fn, 0); + if (TREE_CODE (fn) != FUNCTION_DECL) + return NULL_TREE; + if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fn)), "__show_tree")) + return NULL_TREE; + + /* Get arg 1; print it! */ + tree arg = CALL_EXPR_ARG (call_expr, 1); + + show_tree (arg); + + return NULL_TREE; +} + +static void +callback (void *gcc_data, void *user_data) +{ + tree fndecl = (tree)gcc_data; + walk_tree (&DECL_SAVED_TREE (fndecl), cb_walk_tree_fn, NULL, NULL); +} + +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; + + if (!plugin_default_version_check (version, &gcc_version)) + return 1; + + register_callback (plugin_name, + PLUGIN_PRE_GENERICIZE, + callback, + NULL); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index b7efcf5..f1155ee 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -68,6 +68,8 @@ set plugin_test_list [list \ diagnostic-test-show-locus-color.c } \ { diagnostic_plugin_test_tree_expression_range.c \ diagnostic-test-expressions-1.c } \ + { diagnostic_plugin_show_trees.c \ + diagnostic-test-show-trees-1.c } \ ] foreach plugin_test $plugin_test_list { -- 1.8.5.3