Add fix-it hint for missing return statement in assignment operators (PR c++/85523)
gcc/cp/ChangeLog: PR c++/85523 * decl.c: Include "gcc-rich-location.h". (add_return_star_this_fixit): New function. (finish_function): When warning about missing return statements in functions returning non-void, add a "return *this;" fix-it hint for assignment operators. gcc/testsuite/ChangeLog: PR c++/85523 * g++.dg/pr85523.C: New test. Co-Authored-By: Jonathan Wakely <jwakely@redhat.com> From-SVN: r263298
This commit is contained in:
parent
2e2bd24b7c
commit
bc31a87ac7
4 changed files with 134 additions and 2 deletions
|
@ -1,3 +1,12 @@
|
|||
2018-08-03 David Malcolm <dmalcolm@redhat.com>
|
||||
Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* decl.c: Include "gcc-rich-location.h".
|
||||
(add_return_star_this_fixit): New function.
|
||||
(finish_function): When warning about missing return statements in
|
||||
functions returning non-void, add a "return *this;" fix-it hint for
|
||||
assignment operators.
|
||||
|
||||
2018-08-03 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/86706
|
||||
|
|
|
@ -15710,6 +15710,22 @@ maybe_save_function_definition (tree fun)
|
|||
register_constexpr_fundef (fun, DECL_SAVED_TREE (fun));
|
||||
}
|
||||
|
||||
/* Attempt to add a fix-it hint to RICHLOC suggesting the insertion
|
||||
of "return *this;" immediately before its location, using FNDECL's
|
||||
first statement (if any) to give the indentation, if appropriate. */
|
||||
|
||||
static void
|
||||
add_return_star_this_fixit (gcc_rich_location *richloc, tree fndecl)
|
||||
{
|
||||
location_t indent = UNKNOWN_LOCATION;
|
||||
tree stmts = expr_first (DECL_SAVED_TREE (fndecl));
|
||||
if (stmts)
|
||||
indent = EXPR_LOCATION (stmts);
|
||||
richloc->add_fixit_insert_formatted ("return *this;",
|
||||
richloc->get_loc (),
|
||||
indent);
|
||||
}
|
||||
|
||||
/* Finish up a function declaration and compile that function
|
||||
all the way to assembler language output. The free the storage
|
||||
for the function definition. INLINE_P is TRUE if we just
|
||||
|
@ -15903,8 +15919,21 @@ finish_function (bool inline_p)
|
|||
&& !DECL_DESTRUCTOR_P (fndecl)
|
||||
&& targetm.warn_func_return (fndecl))
|
||||
{
|
||||
warning (OPT_Wreturn_type,
|
||||
"no return statement in function returning non-void");
|
||||
gcc_rich_location richloc (input_location);
|
||||
/* Potentially add a "return *this;" fix-it hint for
|
||||
assignment operators. */
|
||||
if (IDENTIFIER_ASSIGN_OP_P (DECL_NAME (fndecl)))
|
||||
{
|
||||
tree valtype = TREE_TYPE (DECL_RESULT (fndecl));
|
||||
if (TREE_CODE (valtype) == REFERENCE_TYPE
|
||||
&& same_type_ignoring_top_level_qualifiers_p
|
||||
(TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
|
||||
if (global_dc->option_enabled (OPT_Wreturn_type,
|
||||
global_dc->option_state))
|
||||
add_return_star_this_fixit (&richloc, fndecl);
|
||||
}
|
||||
warning_at (&richloc, OPT_Wreturn_type,
|
||||
"no return statement in function returning non-void");
|
||||
TREE_NO_WARNING (fndecl) = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2018-08-03 David Malcolm <dmalcolm@redhat.com>
|
||||
Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR c++/85523
|
||||
* g++.dg/pr85523.C: New test.
|
||||
|
||||
2018-08-03 Bogdan Harjoc <harjoc@gmail.com>
|
||||
|
||||
PR c/86690
|
||||
|
|
88
gcc/testsuite/g++.dg/pr85523.C
Normal file
88
gcc/testsuite/g++.dg/pr85523.C
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* { dg-options "-fdiagnostics-show-caret" } */
|
||||
|
||||
/* Verify that we emit a "return *this;" fix-it hint for
|
||||
a missing return in an assignment operator. */
|
||||
|
||||
struct s1 {
|
||||
s1& operator=(const s1&) { } // { dg-warning "no return statement in function returning non-void" }
|
||||
/* { dg-begin-multiline-output "" }
|
||||
s1& operator=(const s1&) { }
|
||||
^
|
||||
return *this;
|
||||
{ dg-end-multiline-output "" } */
|
||||
};
|
||||
|
||||
/* Likewise for +=. */
|
||||
|
||||
struct s2 {
|
||||
s2& operator+=(const s2&) {} // { dg-warning "no return statement in function returning non-void" }
|
||||
/* { dg-begin-multiline-output "" }
|
||||
s2& operator+=(const s2&) {}
|
||||
^
|
||||
return *this;
|
||||
{ dg-end-multiline-output "" } */
|
||||
};
|
||||
|
||||
/* No warning for "void" return. */
|
||||
|
||||
struct s3 {
|
||||
void operator=(const s3&) { }
|
||||
};
|
||||
|
||||
/* We shouldn't issue the fix-it hint if the return type isn't right. */
|
||||
|
||||
struct s4 {
|
||||
int operator=(int) { } // { dg-warning "no return statement in function returning non-void" }
|
||||
/* { dg-begin-multiline-output "" }
|
||||
int operator=(int) { }
|
||||
^
|
||||
{ dg-end-multiline-output "" } */
|
||||
};
|
||||
|
||||
/* Example of a multi-line fix-it hint. */
|
||||
|
||||
struct s5 {
|
||||
int i;
|
||||
s5& operator=(const s5& z) {
|
||||
i = z.i;
|
||||
} // { dg-warning "no return statement in function returning non-void" }
|
||||
/* { dg-begin-multiline-output "" }
|
||||
+ return *this;
|
||||
}
|
||||
^
|
||||
{ dg-end-multiline-output "" } */
|
||||
};
|
||||
|
||||
/* Example of a multi-line fix-it hint with other statements. */
|
||||
|
||||
extern void log (const char *);
|
||||
struct s6 {
|
||||
int i;
|
||||
s6& operator=(const s6& z) {
|
||||
log ("operator=\n");
|
||||
i = z.i;
|
||||
} // { dg-warning "no return statement in function returning non-void" }
|
||||
/* { dg-begin-multiline-output "" }
|
||||
+ return *this;
|
||||
}
|
||||
^
|
||||
{ dg-end-multiline-output "" } */
|
||||
};
|
||||
|
||||
/* Another example of a multi-line fix-it hint with other statements. */
|
||||
|
||||
struct s7 {
|
||||
int i;
|
||||
s7& operator=(const s6& z) {
|
||||
if (z.i)
|
||||
log ("operator=\n");
|
||||
else
|
||||
log ("operator=\n");
|
||||
i = z.i;
|
||||
} // { dg-warning "no return statement in function returning non-void" }
|
||||
/* { dg-begin-multiline-output "" }
|
||||
+ return *this;
|
||||
}
|
||||
^
|
||||
{ dg-end-multiline-output "" } */
|
||||
};
|
Loading…
Add table
Reference in a new issue