diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-05-26 11:17:54 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-05-26 11:17:54 +0200 |
commit | 6fc9f7aa731e895585c47d740509b5cd1591e797 (patch) | |
tree | d6a31e869ca764436905f87f10676d248ddddf01 /gcc/cp/decl.c | |
parent | 28e0e05badfbdf7930bbd6f3051b07dd7ec37ae2 (diff) | |
download | gcc-6fc9f7aa731e895585c47d740509b5cd1591e797.zip gcc-6fc9f7aa731e895585c47d740509b5cd1591e797.tar.gz gcc-6fc9f7aa731e895585c47d740509b5cd1591e797.tar.bz2 |
cp-tree.h (struct lang_decl_decomp): New type.
* cp-tree.h (struct lang_decl_decomp): New type.
(struct lang_decl): Add u.decomp.
(LANG_DECL_DECOMP_CHECK): Define.
(DECL_DECOMPOSITION_P): Note it is set also on the vars
for user identifiers.
(DECL_DECOMP_BASE): Define.
(retrofit_lang_decl): Add extra int = 0 argument.
* lex.c (retrofit_lang_decl): Add SEL argument, if non-zero
use it to influence the selector choices and for selector
0 to non-zero transition copy old content.
(cxx_dup_lang_specific_decl): Handle DECL_DECOMPOSITION_P.
* decl.c (poplevel): For DECL_DECOMPOSITION_P, check
!DECL_DECOMP_BASE instead of !DECL_VALUE_EXPR. Adjust warning
wording if decl is a structured binding.
(cp_finish_decomp): Pass 4 as the new argument to retrofit_lang_decl.
Set DECL_DECOMP_BASE. Ignore DECL_READ_P sets from initialization
of individual variables for tuple structured bindings.
(grokdeclarator): Pass 4 as the new argument to retrofit_lang_decl.
Clear DECL_DECOMP_BASE.
* decl2.c (mark_used): Mark DECL_DECOMP_BASE TREE_USED as well.
* pt.c (tsubst_decomp_names): Assert DECL_DECOMP_BASE matches what
is expected.
* expr.c (mark_exp_read): Recurse on DECL_DECOMP_BASE instead of
DECL_VALUE_EXPR.
* g++.dg/cpp1z/decomp29.C (p): New variable.
(main): Add further tests.
From-SVN: r248483
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3ff0130..59cb315 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -658,7 +658,7 @@ poplevel (int keep, int reverse, int functionbody) && ! DECL_IN_SYSTEM_HEADER (decl) /* For structured bindings, consider only real variables, not subobjects. */ - && (DECL_DECOMPOSITION_P (decl) ? !DECL_VALUE_EXPR (decl) + && (DECL_DECOMPOSITION_P (decl) ? !DECL_DECOMP_BASE (decl) : (DECL_NAME (decl) && !DECL_ARTIFICIAL (decl))) && type != error_mark_node && (!CLASS_TYPE_P (type) @@ -667,16 +667,28 @@ poplevel (int keep, int reverse, int functionbody) TYPE_ATTRIBUTES (TREE_TYPE (decl))))) { if (! TREE_USED (decl)) - warning_at (DECL_SOURCE_LOCATION (decl), - OPT_Wunused_variable, "unused variable %qD", decl); + { + if (!DECL_NAME (decl) && DECL_DECOMPOSITION_P (decl)) + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wunused_variable, + "unused structured binding declaration"); + else + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wunused_variable, "unused variable %qD", decl); + } else if (DECL_CONTEXT (decl) == current_function_decl // For -Wunused-but-set-variable leave references alone. && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE && errorcount == unused_but_set_errorcount) { - warning_at (DECL_SOURCE_LOCATION (decl), - OPT_Wunused_but_set_variable, - "variable %qD set but not used", decl); + if (!DECL_NAME (decl) && DECL_DECOMPOSITION_P (decl)) + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wunused_but_set_variable, "structured " + "binding declaration set but not used"); + else + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wunused_but_set_variable, + "variable %qD set but not used", decl); unused_but_set_errorcount = errorcount; } } @@ -7361,8 +7373,9 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) } if (processing_template_decl) { - retrofit_lang_decl (first); + retrofit_lang_decl (first, 4); SET_DECL_DECOMPOSITION_P (first); + DECL_DECOMP_BASE (first) = decl; } first = DECL_CHAIN (first); } @@ -7375,8 +7388,9 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d)) { v[count - i - 1] = d; - retrofit_lang_decl (d); + retrofit_lang_decl (d, 4); SET_DECL_DECOMPOSITION_P (d); + DECL_DECOMP_BASE (d) = decl; } tree type = TREE_TYPE (decl); @@ -7482,6 +7496,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) eltscnt = tree_to_uhwi (tsize); if (count != eltscnt) goto cnt_mismatch; + int save_read = DECL_READ_P (decl); for (unsigned i = 0; i < count; ++i) { location_t sloc = input_location; @@ -7514,6 +7529,10 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) cp_finish_decl (v[i], init, /*constexpr*/false, /*asm*/NULL_TREE, LOOKUP_NORMAL); } + /* Ignore reads from the underlying decl performed during initialization + of the individual variables. If those will be read, we'll mark + the underlying decl as read at that point. */ + DECL_READ_P (decl) = save_read; } else if (TREE_CODE (type) == UNION_TYPE) { @@ -12295,9 +12314,10 @@ grokdeclarator (const cp_declarator *declarator, { gcc_assert (declarator && declarator->kind == cdk_decomp); DECL_SOURCE_LOCATION (decl) = declarator->id_loc; - retrofit_lang_decl (decl); + retrofit_lang_decl (decl, 4); DECL_ARTIFICIAL (decl) = 1; SET_DECL_DECOMPOSITION_P (decl); + DECL_DECOMP_BASE (decl) = NULL_TREE; } } |