+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>
* cp-tree.h (PUSH_GLOBAL, PUSH_LOCAL, PUSH_USING): Delete.
if (VAR_P (decl)
&& (! TREE_USED (decl) || !DECL_READ_P (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
&& (!CLASS_TYPE_P (type)
|| !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
else
dump_decl (pp, DECL_NAME (t), flags);
}
+ else if (DECL_DECOMPOSITION_P (t))
+ pp_string (pp, M_("<structured bindings>"));
else
pp_string (pp, M_("<anonymous>"));
if (flags & TFF_DECL_SPECIFIERS)
switch (TREE_CODE (exp))
{
case VAR_DECL:
+ if (DECL_VALUE_EXPR (exp))
+ mark_exp_read (DECL_VALUE_EXPR (exp));
+ gcc_fallthrough ();
case PARM_DECL:
DECL_READ_P (exp) = 1;
break;
--- /dev/null
+// { 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.
+}