re PR go/65755 (incorrect reflection of struct fields with gccgo)
PR go/65755 compiler, runtime, reflect: Use reflection string for type comparisons. Change the runtime and reflect libraries to always use only the type reflection string to determine whether two types are equal. It previously used the PkgPath and Name values for a type name, but that required a PkgPath that did not match the gc compiler. Change the compiler to use the same PkgPath value as the gc compiler in all cases. Change the compiler to put the receiver type in the reflection string for a type defined inside a method. From-SVN: r222194
This commit is contained in:
parent
fdce7c12f3
commit
90e00f872d
@ -2253,22 +2253,7 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type,
|
|||||||
const std::string& pkgpath(package == NULL
|
const std::string& pkgpath(package == NULL
|
||||||
? gogo->pkgpath()
|
? gogo->pkgpath()
|
||||||
: package->pkgpath());
|
: package->pkgpath());
|
||||||
n.assign(pkgpath);
|
s = Expression::make_string(pkgpath, bloc);
|
||||||
unsigned int index;
|
|
||||||
const Named_object* in_function = name->in_function(&index);
|
|
||||||
if (in_function != NULL)
|
|
||||||
{
|
|
||||||
n.append(1, '.');
|
|
||||||
n.append(Gogo::unpack_hidden_name(in_function->name()));
|
|
||||||
if (index > 0)
|
|
||||||
{
|
|
||||||
char buf[30];
|
|
||||||
snprintf(buf, sizeof buf, "%u", index);
|
|
||||||
n.append(1, '.');
|
|
||||||
n.append(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s = Expression::make_string(n, bloc);
|
|
||||||
vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
|
vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9102,22 +9087,17 @@ Named_type::do_reflection(Gogo* gogo, std::string* ret) const
|
|||||||
}
|
}
|
||||||
if (!this->is_builtin())
|
if (!this->is_builtin())
|
||||||
{
|
{
|
||||||
// We handle -fgo-prefix and -fgo-pkgpath differently here for
|
// When -fgo-pkgpath or -fgo-prefix is specified, we use it to
|
||||||
// compatibility with how the compiler worked before
|
// make a unique reflection string, so that the type
|
||||||
// -fgo-pkgpath was introduced. When -fgo-pkgpath is specified,
|
// canonicalization in the reflect package will work. In order
|
||||||
// we use it to make a unique reflection string, so that the
|
// to be compatible with the gc compiler, we put tabs into the
|
||||||
// type canonicalization in the reflect package will work. In
|
// package path, so that the reflect methods can discard it.
|
||||||
// order to be compatible with the gc compiler, we put tabs into
|
|
||||||
// the package path, so that the reflect methods can discard it.
|
|
||||||
const Package* package = this->named_object_->package();
|
const Package* package = this->named_object_->package();
|
||||||
if (gogo->pkgpath_from_option())
|
ret->push_back('\t');
|
||||||
{
|
ret->append(package != NULL
|
||||||
ret->push_back('\t');
|
? package->pkgpath_symbol()
|
||||||
ret->append(package != NULL
|
: gogo->pkgpath_symbol());
|
||||||
? package->pkgpath_symbol()
|
ret->push_back('\t');
|
||||||
: gogo->pkgpath_symbol());
|
|
||||||
ret->push_back('\t');
|
|
||||||
}
|
|
||||||
ret->append(package != NULL
|
ret->append(package != NULL
|
||||||
? package->package_name()
|
? package->package_name()
|
||||||
: gogo->package_name());
|
: gogo->package_name());
|
||||||
@ -9126,6 +9106,14 @@ Named_type::do_reflection(Gogo* gogo, std::string* ret) const
|
|||||||
if (this->in_function_ != NULL)
|
if (this->in_function_ != NULL)
|
||||||
{
|
{
|
||||||
ret->push_back('\t');
|
ret->push_back('\t');
|
||||||
|
const Typed_identifier* rcvr =
|
||||||
|
this->in_function_->func_value()->type()->receiver();
|
||||||
|
if (rcvr != NULL)
|
||||||
|
{
|
||||||
|
Named_type* rcvr_type = rcvr->type()->deref()->named_type();
|
||||||
|
ret->append(Gogo::unpack_hidden_name(rcvr_type->name()));
|
||||||
|
ret->push_back('.');
|
||||||
|
}
|
||||||
ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
|
ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
|
||||||
ret->push_back('$');
|
ret->push_back('$');
|
||||||
if (this->in_function_index_ > 0)
|
if (this->in_function_index_ > 0)
|
||||||
|
@ -1940,13 +1940,7 @@ func canonicalize(t Type) Type {
|
|||||||
if t == nil {
|
if t == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
u := t.uncommon()
|
s := t.rawString()
|
||||||
var s string
|
|
||||||
if u == nil || u.PkgPath() == "" {
|
|
||||||
s = t.rawString()
|
|
||||||
} else {
|
|
||||||
s = u.PkgPath() + "." + u.Name()
|
|
||||||
}
|
|
||||||
canonicalTypeLock.RLock()
|
canonicalTypeLock.RLock()
|
||||||
if r, ok := canonicalType[s]; ok {
|
if r, ok := canonicalType[s]; ok {
|
||||||
canonicalTypeLock.RUnlock()
|
canonicalTypeLock.RUnlock()
|
||||||
|
@ -24,16 +24,5 @@ __go_type_descriptors_equal (const struct __go_type_descriptor *td1,
|
|||||||
return 0;
|
return 0;
|
||||||
if (td1->__code != td2->__code || td1->__hash != td2->__hash)
|
if (td1->__code != td2->__code || td1->__hash != td2->__hash)
|
||||||
return 0;
|
return 0;
|
||||||
if (td1->__uncommon != NULL && td1->__uncommon->__name != NULL)
|
|
||||||
{
|
|
||||||
if (td2->__uncommon == NULL || td2->__uncommon->__name == NULL)
|
|
||||||
return 0;
|
|
||||||
return (__go_ptr_strings_equal (td1->__uncommon->__name,
|
|
||||||
td2->__uncommon->__name)
|
|
||||||
&& __go_ptr_strings_equal (td1->__uncommon->__pkg_path,
|
|
||||||
td2->__uncommon->__pkg_path));
|
|
||||||
}
|
|
||||||
if (td2->__uncommon != NULL && td2->__uncommon->__name != NULL)
|
|
||||||
return 0;
|
|
||||||
return __go_ptr_strings_equal (td1->__reflection, td2->__reflection);
|
return __go_ptr_strings_equal (td1->__reflection, td2->__reflection);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user