aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-05-26 11:17:54 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-05-26 11:17:54 +0200
commit6fc9f7aa731e895585c47d740509b5cd1591e797 (patch)
treed6a31e869ca764436905f87f10676d248ddddf01 /gcc/cp/decl.c
parent28e0e05badfbdf7930bbd6f3051b07dd7ec37ae2 (diff)
downloadgcc-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.c38
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;
}
}