Commit 5726acd7 by Jason Merrill Committed by Jason Merrill

-Wunused and C++17 structured bindings

	* decl.c (poplevel): Don't warn about unused structured bindings,
	only real variables.
	* error.c (dump_simple_decl): Handle structured bindings.
	* expr.c (mark_exp_read): Look through DECL_VALUE_EXPR.

From-SVN: r248399
parent c15394ee
2017-05-23 Jason Merrill <jason@redhat.com>
-Wunused and C++17 structured bindings
* decl.c (poplevel): Don't warn about unused structured bindings,
only real variables.
* error.c (dump_simple_decl): Handle structured bindings.
* expr.c (mark_exp_read): Look through DECL_VALUE_EXPR.
2017-05-23 Nathan Sidwell <nathan@acm.org> 2017-05-23 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (PUSH_GLOBAL, PUSH_LOCAL, PUSH_USING): Delete. * cp-tree.h (PUSH_GLOBAL, PUSH_LOCAL, PUSH_USING): Delete.
......
...@@ -656,7 +656,10 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -656,7 +656,10 @@ poplevel (int keep, int reverse, int functionbody)
if (VAR_P (decl) if (VAR_P (decl)
&& (! TREE_USED (decl) || !DECL_READ_P (decl)) && (! TREE_USED (decl) || !DECL_READ_P (decl))
&& ! DECL_IN_SYSTEM_HEADER (decl) && ! DECL_IN_SYSTEM_HEADER (decl)
&& DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl) /* For structured bindings, consider only real variables, not
subobjects. */
&& (DECL_DECOMPOSITION_P (decl) ? !DECL_VALUE_EXPR (decl)
: (DECL_NAME (decl) && !DECL_ARTIFICIAL (decl)))
&& type != error_mark_node && type != error_mark_node
&& (!CLASS_TYPE_P (type) && (!CLASS_TYPE_P (type)
|| !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
......
...@@ -992,6 +992,8 @@ dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags) ...@@ -992,6 +992,8 @@ dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags)
else else
dump_decl (pp, DECL_NAME (t), flags); dump_decl (pp, DECL_NAME (t), flags);
} }
else if (DECL_DECOMPOSITION_P (t))
pp_string (pp, M_("<structured bindings>"));
else else
pp_string (pp, M_("<anonymous>")); pp_string (pp, M_("<anonymous>"));
if (flags & TFF_DECL_SPECIFIERS) if (flags & TFF_DECL_SPECIFIERS)
......
...@@ -133,6 +133,9 @@ mark_exp_read (tree exp) ...@@ -133,6 +133,9 @@ mark_exp_read (tree exp)
switch (TREE_CODE (exp)) switch (TREE_CODE (exp))
{ {
case VAR_DECL: case VAR_DECL:
if (DECL_VALUE_EXPR (exp))
mark_exp_read (DECL_VALUE_EXPR (exp));
gcc_fallthrough ();
case PARM_DECL: case PARM_DECL:
DECL_READ_P (exp) = 1; DECL_READ_P (exp) = 1;
break; break;
......
// { dg-options "-std=c++17 -Wunused" }
#include <tuple>
struct A { int i,j,k; };
A f();
int z;
int main()
{
{
auto [i,j,k] = f(); // { dg-warning "unused" }
}
{
auto [i,j,k] = f();
z = i;
}
{
auto [i,j] = std::tuple{1,2}; // { dg-warning "unused" }
}
// No parallel second test, because in this case i and j are variables rather
// than mere bindings, so there isn't a link between them and using i will
// not prevent a warning about unused j.
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment