From: Jakub Jelinek Date: Tue, 15 Nov 2016 17:05:23 +0000 (+0100) Subject: decl.c (cp_finish_decomp): For DECL_NAMESPACE_SCOPE_P decl, set DECL_ASSEMBLER_NAME. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a0f5b987521323a66d307fbccd57e0020509dd97;p=gcc.git decl.c (cp_finish_decomp): For DECL_NAMESPACE_SCOPE_P decl, set DECL_ASSEMBLER_NAME. * decl.c (cp_finish_decomp): For DECL_NAMESPACE_SCOPE_P decl, set DECL_ASSEMBLER_NAME. * parser.c (cp_parser_decomposition_declaration): Likewise if returning error_mark_node. * mangle.c (mangle_decomp): New function. * cp-tree.h (mangle_decomp): New declaration. * g++.dg/cpp1z/decomp13.C: New test. From-SVN: r242434 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8b5fc8117cf..0bcb730cb1c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2016-11-15 Jakub Jelinek + + * decl.c (cp_finish_decomp): For DECL_NAMESPACE_SCOPE_P decl, + set DECL_ASSEMBLER_NAME. + * parser.c (cp_parser_decomposition_declaration): Likewise + if returning error_mark_node. + * mangle.c (mangle_decomp): New function. + * cp-tree.h (mangle_decomp): New declaration. + 2016-11-15 Jason Merrill PR c++/78358 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 634efc9ba5c..0dcb8971edd 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6868,6 +6868,7 @@ extern bool decl_tls_wrapper_p (tree); extern tree mangle_ref_init_variable (tree); extern char * get_mangled_vtable_map_var_name (tree); extern bool mangle_return_type_p (tree); +extern tree mangle_decomp (tree, vec &); /* in dump.c */ extern bool cp_dump_tree (void *, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2af95a7568d..23ba087a86f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7301,7 +7301,6 @@ get_tuple_decomp_init (tree decl, unsigned i) void cp_finish_decomp (tree decl, tree first, unsigned int count) { - location_t loc = DECL_SOURCE_LOCATION (decl); if (error_operand_p (decl)) { error_out: @@ -7315,9 +7314,12 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) } first = DECL_CHAIN (first); } + if (DECL_P (decl) && DECL_NAMESPACE_SCOPE_P (decl)) + SET_DECL_ASSEMBLER_NAME (decl, get_identifier ("")); return; } + location_t loc = DECL_SOURCE_LOCATION (decl); if (type_dependent_expression_p (decl) /* This happens for range for when not in templates. Still add the DECL_VALUE_EXPRs for later processing. */ @@ -7530,6 +7532,8 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) i++; } } + if (DECL_NAMESPACE_SCOPE_P (decl)) + SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v)); } /* Returns a declaration for a VAR_DECL as if: diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index be7b72b532e..a4a2444ebfb 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3995,6 +3995,53 @@ mangle_vtt_for_type (const tree type) return mangle_special_for_type (type, "TT"); } +/* Returns an identifier for the mangled name of the decomposition + artificial variable DECL. DECLS is the vector of the VAR_DECLs + for the identifier-list. */ + +tree +mangle_decomp (const tree decl, vec &decls) +{ + gcc_assert (!type_dependent_expression_p (decl)); + + location_t saved_loc = input_location; + input_location = DECL_SOURCE_LOCATION (decl); + + start_mangling (decl); + write_string ("_Z"); + + tree context = decl_mangling_context (decl); + gcc_assert (context != NULL_TREE); + + bool nested = false; + if (DECL_NAMESPACE_STD_P (context)) + write_string ("St"); + else if (context != global_namespace) + { + nested = true; + write_char ('N'); + write_prefix (decl_mangling_context (decl)); + } + + write_string ("DC"); + unsigned int i; + tree d; + FOR_EACH_VEC_ELT (decls, i, d) + write_unqualified_name (d); + write_char ('E'); + + if (nested) + write_char ('E'); + + tree id = finish_mangling_get_identifier (); + if (DEBUG_MANGLE) + fprintf (stderr, "mangle_decomp = '%s'\n\n", + IDENTIFIER_POINTER (id)); + + input_location = saved_loc; + return id; +} + /* Return an identifier for a construction vtable group. TYPE is the most derived class in the hierarchy; BINFO is the base subobject for which this construction vtable group will be used. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9360ab0cbd6..9a5039f9955 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12944,6 +12944,7 @@ cp_parser_decomposition_declaration (cp_parser *parser, tree decl = start_decl (declarator, decl_specifiers, SD_INITIALIZED, NULL_TREE, decl_specifiers->attributes, &pushed_scope); + tree orig_decl = decl; unsigned int i; cp_expr e; @@ -13020,6 +13021,12 @@ cp_parser_decomposition_declaration (cp_parser *parser, if (pushed_scope) pop_scope (pushed_scope); + if (decl == error_mark_node && DECL_P (orig_decl)) + { + if (DECL_NAMESPACE_SCOPE_P (orig_decl)) + SET_DECL_ASSEMBLER_NAME (orig_decl, get_identifier ("")); + } + return decl; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3600f9461ce..a08009b6172 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2016-11-15 Jakub Jelinek + * g++.dg/cpp1z/decomp13.C: New test. + * g++.dg/cpp1y/auto-fn33.C (main): Turn // error: ... into dg-bogus. PR c++/71988 diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp13.C b/gcc/testsuite/g++.dg/cpp1z/decomp13.C new file mode 100644 index 00000000000..9ebddc6e608 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/decomp13.C @@ -0,0 +1,52 @@ +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { int i; long j; int k : 2; char l; } a; +int c[2]; +struct B { template int &get () { return c[I]; } } b; +namespace std { + template struct tuple_size; + template struct tuple_element; +} +template<> struct std::tuple_size { static constexpr int value = 2; }; +template struct std::tuple_element { typedef int type; }; + +auto [ aa, bb, cc, dd ] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +// { dg-final { scan-assembler "_ZDC2aa2bb2cc2ddE" } } +const auto & [ e, f, g, h ] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +// { dg-final { scan-assembler "_ZDC1e1f1g1hE" } } +auto [ ee, ff ] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +// { dg-final { scan-assembler "_ZDC2ee2ffE" } } +auto & [ gg, hh ] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +// { dg-final { scan-assembler "_ZDC2gg2hhE" } } +namespace N +{ + namespace M + { + auto [ i, j, k, l ] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + // { dg-final { scan-assembler "_ZN1N1MDC1i1j1k1lEE" } } + auto & [ m, n, o, ppp ] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + // { dg-final { scan-assembler "_ZN1N1MDC1m1n1o3pppEE" } } + auto [ ii, jj ] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + // { dg-final { scan-assembler "_ZN1N1MDC2ii2jjEE" } } + // { dg-final { scan-assembler "_ZN1N1M2iiE" } } + // { dg-final { scan-assembler "_ZN1N1M2jjE" } } + auto & [ mm, nn ] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + // { dg-final { scan-assembler "_ZN1N1MDC2mm2nnEE" } } + // { dg-final { scan-assembler "_ZN1N1M2mmE" } } + // { dg-final { scan-assembler "_ZN1N1M2nnE" } } + } +} +namespace std +{ + auto [ i2, j2, k2, l2 ] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + // { dg-final { scan-assembler "_ZStDC2i22j22k22l2E" } } + auto [ vv, ww ] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } + // { dg-final { scan-assembler "_ZStDC2vv2wwE" } } + // { dg-final { scan-assembler "_ZSt2vv" } } + // { dg-final { scan-assembler "_ZSt2ww" } } +} +namespace +{ + auto [ v, w, x, y ] = a; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +}