Hello All My understanding of the description of the tag GTY option in http://gcc.gnu.org/onlinedocs/gccint/GTY-Options.html#GTY-Options is that a given discriminated union case can have several tags. so in MELT I did code (file gcc/melt-runtime.h near line 1108 of rev 161710)
[The // c++ like comments are comments in this mail, not in MELT sources] /**** our union for everything ***/ /* never use an array of melt_un, only array of pointers melt_ptr_t */ typedef union GTY ((desc ("%0.u_discr->object_magic"))) melt_un { meltobject_ptr_t GTY ((skip)) u_discr; struct meltforward_st GTY ((skip)) u_forward; struct meltobject_st GTY ((tag ("OBMAG_OBJECT"))) u_object; //// some cases skipped struct meltpair_st GTY ((tag ("OBMAG_PAIR"))) u_pair; struct meltspecial_st GTY ((tag ("OBMAG_SPEC_FILE"), tag ("OBMAG_SPEC_RAWFILE"), tag ("OBMAG_SPEC_MPFR"), tag ("OBMAG_SPECPPL_COEFFICIENT"), tag ("OBMAG_SPECPPL_LINEAR_EXPRESSION"), tag ("OBMAG_SPECPPL_CONSTRAINT"), tag ("OBMAG_SPECPPL_CONSTRAINT_SYSTEM"), tag ("OBMAG_SPECPPL_GENERATOR"), tag ("OBMAG_SPECPPL_GENERATOR_SYSTEM"), tag ("OBMAG_SPECPPL_POLYHEDRON")) ) u_special; struct meltstring_st GTY ((tag ("OBMAG_STRING"))) u_string; /// some other cases skipped } melt_un_t; Notice that I did use several tags for the u_special case. I thought is is permissible, and I was expecting that the gengtype generated marking routine marks the u_special union component for all the OBMAG_SPEC* cases listed above. However, this is not the case. The generated marking routine (in gcc/gtype-desc.c in the build tree) contains void gt_ggc_mx_melt_un (void *x_p) { union melt_un * const x = (union melt_un *)x_p; if (ggc_test_and_set_mark (x)) { switch ((*x).u_discr->object_magic) { case OBMAG_OBJECT: gt_ggc_m_13meltobject_st ((*x).u_object.obj_class); { size_t i0; size_t l0 = (size_t)(((*x).u_object).obj_len); for (i0 = 0; i0 != l0; i0++) { gt_ggc_m_7melt_un ((*x).u_object.obj_vartab[i0]); } } break; // some cases skipped case OBMAG_PAIR: gt_ggc_m_13meltobject_st ((*x).u_pair.discr); gt_ggc_m_7melt_un ((*x).u_pair.hd); gt_ggc_m_11meltpair_st ((*x).u_pair.tl); break; case OBMAG_SPEC_FILE: gt_ggc_m_13meltobject_st ((*x).u_special.discr); break; // **** cases OBMAG_SPEC_RAWFILE and others are missing! case OBMAG_STRING: gt_ggc_m_13meltobject_st ((*x).u_string.discr); break; /// some other cases skipped default: break; } } } Notice that all the OBMAG_SPEC_RAWFILE, OBMAG_SPEC_MPFR etc... cases are absent in the generated marking routine gt_ggc_mx_melt_un above. I was painfully surprised to find this (this is the hardest bug in MELT I've got so far). /* never use an array of melt_un, only array of pointers melt_ptr_t */ typedef union GTY ((desc ("%0.u_discr->object_magic"))) melt_un { meltobject_ptr_t GTY ((skip)) u_discr; struct meltforward_st GTY ((skip)) u_forward; struct meltobject_st GTY ((tag ("OBMAG_OBJECT"))) u_object; //// some cases skipped struct meltbox_st GTY ((tag ("OBMAG_BOX"))) u_box; struct meltpair_st GTY ((tag ("OBMAG_PAIR"))) u_pair; /* The struct meltspecial_st share several GTY tag-s, but gengtype need to have one case per tag! */ struct meltspecial_st GTY ((tag ("OBMAG_SPEC_FILE"))) u_special_file; struct meltspecial_st GTY ((tag ("OBMAG_SPEC_RAWFILE"))) u_special_rawfile; struct meltspecial_st GTY ((tag ("OBMAG_SPEC_MPFR"))) u_special_mpfr; struct meltspecial_st GTY ((tag ("OBMAG_SPECPPL_COEFFICIENT"))) u_special_ppl_coefficient; struct meltspecial_st GTY ((tag ("OBMAG_SPECPPL_LINEAR_EXPRESSION"))) u_special_ppl_linear_expression; struct meltspecial_st GTY ((tag ("OBMAG_SPECPPL_CONSTRAINT"))) u_special_ppl_constraint; struct meltspecial_st GTY ((tag ("OBMAG_SPECPPL_CONSTRAINT_SYSTEM"))) u_special_ppl_constraint_system; struct meltspecial_st GTY ((tag ("OBMAG_SPECPPL_GENERATOR"))) u_special_ppl_generator; struct meltspecial_st GTY ((tag ("OBMAG_SPECPPL_GENERATOR_SYSTEM"))) u_special_ppl_generator_system; struct meltspecial_st GTY ((tag ("OBMAG_SPECPPL_POLYHEDRON"))) u_special_ppl_polyhedron; /* for simplicity and compatibility with previous code, we can just write u_special */ struct meltspecial_st GTY ((skip)) u_special; struct meltstring_st GTY ((tag ("OBMAG_STRING"))) u_string; /// some other cases skipped } melt_un_t; By making this correction, the gengtype generated marking routine has indeed all the cases I was expecting. Do you think it is only my misunderstanding (as everyone noticed, my English language is poor since it is not my native language), or a bug of the gengtype documentation, or a bug in gengtype code? Can several GTY tags appear for the same union component as I thought previously? Cheers. -- Basile STARYNKEVITCH http://starynkevitch.net/Basile/ email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359 8, rue de la Faiencerie, 92340 Bourg La Reine, France *** opinions {are only mines, sont seulement les miennes} ***