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:
parent
954ad1127e
commit
f9f3b77cf5
4 changed files with 160 additions and 0 deletions
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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...
|
||||
|
|
134
gcc/testsuite/g++.dg/cpp1z/decomp48.C
Normal file
134
gcc/testsuite/g++.dg/cpp1z/decomp48.C
Normal 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 ();
|
||||
}
|
Loading…
Add table
Reference in a new issue