Message ID | 20161115141218.GF3541@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
OK. On Tue, Nov 15, 2016 at 9:12 AM, Jakub Jelinek <jakub@redhat.com> wrote: > Hi! > > On the following testcase we ICE, because the underlying artificial decls > have NULL DECL_NAME (intentional), thus mangling is not able to figure out > what to do. This patch attempts to follow the > http://sourcerytools.com/pipermail/cxx-abi-dev/2016-August/002951.html > proposal (and for error recovery just uses <decomp> in order not to ICE). > > Not really sure about ABI tags though. > I guess one can specify abi tag on the whole decomposition, perhaps > __attribute__((abi_tag ("foobar"))) auto [ a, b ] = A (); > And/or there could be ABI tags on the type of the artifical decl. > What about ABI tags on the types that the decomposition resolved to > (say if std::tuple* is involved)? Shall all ABI tags go at the end > of the whole decomp decl, or shall the individual source names have their > ABI tags attached after them? > What about the std::tuple* case where the standalone vars exist too, > shall e.g. abi_tag attributes be copied from the decomp var to those? > Any other attributes to copy over (e.g. unused comes to mind). > > In any case, bootstrapped/regtested on x86_64-linux and i686-linux, ok for > trunk (and the rest would be resolved incrementally)? > > 2016-11-15 Jakub Jelinek <jakub@redhat.com> > > * 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/decomp12.C: New test. > > --- gcc/cp/decl.c.jj 2016-11-15 09:57:00.000000000 +0100 > +++ gcc/cp/decl.c 2016-11-15 12:16:41.230596777 +0100 > @@ -7301,7 +7301,6 @@ get_tuple_decomp_init (tree decl, unsign > 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, > } > first = DECL_CHAIN (first); > } > + if (DECL_P (decl) && DECL_NAMESPACE_SCOPE_P (decl)) > + SET_DECL_ASSEMBLER_NAME (decl, get_identifier ("<decomp>")); > 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, > 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: > --- gcc/cp/parser.c.jj 2016-11-15 10:37:56.000000000 +0100 > +++ gcc/cp/parser.c 2016-11-15 12:16:26.361784744 +0100 > @@ -12944,6 +12944,7 @@ cp_parser_decomposition_declaration (cp_ > 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_ > 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 ("<decomp>")); > + } > + > return decl; > } > > --- gcc/cp/mangle.c.jj 2016-11-11 14:01:06.000000000 +0100 > +++ gcc/cp/mangle.c 2016-11-15 11:48:58.345751857 +0100 > @@ -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<tree> &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. > --- gcc/cp/cp-tree.h.jj 2016-11-15 09:57:00.000000000 +0100 > +++ gcc/cp/cp-tree.h 2016-11-15 11:49:40.446215562 +0100 > @@ -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<tree> &); > > /* in dump.c */ > extern bool cp_dump_tree (void *, tree); > --- gcc/testsuite/g++.dg/cpp1z/decomp12.C.jj 2016-11-15 12:42:02.319445610 +0100 > +++ gcc/testsuite/g++.dg/cpp1z/decomp12.C 2016-11-15 12:43:09.147608099 +0100 > @@ -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 I> int &get () { return c[I]; } } b; > +namespace std { > + template<typename T> struct tuple_size; > + template<int, typename> struct tuple_element; > +} > +template<> struct std::tuple_size<B> { static constexpr int value = 2; }; > +template<int I> struct std::tuple_element<I,B> { 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 } } > +} > > Jakub
--- gcc/cp/decl.c.jj 2016-11-15 09:57:00.000000000 +0100 +++ gcc/cp/decl.c 2016-11-15 12:16:41.230596777 +0100 @@ -7301,7 +7301,6 @@ get_tuple_decomp_init (tree decl, unsign 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, } first = DECL_CHAIN (first); } + if (DECL_P (decl) && DECL_NAMESPACE_SCOPE_P (decl)) + SET_DECL_ASSEMBLER_NAME (decl, get_identifier ("<decomp>")); 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, 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: --- gcc/cp/parser.c.jj 2016-11-15 10:37:56.000000000 +0100 +++ gcc/cp/parser.c 2016-11-15 12:16:26.361784744 +0100 @@ -12944,6 +12944,7 @@ cp_parser_decomposition_declaration (cp_ 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_ 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 ("<decomp>")); + } + return decl; } --- gcc/cp/mangle.c.jj 2016-11-11 14:01:06.000000000 +0100 +++ gcc/cp/mangle.c 2016-11-15 11:48:58.345751857 +0100 @@ -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<tree> &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. --- gcc/cp/cp-tree.h.jj 2016-11-15 09:57:00.000000000 +0100 +++ gcc/cp/cp-tree.h 2016-11-15 11:49:40.446215562 +0100 @@ -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<tree> &); /* in dump.c */ extern bool cp_dump_tree (void *, tree); --- gcc/testsuite/g++.dg/cpp1z/decomp12.C.jj 2016-11-15 12:42:02.319445610 +0100 +++ gcc/testsuite/g++.dg/cpp1z/decomp12.C 2016-11-15 12:43:09.147608099 +0100 @@ -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 I> int &get () { return c[I]; } } b; +namespace std { + template<typename T> struct tuple_size; + template<int, typename> struct tuple_element; +} +template<> struct std::tuple_size<B> { static constexpr int value = 2; }; +template<int I> struct std::tuple_element<I,B> { 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 } } +}