aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/gogo.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-10-25 22:18:08 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-10-25 22:18:08 +0000
commit34489eb2af3bbb7be101bc838615cf4a4dc6828d (patch)
tree0dbda78980d4553fdaeee92ca666d72a2ab95213 /gcc/go/gofrontend/gogo.cc
parentfc756f9f460d5f0ec73a72128645fdb39fec77a0 (diff)
downloadgcc-34489eb2af3bbb7be101bc838615cf4a4dc6828d.zip
gcc-34489eb2af3bbb7be101bc838615cf4a4dc6828d.tar.gz
gcc-34489eb2af3bbb7be101bc838615cf4a4dc6828d.tar.bz2
compiler: improve name mangling for packpaths
The current implementation of Gogo::pkgpath_for_symbol was written in a way that allowed two distinct package paths to map to the same symbol, which could cause collisions at link- time or compile-time. Switch to a better mangling scheme to insure that we get a unique packagepath symbol for each package. In the new scheme instead of having separate mangling schemes for identifiers and package paths, the main identifier mangler ("go_encode_id") now handles mangling of both packagepath characters and identifier characters. The new mangling scheme is more intrusive: "foo/bar.Baz" is mangled as "foo..z2fbar.Baz" instead of "foo_bar.Baz". To mitigate this, this patch also adds a demangling capability so that function names returned from runtime.CallersFrames are converted back to their original unmangled form. Changing the pkgpath_for_symbol scheme requires updating a number of //go:linkname directives and C "__asm__" directives to match the new scheme, as well as updating the 'gotest' driver (which makes assumptions about the correct mapping from pkgpath symbol to package name). Fixes golang/go#27534. Reviewed-on: https://go-review.googlesource.com/c/135455 From-SVN: r265510
Diffstat (limited to 'gcc/go/gofrontend/gogo.cc')
-rw-r--r--gcc/go/gofrontend/gogo.cc45
1 files changed, 28 insertions, 17 deletions
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 2472245..70af627 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -256,26 +256,11 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int, int pointer_size)
this->globals_->add_function_declaration("delete", NULL, delete_type, loc);
}
-// Convert a pkgpath into a string suitable for a symbol. Note that
-// this transformation is convenient but imperfect. A -fgo-pkgpath
-// option of a/b_c will conflict with a -fgo-pkgpath option of a_b/c,
-// possibly leading to link time errors.
-
std::string
Gogo::pkgpath_for_symbol(const std::string& pkgpath)
{
- std::string s = pkgpath;
- for (size_t i = 0; i < s.length(); ++i)
- {
- char c = s[i];
- if ((c >= 'a' && c <= 'z')
- || (c >= 'A' && c <= 'Z')
- || (c >= '0' && c <= '9'))
- ;
- else
- s[i] = '_';
- }
- return s;
+ go_assert(!pkgpath.empty());
+ return go_encode_id(pkgpath);
}
// Get the package path to use for type reflection data. This should
@@ -319,6 +304,32 @@ Gogo::set_prefix(const std::string& arg)
this->prefix_from_option_ = true;
}
+// Given a name which may or may not have been hidden, append the
+// appropriate version of the name to the result string. Take care
+// to avoid creating a sequence that will be rejected by go_encode_id
+// (avoid ..u, ..U, ..z).
+void
+Gogo::append_possibly_hidden_name(std::string *result, const std::string& name)
+{
+ // FIXME: This adds in pkgpath twice for hidden symbols, which is
+ // less than ideal.
+ if (!Gogo::is_hidden_name(name))
+ (*result) += name;
+ else
+ {
+ std::string n = ".";
+ std::string pkgpath = Gogo::hidden_name_pkgpath(name);
+ char lastR = result->at(result->length() - 1);
+ char firstP = pkgpath.at(0);
+ if (lastR == '.' && (firstP == 'u' || firstP == 'U' || firstP == 'z'))
+ n = "_.";
+ n.append(pkgpath);
+ n.append(1, '.');
+ n.append(Gogo::unpack_hidden_name(name));
+ (*result) += n;
+ }
+}
+
// Munge name for use in an error message.
std::string