This patch to the Go frontend by Than McIntosh fixes a problem when the name of a package starts with a non-ASCII character. The function Lex::is_exported_name (which assumes that its input is a mangled name) was being called on non-mangled (raw utf-8) names in various places. In https://golang.org/issue/27836 this caused an imported package to be registered under the wrong name. To fix the issue, rename 'Lex::is_exported_name' to 'Lex::is_exported_mangled_name', and add a new 'Lex::is_exported_name' that works on utf-8 strings. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 264648) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -944784a93cf89d3a238e5607c993ea5f18f99c12 +f4a224ec481957ca4f14d0e8cc4fe59cc95b3a49 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/import.cc =================================================================== --- gcc/go/gofrontend/import.cc (revision 264648) +++ gcc/go/gofrontend/import.cc (working copy) @@ -983,8 +983,6 @@ Import::read_name() std::string ret = this->read_identifier(); if (ret == "?") ret.clear(); - else if (!Lex::is_exported_name(ret)) - ret = '.' + this->package_->pkgpath() + '.' + ret; return ret; } Index: gcc/go/gofrontend/lex.cc =================================================================== --- gcc/go/gofrontend/lex.cc (revision 264648) +++ gcc/go/gofrontend/lex.cc (working copy) @@ -2764,7 +2764,7 @@ Lex::is_unicode_uppercase(unsigned int c // mangled name which includes only ASCII characters. bool -Lex::is_exported_name(const std::string& name) +Lex::is_exported_mangled_name(const std::string& name) { unsigned char c = name[0]; if (c != '.') @@ -2791,6 +2791,18 @@ Lex::is_exported_name(const std::string& } } +// Return whether the identifier NAME should be exported. NAME is a +// an unmangled utf-8 string and may contain non-ASCII characters. + +bool +Lex::is_exported_name(const std::string& name) +{ + unsigned int uchar; + if (Lex::fetch_char(name.c_str(), &uchar) != 0) + return Lex::is_unicode_letter(uchar) && Lex::is_unicode_uppercase(uchar); + return false; +} + // Return whether the identifier NAME contains an invalid character. // This is based on how we handle invalid characters in // gather_identifier. Index: gcc/go/gofrontend/lex.h =================================================================== --- gcc/go/gofrontend/lex.h (revision 264648) +++ gcc/go/gofrontend/lex.h (working copy) @@ -408,6 +408,11 @@ class Lex // Return whether the identifier NAME should be exported. NAME is a // mangled name which includes only ASCII characters. static bool + is_exported_mangled_name(const std::string& name); + + // Return whether the identifier NAME should be exported. NAME is + // an unmangled utf-8 string and may contain non-ASCII characters. + static bool is_exported_name(const std::string& name); // Return whether the identifier NAME is invalid. When we see an