summaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-03 12:59:57 +0000
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-03 12:59:57 +0000
commit07cc3a26eae15a67863804d2113f8184f475a823 (patch)
tree5cc89dbc00bbc10b8f999101d2d2ff45011e340d /gcc/java
parentec530640a071c3bf2b99a9bb70b12380f7f23955 (diff)
downloadgcc-07cc3a26eae15a67863804d2113f8184f475a823.tar.gz
2007-10-03 Andrew Haley <aph@redhat.com>
PR java/33639 * class.c (mangled_classname): Detect and replace illegal characters in assembly language symbols. (gen_indirect_dispatch_tables): Call mangled_classname() on the type. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128981 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog8
-rw-r--r--gcc/java/class.c57
2 files changed, 63 insertions, 2 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index bb22fdc36d0..4378b8f26d8 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,11 @@
+2007-10-03 Andrew Haley <aph@redhat.com>
+
+ PR java/33639
+ * class.c (mangled_classname): Detect and replace illegal
+ characters in assembly language symbols.
+ (gen_indirect_dispatch_tables): Call mangled_classname() on
+ the type.
+
2007-09-27 Jakub Jelinek <jakub@redhat.com>
* lang.c (java_print_error_function): Add third argument.
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 82b71b4df18..75ee58aaedd 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -314,10 +314,63 @@ identifier_subst (const tree old_id,
tree
mangled_classname (const char *prefix, tree type)
{
+ tree result;
tree ident = TYPE_NAME (type);
if (TREE_CODE (ident) != IDENTIFIER_NODE)
ident = DECL_NAME (ident);
- return identifier_subst (ident, prefix, '.', '_', "");
+ result = identifier_subst (ident, prefix, '.', '_', "");
+
+ /* Replace any characters that aren't in the set [0-9a-zA-Z_$] with
+ "_0xXX". Class names containing such chracters are uncommon, but
+ they do sometimes occur in class files. Without this check,
+ these names cause assembly errors.
+
+ There is a possibility that a real class name could conflict with
+ the identifier we generate, but it is unlikely and will
+ immediately be detected as an assembler error. At some point we
+ should do something more elaborate (perhaps using the full
+ unicode mangling scheme) in order to prevent such a conflict. */
+ {
+ int i;
+ const int len = IDENTIFIER_LENGTH (result);
+ const char *p = IDENTIFIER_POINTER (result);
+ int illegal_chars = 0;
+
+ /* Make two passes over the identifier. The first pass is merely
+ to count illegal characters; we need to do this in order to
+ allocate a buffer. */
+ for (i = 0; i < len; i++)
+ {
+ char c = p[i];
+ illegal_chars += (! ISALNUM (c) && c != '_' && c != '$');
+ }
+
+ /* And the second pass, which is rarely executed, does the
+ rewriting. */
+ if (illegal_chars != 0)
+ {
+ char *buffer = alloca (illegal_chars * 4 + len + 1);
+ int j;
+
+ for (i = 0, j = 0; i < len; i++)
+ {
+ char c = p[i];
+ if (! ISALNUM (c) && c != '_' && c != '$')
+ {
+ buffer[j++] = '_';
+ sprintf (&buffer[j], "0x%02x", c);
+ j += 4;
+ }
+ else
+ buffer[j++] = c;
+ }
+
+ buffer[j] = 0;
+ result = get_identifier (buffer);
+ }
+ }
+
+ return result;
}
tree
@@ -389,7 +442,7 @@ while (0)
void
gen_indirect_dispatch_tables (tree type)
{
- const char *typename = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+ const char *typename = IDENTIFIER_POINTER (mangled_classname ("", type));
{
tree field = NULL;
char *buf = alloca (strlen (typename) + strlen ("_catch_classes_") + 1);