re PR c++/87582 (Returning a reference to a data member via structured bindings dangles)

PR c++/87582
	* typeck.c (maybe_warn_about_returning_address_of_local): If
	whats_returned is a structured binding identifier and the structured
	binding is a reference, recurse on its initializer.

	* g++.dg/cpp1z/decomp48.C: New test.

From-SVN: r265041
This commit is contained in:
Jakub Jelinek 2018-10-11 15:46:27 +02:00 committed by Jakub Jelinek
parent 954ad1127e
commit f9f3b77cf5
4 changed files with 160 additions and 0 deletions

View file

@ -1,5 +1,10 @@
2018-10-11 Jakub Jelinek <jakub@redhat.com>
PR c++/87582
* typeck.c (maybe_warn_about_returning_address_of_local): If
whats_returned is a structured binding identifier and the structured
binding is a reference, recurse on its initializer.
PR c++/87547
* rtti.c (get_tinfo_decl_dynamic): Use unlowered_expr_type instead
of TREE_TYPE.

View file

@ -9096,6 +9096,22 @@ maybe_warn_about_returning_address_of_local (tree retval)
&& !(TREE_STATIC (whats_returned)
|| TREE_PUBLIC (whats_returned)))
{
if (VAR_P (whats_returned)
&& DECL_DECOMPOSITION_P (whats_returned)
&& DECL_DECOMP_BASE (whats_returned)
&& DECL_HAS_VALUE_EXPR_P (whats_returned))
{
/* When returning address of a structured binding, if the structured
binding is not a reference, continue normally, if it is a
reference, recurse on the initializer of the structured
binding. */
tree base = DECL_DECOMP_BASE (whats_returned);
if (TYPE_REF_P (TREE_TYPE (base)))
{
tree init = DECL_INITIAL (base);
return maybe_warn_about_returning_address_of_local (init);
}
}
bool w = false;
auto_diagnostic_group d;
if (TYPE_REF_P (valtype))

View file

@ -1,3 +1,8 @@
2018-10-11 Jakub Jelinek <jakub@redhat.com>
PR c++/87582
* g++.dg/cpp1z/decomp48.C: New test.
2018-10-11 David Malcolm <dmalcolm@redhat.com>
* g++.dg/diagnostic/macro-arg-count.C: Move to...

View file

@ -0,0 +1,134 @@
// PR c++/87582
// { dg-do run { target c++11 } }
// { dg-options "-Wreturn-local-addr" }
struct S { int s, t; };
S v {1, 2};
int a[3] = {1, 2, 3};
int &
f1 ()
{
auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return s; // { dg-bogus "reference to local variable '.' returned" }
}
int &
f2 ()
{
S v {1, 2};
auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return s; // { dg-warning "reference to local variable 'v' returned" }
}
int &
f3 ()
{
auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return s; // { dg-bogus "reference to local variable '.' returned" }
}
int &
f4 ()
{
int a[3] = {1, 2, 3};
auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return s; // { dg-warning "reference to local variable 'a' returned" }
}
int &
f5 ()
{
auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return s; // { dg-warning "reference to local variable 's' returned" }
}
int &
f6 ()
{
S v {1, 2};
auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return s; // { dg-warning "reference to local variable 's' returned" }
}
int &
f7 ()
{
auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return s; // { dg-warning "reference to local variable 's' returned" }
}
int &
f8 ()
{
int a[3] = {1, 2, 3};
auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return s; // { dg-warning "reference to local variable 's' returned" }
}
int *
f9 ()
{
auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return &s; // { dg-bogus "address of local variable '.' returned" }
}
int *
f10 ()
{
S v {1, 2};
auto& [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return &s; // { dg-warning "address of local variable 'v' returned" }
}
int *
f11 ()
{
auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return &s; // { dg-bogus "address of local variable '.' returned" }
}
int *
f12 ()
{
int a[3] = {1, 2, 3};
auto& [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return &s; // { dg-warning "address of local variable 'a' returned" }
}
int *
f13 ()
{
auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return &s; // { dg-warning "address of local variable 's' returned" }
}
int *
f14 ()
{
S v {1, 2};
auto [s, t] = v; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return &s; // { dg-warning "address of local variable 's' returned" }
}
int *
f15 ()
{
auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return &s; // { dg-warning "address of local variable 's' returned" }
}
int *
f16 ()
{
int a[3] = {1, 2, 3};
auto [s, t, u] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
return &s; // { dg-warning "address of local variable 's' returned" }
}
int
main ()
{
if (&f1 () != &v.s || &f3 () != &a[0] || f9 () != &v.s || f11 () != &a[0])
__builtin_abort ();
}