aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/mangle.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-12-15 22:39:20 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-12-15 22:39:20 +0100
commit70356f771a65b378362b08d5fdb926fbb88e4aa7 (patch)
treeb5ee5b2b815030b7f06772d64cb74ea7a4a26e7b /gcc/cp/mangle.c
parenta8c55cacaf8fa1e90f9e26c467a78081ae152b50 (diff)
downloadgcc-70356f771a65b378362b08d5fdb926fbb88e4aa7.zip
gcc-70356f771a65b378362b08d5fdb926fbb88e4aa7.tar.gz
gcc-70356f771a65b378362b08d5fdb926fbb88e4aa7.tar.bz2
re PR c++/81197 (ICE with structured binding and lifetime-extended temporaries)
PR c++/81197 * cp-tree.h (cp_maybe_mangle_decomp): Declare. * decl.c (cp_maybe_mangle_decomp): New function. (cp_finish_decomp): Don't SET_DECL_ASSEMBLER_NAME here. * parser.c (cp_convert_range_for, cp_parser_decomposition_declaration): Call cp_maybe_mangle_decomp. * pt.c (tsubst_expr): Likewise. * mangle.c (find_decomp_unqualified_name): New function. (write_unqualified_name): Handle DECL_DECOMPOSITION_P where DECL_ASSEMBLER_NAME is already set. * g++.dg/cpp1z/decomp34.C: New test. From-SVN: r255705
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r--gcc/cp/mangle.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 6d4e591..ffd2b4c 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1247,6 +1247,51 @@ write_template_prefix (const tree node)
add_substitution (substitution);
}
+/* As the list of identifiers for the structured binding declaration
+ DECL is likely gone, try to recover the DC <source-name>+ E portion
+ from its mangled name. Return pointer to the DC and set len to
+ the length up to and including the terminating E. On failure
+ return NULL. */
+
+static const char *
+find_decomp_unqualified_name (tree decl, size_t *len)
+{
+ const char *p = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ const char *end = p + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl));
+ bool nested = false;
+ if (strncmp (p, "_Z", 2))
+ return NULL;
+ p += 2;
+ if (!strncmp (p, "St", 2))
+ p += 2;
+ else if (*p == 'N')
+ {
+ nested = true;
+ ++p;
+ while (ISDIGIT (p[0]))
+ {
+ char *e;
+ long num = strtol (p, &e, 10);
+ if (num >= 1 && num < end - e)
+ p = e + num;
+ else
+ break;
+ }
+ }
+ if (strncmp (p, "DC", 2))
+ return NULL;
+ if (nested)
+ {
+ if (end[-1] != 'E')
+ return NULL;
+ --end;
+ }
+ if (end[-1] != 'E')
+ return NULL;
+ *len = end - p;
+ return p;
+}
+
/* We don't need to handle thunks, vtables, or VTTs here. Those are
mangled through special entry points.
@@ -1291,7 +1336,17 @@ write_unqualified_name (tree decl)
{
found = true;
gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
- write_source_name (DECL_ASSEMBLER_NAME (decl));
+ const char *decomp_str = NULL;
+ size_t decomp_len = 0;
+ if (VAR_P (decl)
+ && DECL_DECOMPOSITION_P (decl)
+ && DECL_NAME (decl) == NULL_TREE
+ && DECL_NAMESPACE_SCOPE_P (decl))
+ decomp_str = find_decomp_unqualified_name (decl, &decomp_len);
+ if (decomp_str)
+ write_chars (decomp_str, decomp_len);
+ else
+ write_source_name (DECL_ASSEMBLER_NAME (decl));
}
else if (DECL_DECLARES_FUNCTION_P (decl))
{