re PR c++/44859 (missed warning: returning reference to temporary)
authorPatrick Palka <patrick@parcs.ath.cx>
Tue, 1 Apr 2014 00:48:33 +0000 (20:48 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 1 Apr 2014 00:48:33 +0000 (20:48 -0400)
PR c++/44859
* typeck.c (maybe_warn_about_returning_address_of_local): Unwrap
COMPONENT_REFs and ARRAY_REFs sooner.

From-SVN: r208970

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/g++.dg/warn/Wreturn-local-addr-2.C [new file with mode: 0644]

index aca5f44..553a059 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2014-03-29  Adam Butcher  <adam@jessamine.co.uk>
 
        PR c++/60626
index 559f19b..9a80727 100644 (file)
@@ -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 (file)
index 0000000..c483601
--- /dev/null
@@ -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" }