diff mbox

C++ PATCH for c++/986 (warn about temporary bound to reference in constructor)

Message ID 4EBF5132.4060407@redhat.com
State New
Headers show

Commit Message

Jason Merrill Nov. 13, 2011, 5:10 a.m. UTC
My recent work on fixing lifetime extension for temporaries bound to 
references makes it trivial to add this warning.

Tested x86_64-pc-linux-gnu, applied to trunk.
diff mbox

Patch

commit 1db25121594ff9405adeb5bd6892d72679bf2ba1
Author: Jason Merrill <jason@redhat.com>
Date:   Sat Nov 12 20:42:21 2011 -0500

    	PR c++/986
    	* call.c (set_up_extended_ref_temp): Warn about references
    	bound to non-static reference members.
    	* init.c (perform_member_init): Pass in the member.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index dd3026d..181d9e8 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8609,6 +8609,14 @@  set_up_extended_ref_temp (tree decl, tree expr, VEC(tree,gc) **cleanups,
   if (TREE_CODE (expr) != TARGET_EXPR)
     expr = get_target_expr (expr);
 
+  if (TREE_CODE (decl) == FIELD_DECL
+      && extra_warnings && !TREE_NO_WARNING (decl))
+    {
+      warning (OPT_Wextra, "a temporary bound to %qD only persists "
+	       "until the constructor exits", decl);
+      TREE_NO_WARNING (decl) = true;
+    }
+
   /* Recursively extend temps in this initializer.  */
   TARGET_EXPR_INITIAL (expr)
     = extend_ref_init_temps (decl, TARGET_EXPR_INITIAL (expr), cleanups);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 888c151..73f2b67 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -623,7 +623,7 @@  perform_member_init (tree member, tree init)
       if (init == error_mark_node)
 	return;
       /* Use 'this' as the decl, as it has the lifetime we want.  */
-      init = extend_ref_init_temps (current_class_ptr, init, &cleanups);
+      init = extend_ref_init_temps (member, init, &cleanups);
       if (TREE_CODE (type) == ARRAY_TYPE
 	  && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type)))
 	init = build_vec_init_expr (type, init, tf_warning_or_error);
diff --git a/gcc/testsuite/g++.dg/warn/ref-temp1.C b/gcc/testsuite/g++.dg/warn/ref-temp1.C
new file mode 100644
index 0000000..26f1ca5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/ref-temp1.C
@@ -0,0 +1,11 @@ 
+// PR c++/986
+// { dg-options "-Wall -Wextra" }
+
+struct X { X (int); };
+
+struct Y {
+  Y ();
+  const X &x;			// note the ampersand
+};
+
+Y::Y () : x(1) {}		// { dg-warning "temporary" }