re PR c++/986 (g++ misses warning for reference on temporary that invokes undefined behaviour)

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
This commit is contained in:
Jason Merrill 2011-11-13 00:09:36 -05:00 committed by Jason Merrill
parent afe5cf2190
commit 2c6f792709
5 changed files with 28 additions and 1 deletions

View 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.

View 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);

View 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);

View 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.

View File

@ -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" }