On 02/27/2018 04:44 PM, Jakub Jelinek wrote:
On Mon, Feb 26, 2018 at 09:19:56PM -0700, Martin Sebor wrote:+ /* Put together a list of the black listed attributes that the primary + template is declared with that the specialization is not, in case + it's not apparent from the most recent declaration of the primary. */ + unsigned nattrs = 0; + std::string str; + + for (unsigned i = 0; i != sizeof blacklist / sizeof *blacklist; ++i) + { + for (unsigned j = 0; j != 2; ++j) + { + if (!lookup_attribute (blacklist[i], tmpl_attrs[j])) + continue; + + for (unsigned k = 0; k != 1 + !!spec_attrs[1]; ++k) + { + if (lookup_attribute (blacklist[i], spec_attrs[k])) + break; + + if (str.size ()) + str += ", "; + str += "%<"; + str += blacklist[i]; + str += "%>"; + ++nattrs; + } + } + } + + if (!nattrs) + return; + + if (warning_at (DECL_SOURCE_LOCATION (spec), OPT_Wmissing_attributes, + "explicit specialization %q#D may be missing attributes", + spec)) + { + if (nattrs > 1) + str = G_("missing primary template attributes ") + str; + else + str = G_("missing primary template attribute ") + str; + + inform (DECL_SOURCE_LOCATION (tmpl), str.c_str ());This is broken for multiple reasons: 1) it should be inform_n rather than inform 2) you really can't do what you're doing for translations; G_(...) marks the string for translations, but what actually is translated is not that string, but rather what is passed to inform, i.e. str.c_str (), so it will be likely never translated 3) as others have mentioned, the #include <string> you are doing is wrong 4) I don't see justification to use std::string here What you IMHO should use instead is use pretty_printer str; instead, and the pp_* APIs to add stuff in there, including pp_begin_quote (&str, pp_show_color (global_dc->printer)) and pp_end_quote (&str, pp_show_color (global_dc->printer)) when you want to add what %< or %> expand to, and finally inform_n (DECL_SOURCE_LOCATION (tmpl), nattrs, "missing primary template attribute %s", "missing primary template attributes %s", pp_formatted_text (&str)); That way it should be properly translatable.
Using inform_n() would not be correct here. What's being translated is one of exactly two forms: singular and plural. It doesn't matter how many things the plural form refers to because the number doesn't appear in the message. Let's ask Google to translate the message above to a language with more than two plural forms, such as Czech: there are missing attributes: https://translate.google.com/?tl=cs#auto/cs/there%20are%20missing%20attributes vs there are 5 missing attributes: https://translate.google.com/?tl=cs#auto/cs/there%20are%205%20missing%20attributes Only the first form is correct when the exact number isn't mentioned. There are many places in the C++ front-end where a string enclosed in G_() is assigned to a pointer and later used in a diagnostic call. Is there something different about the usage I introduced that makes it unsuitable for translation? std::string is used in a number of places in GCC. Why does using it here need any special justification? Using the pretty printer as you suggest also sounds complicated to me and so prone to error but I will defer to Jason's opinion to decide if any changes are necessary. Martin PS What I do think would be helpful (and what I'd like to look into adding in stage 1) is a directive to format attribute lists. But I'm not sure the directive will help with cases like this one.
