From 5726acd7d7f84a27e17719f185e3e4c5e67aeb2d Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 23 May 2017 21:46:16 -0400 Subject: [PATCH] -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 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/decl.c | 5 ++++- gcc/cp/error.c | 2 ++ gcc/cp/expr.c | 3 +++ gcc/testsuite/g++.dg/cpp1z/decomp29.C | 26 ++++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp29.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4a72b655318..785dfc56fc0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2017-05-23 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. + 2017-05-23 Nathan Sidwell * cp-tree.h (PUSH_GLOBAL, PUSH_LOCAL, PUSH_USING): Delete. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5877f37998e..afd47bbc509 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -656,7 +656,10 @@ poplevel (int keep, int reverse, int functionbody) 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) diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 1ae25bb486c..624a0e95d7f 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -992,6 +992,8 @@ dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags) else dump_decl (pp, DECL_NAME (t), flags); } + else if (DECL_DECOMPOSITION_P (t)) + pp_string (pp, M_("")); else pp_string (pp, M_("")); if (flags & TFF_DECL_SPECIFIERS) diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 77af54e82a1..75e99e598af 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -133,6 +133,9 @@ mark_exp_read (tree exp) 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; diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp29.C b/gcc/testsuite/g++.dg/cpp1z/decomp29.C new file mode 100644 index 00000000000..daf07a038d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/decomp29.C @@ -0,0 +1,26 @@ +// { dg-options "-std=c++17 -Wunused" } + +#include + +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. +} -- 2.30.2