Re: [PATCH v2] C++: Add fix-it hints for -Wold-style-cast
On Wed, May 3, 2017 at 9:51 AM, David Malcolmwrote: > On Thu, 2017-04-27 at 23:03 +0200, Marek Polacek wrote: >> On Thu, Apr 27, 2017 at 05:10:24PM -0400, David Malcolm wrote: >> > + /* First try const_cast. */ >> > + trial = build_const_cast (dst_type, orig_expr, 0 /* complain >> > */); >> > + if (trial != error_mark_node) >> > +return "const_cast"; >> > + >> > + /* If that fails, try static_cast. */ >> > + trial = build_static_cast (dst_type, orig_expr, 0 /* complain >> > */); >> > + if (trial != error_mark_node) >> > +return "static_cast"; >> > + >> > + /* Finally, try reinterpret_cast. */ >> > + trial = build_reinterpret_cast (dst_type, orig_expr, 0 /* >> > complain */); >> > + if (trial != error_mark_node) >> > +return "reinterpret_cast"; >> >> I think you'll want tf_none instead of 0 /* complain */ in these. >> >> Marek > > Thanks. > > Here's an updated version of the patch. > > Changes since v1: > - updated expected fixit-formatting (the new fix-it printer in > r247548 handles this properly now) > - added new test cases as suggested by Florian > - use "tf_none" rather than "0 /* complain */" > > Successfully bootstrapped on x86_64-pc-linux-gnu. > > OK for trunk? OK. Jason
[PING^3] re [PATCH v2] C++: Add fix-it hints for -Wold-style-cast
Ping re this patch: https://gcc.gnu.org/ml/gcc-patches/2017-05/msg00204.html (more description can be seen in v1 of the patch here: https://gcc.gnu.org/ml/gcc-patches/2017-04/msg01429.html ) On Mon, 2017-06-05 at 12:41 -0400, David Malcolm wrote: > Ping re this patch: > > https://gcc.gnu.org/ml/gcc-patches/2017-05/msg00204.html > > On Fri, 2017-05-26 at 15:35 -0400, David Malcolm wrote: > > On Wed, 2017-05-03 at 09:51 -0400, David Malcolm wrote: > > > On Thu, 2017-04-27 at 23:03 +0200, Marek Polacek wrote: > > > > On Thu, Apr 27, 2017 at 05:10:24PM -0400, David Malcolm wrote: > > > > > + /* First try const_cast. */ > > > > > + trial = build_const_cast (dst_type, orig_expr, 0 /* > > > > > complain > > > > > */); > > > > > + if (trial != error_mark_node) > > > > > +return "const_cast"; > > > > > + > > > > > + /* If that fails, try static_cast. */ > > > > > + trial = build_static_cast (dst_type, orig_expr, 0 /* > > > > > complain > > > > > */); > > > > > + if (trial != error_mark_node) > > > > > +return "static_cast"; > > > > > + > > > > > + /* Finally, try reinterpret_cast. */ > > > > > + trial = build_reinterpret_cast (dst_type, orig_expr, 0 /* > > > > > complain */); > > > > > + if (trial != error_mark_node) > > > > > +return "reinterpret_cast"; > > > > > > > > I think you'll want tf_none instead of 0 /* complain */ in > > > > these. > > > > > > > > Marek > > > > > > Thanks. > > > > > > Here's an updated version of the patch. > > > > > > Changes since v1: > > > - updated expected fixit-formatting (the new fix-it printer in > > > r247548 handles this properly now) > > > - added new test cases as suggested by Florian > > > - use "tf_none" rather than "0 /* complain */" > > > > > > Successfully bootstrapped on x86_64-pc-linux-gnu. > > > > > > OK for trunk? > > > > > > gcc/cp/ChangeLog: > > > * parser.c (get_cast_suggestion): New function. > > > (maybe_add_cast_fixit): New function. > > > (cp_parser_cast_expression): Capture the location of the > > > closing > > > parenthesis. Call maybe_add_cast_fixit when emitting warnings > > > about old-style casts. > > > > > > gcc/testsuite/ChangeLog: > > > * g++.dg/other/old-style-cast-fixits.C: New test case. > > > --- > > > gcc/cp/parser.c| 93 > > > - > > > gcc/testsuite/g++.dg/other/old-style-cast-fixits.C | 95 > > > ++ > > > 2 files changed, 186 insertions(+), 2 deletions(-) > > > create mode 100644 gcc/testsuite/g++.dg/other/old-style-cast > > > -fixits.C > > > > > > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > > > index 4714bc6..2f83aa9 100644 > > > --- a/gcc/cp/parser.c > > > +++ b/gcc/cp/parser.c > > > @@ -8633,6 +8633,85 @@ cp_parser_tokens_start_cast_expression > > > (cp_parser *parser) > > > } > > > } > > > > > > +/* Try to find a legal C++-style cast to DST_TYPE for ORIG_EXPR, > > > trying them > > > + in the order: const_cast, static_cast, reinterpret_cast. > > > + > > > + Don't suggest dynamic_cast. > > > + > > > + Return the first legal cast kind found, or NULL otherwise. > > > */ > > > + > > > +static const char * > > > +get_cast_suggestion (tree dst_type, tree orig_expr) > > > +{ > > > + tree trial; > > > + > > > + /* Reuse the parser logic by attempting to build the various > > > kinds > > > of > > > + cast, with "complain" disabled. > > > + Identify the first such cast that is valid. */ > > > + > > > + /* Don't attempt to run such logic within template processing. > > > */ > > > + if (processing_template_decl) > > > +return NULL; > > > + > > > + /* First try const_cast. */ > > > + trial = build_const_cast (dst_type, orig_expr, tf_none); > > > + if (trial != error_mark_node) > > > +return "const_cast"; > > > + > > > + /* If that fails, try static_cast. */ > > > + trial = build_static_cast (dst_type, orig_expr, tf_none); > > > + if (trial != error_mark_node) > > > +return "static_cast"; > > > + > > > + /* Finally, try reinterpret_cast. */ > > > + trial = build_reinterpret_cast (dst_type, orig_expr, tf_none); > > > + if (trial != error_mark_node) > > > +return "reinterpret_cast"; > > > + > > > + /* No such cast possible. */ > > > + return NULL; > > > +} > > > + > > > +/* If -Wold-style-cast is enabled, add fix-its to RICHLOC, > > > + suggesting how to convert a C-style cast of the form: > > > + > > > + (DST_TYPE)ORIG_EXPR > > > + > > > + to a C++-style cast. > > > + > > > + The primary range of RICHLOC is asssumed to be that of the > > > original > > > + expression. OPEN_PAREN_LOC and CLOSE_PAREN_LOC give the > > > locations > > > + of the parens in the C-style cast. */ > > > + > > > +static void > > > +maybe_add_cast_fixit (rich_location *rich_loc, location_t > > > open_paren_loc, > > > + location_t close_paren_loc, tree > > > orig_expr, > > > + tree dst_type) > > > +{ > > > + /* This function is
[PING^2] re [PATCH v2] C++: Add fix-it hints for -Wold-style-cast
Ping re this patch: https://gcc.gnu.org/ml/gcc-patches/2017-05/msg00204.html On Fri, 2017-05-26 at 15:35 -0400, David Malcolm wrote: > On Wed, 2017-05-03 at 09:51 -0400, David Malcolm wrote: > > On Thu, 2017-04-27 at 23:03 +0200, Marek Polacek wrote: > > > On Thu, Apr 27, 2017 at 05:10:24PM -0400, David Malcolm wrote: > > > > + /* First try const_cast. */ > > > > + trial = build_const_cast (dst_type, orig_expr, 0 /* complain > > > > */); > > > > + if (trial != error_mark_node) > > > > +return "const_cast"; > > > > + > > > > + /* If that fails, try static_cast. */ > > > > + trial = build_static_cast (dst_type, orig_expr, 0 /* > > > > complain > > > > */); > > > > + if (trial != error_mark_node) > > > > +return "static_cast"; > > > > + > > > > + /* Finally, try reinterpret_cast. */ > > > > + trial = build_reinterpret_cast (dst_type, orig_expr, 0 /* > > > > complain */); > > > > + if (trial != error_mark_node) > > > > +return "reinterpret_cast"; > > > > > > I think you'll want tf_none instead of 0 /* complain */ in these. > > > > > > Marek > > > > Thanks. > > > > Here's an updated version of the patch. > > > > Changes since v1: > > - updated expected fixit-formatting (the new fix-it printer in > > r247548 handles this properly now) > > - added new test cases as suggested by Florian > > - use "tf_none" rather than "0 /* complain */" > > > > Successfully bootstrapped on x86_64-pc-linux-gnu. > > > > OK for trunk? > > > > gcc/cp/ChangeLog: > > * parser.c (get_cast_suggestion): New function. > > (maybe_add_cast_fixit): New function. > > (cp_parser_cast_expression): Capture the location of the > > closing > > parenthesis. Call maybe_add_cast_fixit when emitting warnings > > about old-style casts. > > > > gcc/testsuite/ChangeLog: > > * g++.dg/other/old-style-cast-fixits.C: New test case. > > --- > > gcc/cp/parser.c| 93 > > - > > gcc/testsuite/g++.dg/other/old-style-cast-fixits.C | 95 > > ++ > > 2 files changed, 186 insertions(+), 2 deletions(-) > > create mode 100644 gcc/testsuite/g++.dg/other/old-style-cast > > -fixits.C > > > > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > > index 4714bc6..2f83aa9 100644 > > --- a/gcc/cp/parser.c > > +++ b/gcc/cp/parser.c > > @@ -8633,6 +8633,85 @@ cp_parser_tokens_start_cast_expression > > (cp_parser *parser) > > } > > } > > > > +/* Try to find a legal C++-style cast to DST_TYPE for ORIG_EXPR, > > trying them > > + in the order: const_cast, static_cast, reinterpret_cast. > > + > > + Don't suggest dynamic_cast. > > + > > + Return the first legal cast kind found, or NULL otherwise. */ > > + > > +static const char * > > +get_cast_suggestion (tree dst_type, tree orig_expr) > > +{ > > + tree trial; > > + > > + /* Reuse the parser logic by attempting to build the various > > kinds > > of > > + cast, with "complain" disabled. > > + Identify the first such cast that is valid. */ > > + > > + /* Don't attempt to run such logic within template processing. > > */ > > + if (processing_template_decl) > > +return NULL; > > + > > + /* First try const_cast. */ > > + trial = build_const_cast (dst_type, orig_expr, tf_none); > > + if (trial != error_mark_node) > > +return "const_cast"; > > + > > + /* If that fails, try static_cast. */ > > + trial = build_static_cast (dst_type, orig_expr, tf_none); > > + if (trial != error_mark_node) > > +return "static_cast"; > > + > > + /* Finally, try reinterpret_cast. */ > > + trial = build_reinterpret_cast (dst_type, orig_expr, tf_none); > > + if (trial != error_mark_node) > > +return "reinterpret_cast"; > > + > > + /* No such cast possible. */ > > + return NULL; > > +} > > + > > +/* If -Wold-style-cast is enabled, add fix-its to RICHLOC, > > + suggesting how to convert a C-style cast of the form: > > + > > + (DST_TYPE)ORIG_EXPR > > + > > + to a C++-style cast. > > + > > + The primary range of RICHLOC is asssumed to be that of the > > original > > + expression. OPEN_PAREN_LOC and CLOSE_PAREN_LOC give the > > locations > > + of the parens in the C-style cast. */ > > + > > +static void > > +maybe_add_cast_fixit (rich_location *rich_loc, location_t > > open_paren_loc, > > + location_t close_paren_loc, tree orig_expr, > > + tree dst_type) > > +{ > > + /* This function is non-trivial, so bail out now if the warning > > isn't > > + going to be emitted. */ > > + if (!warn_old_style_cast) > > +return; > > + > > + /* Try to find a legal C++ cast, trying them in order: > > + const_cast, static_cast, reinterpret_cast. */ > > + const char *cast_suggestion = get_cast_suggestion (dst_type, > > orig_expr); > > + if (!cast_suggestion) > > +return; > > + > > + /* Replace the open paren with "CAST_SUGGESTION<". */ > > + pretty_printer pp; > > + pp_printf (, "%s<", cast_suggestion); > > +
[PING] re [PATCH v2] C++: Add fix-it hints for -Wold-style-cast
On Wed, 2017-05-03 at 09:51 -0400, David Malcolm wrote: > On Thu, 2017-04-27 at 23:03 +0200, Marek Polacek wrote: > > On Thu, Apr 27, 2017 at 05:10:24PM -0400, David Malcolm wrote: > > > + /* First try const_cast. */ > > > + trial = build_const_cast (dst_type, orig_expr, 0 /* complain > > > */); > > > + if (trial != error_mark_node) > > > +return "const_cast"; > > > + > > > + /* If that fails, try static_cast. */ > > > + trial = build_static_cast (dst_type, orig_expr, 0 /* complain > > > */); > > > + if (trial != error_mark_node) > > > +return "static_cast"; > > > + > > > + /* Finally, try reinterpret_cast. */ > > > + trial = build_reinterpret_cast (dst_type, orig_expr, 0 /* > > > complain */); > > > + if (trial != error_mark_node) > > > +return "reinterpret_cast"; > > > > I think you'll want tf_none instead of 0 /* complain */ in these. > > > > Marek > > Thanks. > > Here's an updated version of the patch. > > Changes since v1: > - updated expected fixit-formatting (the new fix-it printer in > r247548 handles this properly now) > - added new test cases as suggested by Florian > - use "tf_none" rather than "0 /* complain */" > > Successfully bootstrapped on x86_64-pc-linux-gnu. > > OK for trunk? > > gcc/cp/ChangeLog: > * parser.c (get_cast_suggestion): New function. > (maybe_add_cast_fixit): New function. > (cp_parser_cast_expression): Capture the location of the > closing > parenthesis. Call maybe_add_cast_fixit when emitting warnings > about old-style casts. > > gcc/testsuite/ChangeLog: > * g++.dg/other/old-style-cast-fixits.C: New test case. > --- > gcc/cp/parser.c| 93 > - > gcc/testsuite/g++.dg/other/old-style-cast-fixits.C | 95 > ++ > 2 files changed, 186 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/other/old-style-cast > -fixits.C > > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > index 4714bc6..2f83aa9 100644 > --- a/gcc/cp/parser.c > +++ b/gcc/cp/parser.c > @@ -8633,6 +8633,85 @@ cp_parser_tokens_start_cast_expression > (cp_parser *parser) > } > } > > +/* Try to find a legal C++-style cast to DST_TYPE for ORIG_EXPR, > trying them > + in the order: const_cast, static_cast, reinterpret_cast. > + > + Don't suggest dynamic_cast. > + > + Return the first legal cast kind found, or NULL otherwise. */ > + > +static const char * > +get_cast_suggestion (tree dst_type, tree orig_expr) > +{ > + tree trial; > + > + /* Reuse the parser logic by attempting to build the various kinds > of > + cast, with "complain" disabled. > + Identify the first such cast that is valid. */ > + > + /* Don't attempt to run such logic within template processing. */ > + if (processing_template_decl) > +return NULL; > + > + /* First try const_cast. */ > + trial = build_const_cast (dst_type, orig_expr, tf_none); > + if (trial != error_mark_node) > +return "const_cast"; > + > + /* If that fails, try static_cast. */ > + trial = build_static_cast (dst_type, orig_expr, tf_none); > + if (trial != error_mark_node) > +return "static_cast"; > + > + /* Finally, try reinterpret_cast. */ > + trial = build_reinterpret_cast (dst_type, orig_expr, tf_none); > + if (trial != error_mark_node) > +return "reinterpret_cast"; > + > + /* No such cast possible. */ > + return NULL; > +} > + > +/* If -Wold-style-cast is enabled, add fix-its to RICHLOC, > + suggesting how to convert a C-style cast of the form: > + > + (DST_TYPE)ORIG_EXPR > + > + to a C++-style cast. > + > + The primary range of RICHLOC is asssumed to be that of the > original > + expression. OPEN_PAREN_LOC and CLOSE_PAREN_LOC give the > locations > + of the parens in the C-style cast. */ > + > +static void > +maybe_add_cast_fixit (rich_location *rich_loc, location_t > open_paren_loc, > + location_t close_paren_loc, tree orig_expr, > + tree dst_type) > +{ > + /* This function is non-trivial, so bail out now if the warning > isn't > + going to be emitted. */ > + if (!warn_old_style_cast) > +return; > + > + /* Try to find a legal C++ cast, trying them in order: > + const_cast, static_cast, reinterpret_cast. */ > + const char *cast_suggestion = get_cast_suggestion (dst_type, > orig_expr); > + if (!cast_suggestion) > +return; > + > + /* Replace the open paren with "CAST_SUGGESTION<". */ > + pretty_printer pp; > + pp_printf (, "%s<", cast_suggestion); > + rich_loc->add_fixit_replace (open_paren_loc, pp_formatted_text > ()); > + > + /* Replace the close paren with "> (". */ > + rich_loc->add_fixit_replace (close_paren_loc, "> ("); > + > + /* Add a closing paren after the expr (the primary range of > RICH_LOC). */ > + rich_loc->add_fixit_insert_after (")"); > +} > + > + > /* Parse a cast-expression. > > cast-expression: > @@ -8668,6 +8747,7 @@ cp_parser_cast_expression
[PATCH v2] C++: Add fix-it hints for -Wold-style-cast
On Thu, 2017-04-27 at 23:03 +0200, Marek Polacek wrote: > On Thu, Apr 27, 2017 at 05:10:24PM -0400, David Malcolm wrote: > > + /* First try const_cast. */ > > + trial = build_const_cast (dst_type, orig_expr, 0 /* complain > > */); > > + if (trial != error_mark_node) > > +return "const_cast"; > > + > > + /* If that fails, try static_cast. */ > > + trial = build_static_cast (dst_type, orig_expr, 0 /* complain > > */); > > + if (trial != error_mark_node) > > +return "static_cast"; > > + > > + /* Finally, try reinterpret_cast. */ > > + trial = build_reinterpret_cast (dst_type, orig_expr, 0 /* > > complain */); > > + if (trial != error_mark_node) > > +return "reinterpret_cast"; > > I think you'll want tf_none instead of 0 /* complain */ in these. > > Marek Thanks. Here's an updated version of the patch. Changes since v1: - updated expected fixit-formatting (the new fix-it printer in r247548 handles this properly now) - added new test cases as suggested by Florian - use "tf_none" rather than "0 /* complain */" Successfully bootstrapped on x86_64-pc-linux-gnu. OK for trunk? gcc/cp/ChangeLog: * parser.c (get_cast_suggestion): New function. (maybe_add_cast_fixit): New function. (cp_parser_cast_expression): Capture the location of the closing parenthesis. Call maybe_add_cast_fixit when emitting warnings about old-style casts. gcc/testsuite/ChangeLog: * g++.dg/other/old-style-cast-fixits.C: New test case. --- gcc/cp/parser.c| 93 - gcc/testsuite/g++.dg/other/old-style-cast-fixits.C | 95 ++ 2 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/other/old-style-cast-fixits.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4714bc6..2f83aa9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8633,6 +8633,85 @@ cp_parser_tokens_start_cast_expression (cp_parser *parser) } } +/* Try to find a legal C++-style cast to DST_TYPE for ORIG_EXPR, trying them + in the order: const_cast, static_cast, reinterpret_cast. + + Don't suggest dynamic_cast. + + Return the first legal cast kind found, or NULL otherwise. */ + +static const char * +get_cast_suggestion (tree dst_type, tree orig_expr) +{ + tree trial; + + /* Reuse the parser logic by attempting to build the various kinds of + cast, with "complain" disabled. + Identify the first such cast that is valid. */ + + /* Don't attempt to run such logic within template processing. */ + if (processing_template_decl) +return NULL; + + /* First try const_cast. */ + trial = build_const_cast (dst_type, orig_expr, tf_none); + if (trial != error_mark_node) +return "const_cast"; + + /* If that fails, try static_cast. */ + trial = build_static_cast (dst_type, orig_expr, tf_none); + if (trial != error_mark_node) +return "static_cast"; + + /* Finally, try reinterpret_cast. */ + trial = build_reinterpret_cast (dst_type, orig_expr, tf_none); + if (trial != error_mark_node) +return "reinterpret_cast"; + + /* No such cast possible. */ + return NULL; +} + +/* If -Wold-style-cast is enabled, add fix-its to RICHLOC, + suggesting how to convert a C-style cast of the form: + + (DST_TYPE)ORIG_EXPR + + to a C++-style cast. + + The primary range of RICHLOC is asssumed to be that of the original + expression. OPEN_PAREN_LOC and CLOSE_PAREN_LOC give the locations + of the parens in the C-style cast. */ + +static void +maybe_add_cast_fixit (rich_location *rich_loc, location_t open_paren_loc, + location_t close_paren_loc, tree orig_expr, + tree dst_type) +{ + /* This function is non-trivial, so bail out now if the warning isn't + going to be emitted. */ + if (!warn_old_style_cast) +return; + + /* Try to find a legal C++ cast, trying them in order: + const_cast, static_cast, reinterpret_cast. */ + const char *cast_suggestion = get_cast_suggestion (dst_type, orig_expr); + if (!cast_suggestion) +return; + + /* Replace the open paren with "CAST_SUGGESTION<". */ + pretty_printer pp; + pp_printf (, "%s<", cast_suggestion); + rich_loc->add_fixit_replace (open_paren_loc, pp_formatted_text ()); + + /* Replace the close paren with "> (". */ + rich_loc->add_fixit_replace (close_paren_loc, "> ("); + + /* Add a closing paren after the expr (the primary range of RICH_LOC). */ + rich_loc->add_fixit_insert_after (")"); +} + + /* Parse a cast-expression. cast-expression: @@ -8668,6 +8747,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p, /* Consume the `('. */ cp_token *open_paren = cp_lexer_consume_token (parser->lexer); location_t open_paren_loc = open_paren->location; + location_t close_paren_loc = UNKNOWN_LOCATION; /* A very tricky bit is that `(struct S) { 3 }' is a compound-literal