Commit bc31a87a by David Malcolm Committed by David Malcolm

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
parent 2e2bd24b
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> 2018-08-03 Jason Merrill <jason@redhat.com>
PR c++/86706 PR c++/86706
......
...@@ -15710,6 +15710,22 @@ maybe_save_function_definition (tree fun) ...@@ -15710,6 +15710,22 @@ maybe_save_function_definition (tree fun)
register_constexpr_fundef (fun, DECL_SAVED_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 /* Finish up a function declaration and compile that function
all the way to assembler language output. The free the storage all the way to assembler language output. The free the storage
for the function definition. INLINE_P is TRUE if we just for the function definition. INLINE_P is TRUE if we just
...@@ -15903,8 +15919,21 @@ finish_function (bool inline_p) ...@@ -15903,8 +15919,21 @@ finish_function (bool inline_p)
&& !DECL_DESTRUCTOR_P (fndecl) && !DECL_DESTRUCTOR_P (fndecl)
&& targetm.warn_func_return (fndecl)) && targetm.warn_func_return (fndecl))
{ {
warning (OPT_Wreturn_type, gcc_rich_location richloc (input_location);
"no return statement in function returning non-void"); /* 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; TREE_NO_WARNING (fndecl) = 1;
} }
......
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> 2018-08-03 Bogdan Harjoc <harjoc@gmail.com>
PR c/86690 PR c/86690
......
/* { 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 "" } */
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment