From ff0425cdeb49db33d4bfe736829005544b45e659 Mon Sep 17 00:00:00 2001
From: Jonathan Wakely <jwakely@redhat.com>
Date: Tue, 8 Jan 2019 08:57:58 +0000
Subject: [PATCH] re PR c++/88554 (Segfault ICE when falling off the end of a
 reference-returning friend operator)

	PR c++/88554
	* decl.c (finish_function): For -Wreturn-type don't add a return *this;
	fixit hint if current_class_ref is NULL.  Use a single if instead of
	two nested ones.

	* g++.dg/warn/Wreturn-type-11.C: New test.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>

From-SVN: r267672
---
 gcc/cp/ChangeLog                            |  8 ++++++++
 gcc/cp/decl.c                               |  9 +++++----
 gcc/testsuite/ChangeLog                     |  6 ++++++
 gcc/testsuite/g++.dg/warn/Wreturn-type-11.C | 11 +++++++++++
 4 files changed, 30 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/Wreturn-type-11.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4da1c82334a2..32c7f40b2129 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2019-01-08  Jonathan Wakely  <jwakely@redhat.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/88554
+	* decl.c (finish_function): For -Wreturn-type don't add a return *this;
+	fixit hint if current_class_ref is NULL.  Use a single if instead of
+	two nested ones.
+
 2019-01-07  Paolo Carlini  <paolo.carlini@oracle.com>
 
 	* decl.c (start_decl): Improve two error_at locations.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 220a95c4b0ff..f456c070dcd2 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -16097,11 +16097,12 @@ finish_function (bool inline_p)
 	{
 	  tree valtype = TREE_TYPE (DECL_RESULT (fndecl));
 	  if (TREE_CODE (valtype) == REFERENCE_TYPE
+	      && current_class_ref
 	      && 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);
+		  (TREE_TYPE (valtype), TREE_TYPE (current_class_ref))
+	      && 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");
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 23de2ea6f0b0..552ba4dd9778 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-01-08  Jonathan Wakely  <jwakely@redhat.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/88554
+	* g++.dg/warn/Wreturn-type-11.C: New test.
+
 2019-01-07  David Malcolm  <dmalcolm@redhat.com>
 
 	PR jit/88747
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-type-11.C b/gcc/testsuite/g++.dg/warn/Wreturn-type-11.C
new file mode 100644
index 000000000000..35d05eb6012c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wreturn-type-11.C
@@ -0,0 +1,11 @@
+// PR c++/88554
+// { dg-do compile }
+// { dg-options "-Wreturn-type" }
+
+struct X {
+  friend X & operator+= (X &, int) { }	// { dg-warning "no return statement in function returning non-void" }
+					// { dg-bogus "return \\*this;" "" { target *-*-* } .-1 }
+};
+struct Y {};
+Y & operator += (Y &, Y &) { }		// { dg-warning "no return statement in function returning non-void" }
+					// { dg-bogus "return \\*this;" "" { target *-*-* } .-1 }
-- 
GitLab