diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-12-15 22:39:20 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-12-15 22:39:20 +0100 |
commit | 70356f771a65b378362b08d5fdb926fbb88e4aa7 (patch) | |
tree | b5ee5b2b815030b7f06772d64cb74ea7a4a26e7b /gcc/cp/mangle.c | |
parent | a8c55cacaf8fa1e90f9e26c467a78081ae152b50 (diff) | |
download | gcc-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.c | 57 |
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)) { |