Hi Jason! Possible test.
An existing test might be to equip the existing warning for bool unsigned double meh(void) {return 0;} with a fix-it hint instead of the brief error: two or more data types in declaration of ‘meh’. Likewise for bool unsigned meh(void) {return 0;} error: ‘unsigned’ specified with ‘bool’ so we wouldn't need a plugin, and it might even be useful? ;) cheers, * g++.dg/plugin/plugin.exp: Add new test. * g++.dg/plugin/result-decl-plugin-test-1.C: New test. * g++.dg/plugin/result-decl-plugin-test-2.C: New test. * g++.dg/plugin/result_decl_plugin.C: New test. --- gcc/testsuite/g++.dg/plugin/plugin.exp | 3 + .../g++.dg/plugin/result-decl-plugin-test-1.C | 28 +++++++++ .../g++.dg/plugin/result-decl-plugin-test-2.C | 61 +++++++++++++++++++ .../g++.dg/plugin/result_decl_plugin.C | 57 +++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-1.C create mode 100644 gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-2.C create mode 100644 gcc/testsuite/g++.dg/plugin/result_decl_plugin.C diff --git a/gcc/testsuite/g++.dg/plugin/plugin.exp b/gcc/testsuite/g++.dg/plugin/plugin.exp index b5fb42fa77a..f2b526b4704 100644 --- a/gcc/testsuite/g++.dg/plugin/plugin.exp +++ b/gcc/testsuite/g++.dg/plugin/plugin.exp @@ -80,6 +80,9 @@ set plugin_test_list [list \ show-template-tree-color-labels.C \ show-template-tree-color-no-elide-type.C } \ { comment_plugin.c comments-1.C } \ + { result_decl_plugin.C \ + result-decl-plugin-test-1.C \ + result-decl-plugin-test-2.C } \ ] foreach plugin_test $plugin_test_list { diff --git a/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-1.C b/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-1.C new file mode 100644 index 00000000000..bd323181d70 --- /dev/null +++ b/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-1.C @@ -0,0 +1,28 @@ +/* Verify that class member functions result decl have the correct location. */ +// { dg-options "-fdiagnostics-generate-patch" } +namespace std { template < typename, typename > struct pair; } +template < typename > struct __mini_vector +{ + int _M_finish; + const + unsigned long + __attribute__((deprecated)) + _M_space_left() + { return _M_finish != 0; } +}; + template class __mini_vector< std::pair< long, long > >; + template class __mini_vector< int >; +#if 0 +{ dg-begin-multiline-output "" } +@@ -5,7 +5,7 @@ template < typename > struct __mini_vect + { + int _M_finish; + const +- unsigned long ++ bool + __attribute__((deprecated)) + _M_space_left() + { return _M_finish != 0; } + +{ dg-end-multiline-output "" } +#endif diff --git a/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-2.C b/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-2.C new file mode 100644 index 00000000000..385a7ef482f --- /dev/null +++ b/gcc/testsuite/g++.dg/plugin/result-decl-plugin-test-2.C @@ -0,0 +1,61 @@ +/* Verify that template functions result decl have the correct location. */ +// { dg-options "-fdiagnostics-generate-patch" } +template <class T> +int +f() +{ + return 42; +} +int main() +{ + f<int>(); +} +unsigned long long huh(void) +{ + return 1ULL; +} +#if 0 +{ dg-begin-multiline-output "" } +g++.dg/plugin/result-decl-plugin-test-2.C:4:1: warning: Function ‘f’ result location + 4 | int + | ^~~ + | bool +g++.dg/plugin/result-decl-plugin-test-2.C:9:1: warning: Function ‘main’ result location + 9 | int main() + | ^~~ + | bool +g++.dg/plugin/result-decl-plugin-test-2.C:13:28: warning: Function ‘huh’ result location + 13 | unsigned long long huh(void) + | ^ + | bool +g++.dg/plugin/result-decl-plugin-test-2.C: In instantiation of ‘int f() [with T = int]’: +g++.dg/plugin/result-decl-plugin-test-2.C:11:10: required from here +g++.dg/plugin/result-decl-plugin-test-2.C:4:1: warning: Function ‘f’ result location + 4 | int + | ^~~ + | bool +--- g++.dg/plugin/result-decl-plugin-test-2.C ++++ g++.dg/plugin/result-decl-plugin-test-2.C +@@ -1,16 +1,16 @@ + /* Verify that template functions result decl have the correct location. */ + // { dg-options "-fdiagnostics-generate-patch" } + template <class T> +-int ++bool + f() + { + return 42; + } +-int main() ++bool main() + { + f<int>(); + } +-unsigned long long huh(void) ++unsigned long long huh(voidbool + { + return 1ULL; + } +{ dg-end-multiline-output "" } +#endif +// Note: f() should not +bbool with an off-by-one for the start 'b' ! diff --git a/gcc/testsuite/g++.dg/plugin/result_decl_plugin.C b/gcc/testsuite/g++.dg/plugin/result_decl_plugin.C new file mode 100644 index 00000000000..40f54a6acfe --- /dev/null +++ b/gcc/testsuite/g++.dg/plugin/result_decl_plugin.C @@ -0,0 +1,57 @@ +/* A plugin example that points at the location of function decl result decl */ +/* This file is part of GCC */ +/* { dg-options "-O" } */ +#include "gcc-plugin.h" +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tree.h" +#include "tree-pass.h" +#include "intl.h" +#include "diagnostic.h" +#include "gcc-rich-location.h" +#include "langhooks.h" +#include "plugin-version.h" + +static struct plugin_info _this_info = { + .version = "1", + .help = "None", +}; +/* Callback function to invoke after GCC finishes a declaration. */ + +static void plugin_finish_decl (void *event_data, void *data) +{ + tree decl = (tree) event_data; + if (!decl || TREE_CODE (decl) != FUNCTION_DECL) + return; + + tree logical_1_t = boolean_type_node; + tree logical_1_n = DECL_NAME (TYPE_NAME (logical_1_t)); + location_t result_loc = DECL_SOURCE_LOCATION (DECL_RESULT (decl)); + gcc_rich_location richloc (result_loc); + richloc.add_fixit_replace (result_loc, IDENTIFIER_POINTER (logical_1_n)); + + warning_at (&richloc, 0, G_("Function %qs result location"), + IDENTIFIER_POINTER (DECL_NAME (decl))); +} + +int +plugin_init (struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version) +{ + if (!plugin_default_version_check (version, &gcc_version)) + { + error(G_("incompatible gcc/plugin versions")); + return 1; + } + + const char *plugin_name = plugin_info->base_name; + + register_callback(plugin_name, PLUGIN_INFO, NULL, &_this_info); + register_callback (plugin_name, PLUGIN_FINISH_PARSE_FUNCTION, + plugin_finish_decl, NULL); + return 0; +} + +/* Announce that we are GPL. */ +int plugin_is_GPL_compatible; -- 2.38.1