]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/986 (g++ misses warning for reference on temporary that invokes undefined...
authorJason Merrill <jason@redhat.com>
Sun, 13 Nov 2011 05:09:36 +0000 (00:09 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 13 Nov 2011 05:09:36 +0000 (00:09 -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.

From-SVN: r181334

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/ref-temp1.C [new file with mode: 0644]

index 21f64476d96245cae5de26efaebf08b5b5d90446..a33332cc6a93aa5da7696cdce87ec36f57b23f47 100644 (file)
@@ -1,5 +1,10 @@
 2011-11-12  Jason Merrill  <jason@redhat.com>
 
+       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.
+
        PR c++/51060
        * cp-gimplify.c (cp_gimplify_expr): Leave clobbers alone.
 
index e81950ce537bdd68d6414f2be9efdb3733a9a61e..ab0654273a3e2abf3b089ff2c3b2a16b5bc518d3 100644 (file)
@@ -8607,6 +8607,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);
index 77fe42e4dc64e28bc40effb70503b2b221ada12f..5c20e32a79f0476ffacd58f80eb6c4cc0697bdc3 100644 (file)
@@ -599,7 +599,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);
index 0582e49e0e5cbfae62cf871dbc59a49aa5737fb6..4c4460310efc7ac7f87c6c7f97c670e8fe598101 100644 (file)
@@ -1,5 +1,8 @@
 2011-11-12  Jason Merrill  <jason@redhat.com>
 
+       PR c++/986
+       * g++.dg/warn/ref-temp1.C: New.
+
        PR c++/51060
        * g++.dg/opt/stack2.C: New.
 
diff --git a/gcc/testsuite/g++.dg/warn/ref-temp1.C b/gcc/testsuite/g++.dg/warn/ref-temp1.C
new file mode 100644 (file)
index 0000000..26f1ca5
--- /dev/null
@@ -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" }