compiler: fix parsing issue with non-ASCII first package char

Fix a bug in the parser code that decides whether a given name should
    be considered exported or not. 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. For the bug in
    question 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.
    
    Fixes golang/go#27836.
    
    Reviewed-on: https://go-review.googlesource.com/137736

From-SVN: r264690
This commit is contained in:
Ian Lance Taylor 2018-09-28 13:50:44 +00:00
parent dc16b00717
commit 20a73a1947
4 changed files with 19 additions and 4 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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& name)
}
}
// 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.

View File

@ -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