diff mbox

Fix PR c++/44859

Message ID 1396271151-12458-1-git-send-email-patrick@parcs.ath.cx
State New
Headers show

Commit Message

Patrick Palka March 31, 2014, 1:05 p.m. UTC
Hi,

In PR c++/44859, it is noted that the following code does not emit a
"returning reference to temporary" warning:

  struct Base2 { int m_foo; };
  struct Derived2 : public Base2 {};
  const Base2& f8() { return Derived2(); } // <-- here

The source of the problem seems to be that
maybe_warn_about_returning_address_of_local() does not look through
COMPONENT_REFs in a function's return value if the function's return
type is a REFERENCE_TYPE.  This patch simply changes the just mentioned
function to look through COMPONENT_REFs (and ARRAY_REFs)
unconditionally.

This change was successfully bootstrapped and regtested against
x86_64-unknown-linux-gnu.

2014-03-31  Patrick Palka  patrick@parcs.ath.cx

	PR c++/44859
	* typeck.c (maybe_warn_about_returning_address_of_local): Unwrap
	COMPONENT_REFs and ARRAY_REFs sooner.
---
 gcc/cp/typeck.c                                  |  8 ++++----
 gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C | 11 +++++++++++
 2 files changed, 15 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C

Comments

Jason Merrill April 1, 2014, 7:18 p.m. UTC | #1
Applied, thanks.

Jason
diff mbox

Patch

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 559f19b5..9a80727 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8283,6 +8283,10 @@  maybe_warn_about_returning_address_of_local (tree retval)
     return;
   whats_returned = TREE_OPERAND (whats_returned, 0);
 
+  while (TREE_CODE (whats_returned) == COMPONENT_REF
+	 || TREE_CODE (whats_returned) == ARRAY_REF)
+    whats_returned = TREE_OPERAND (whats_returned, 0);
+
   if (TREE_CODE (valtype) == REFERENCE_TYPE)
     {
       if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
@@ -8300,10 +8304,6 @@  maybe_warn_about_returning_address_of_local (tree retval)
 	}
     }
 
-  while (TREE_CODE (whats_returned) == COMPONENT_REF
-	 || TREE_CODE (whats_returned) == ARRAY_REF)
-    whats_returned = TREE_OPERAND (whats_returned, 0);
-
   if (DECL_P (whats_returned)
       && DECL_NAME (whats_returned)
       && DECL_FUNCTION_SCOPE_P (whats_returned)
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C
new file mode 100644
index 0000000..c483601
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C
@@ -0,0 +1,11 @@ 
+// PR c++/44859
+
+struct Base2 { int m_foo; };
+struct Derived2 : public Base2 {};
+
+const Base2& f8() { return Derived2(); } // { dg-warning "reference to temporary" }
+
+struct foo { };
+struct bar { foo base; };
+
+const foo& f9() { return bar().base; } // { dg-warning "reference to temporary" }