This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
other/8757: GCC crash when sizeof (long) > sizeof (char *), (splay_tree_compare_fn)strcmp is wrong
- From: mitr at volny dot cz
- To: gcc-gnats at gcc dot gnu dot org
- Date: 29 Nov 2002 16:24:33 -0000
- Subject: other/8757: GCC crash when sizeof (long) > sizeof (char *), (splay_tree_compare_fn)strcmp is wrong
- Reply-to: mitr at volny dot cz
>Number: 8757
>Category: other
>Synopsis: GCC crash when sizeof (long) > sizeof (char *), (splay_tree_compare_fn)strcmp is wrong
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Nov 29 08:26:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: mitr@volny.cz
>Release: gcc-3.2, current (Nov 29 2002) CVS HEAD
>Organization:
>Environment:
>Description:
In several places, (splay_tree_compare_fn)strcmp
is passed to splay_tree_new (). But the compare
function is defined with two "long" arguments,
and when sizeof (long) > sizeof (char *), strcmp
uses the lower and upper half of the first "long"
argument as pointers, and GCC crashes. Attached patch
fixes all occurences in gcc-core-3.2, there may be more
in other frontends.
BTW, AFAIK it is not guaranteed that 'long' is long
enough to hold a pointer.
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="gcc-patch"
Content-Disposition: inline; filename="gcc-patch"
diff -urN gcc-3.2/gcc/c-lex.c sw/gcc-3.2/gcc/c-lex.c
--- gcc-3.2/gcc/c-lex.c 2002-06-28 00:27:09.000000000 +0200
+++ sw/gcc-3.2/gcc/c-lex.c 2002-11-24 22:53:58.000000000 +0100
@@ -108,7 +108,7 @@
struct c_fileinfo *toplevel;
/* Set up filename timing. Must happen before cpp_read_main_file. */
- file_info_tree = splay_tree_new ((splay_tree_compare_fn)strcmp,
+ file_info_tree = splay_tree_new (splay_tree_compare_strings,
0,
(splay_tree_delete_value_fn)free);
toplevel = get_fileinfo ("<top level>");
diff -urN gcc-3.2/gcc/config/alpha/alpha.c sw/gcc-3.2/gcc/config/alpha/alpha.c
--- gcc-3.2/gcc/config/alpha/alpha.c 2002-05-27 07:48:16.000000000 +0200
+++ sw/gcc-3.2/gcc/config/alpha/alpha.c 2002-11-24 22:55:57.000000000 +0100
@@ -8270,7 +8270,7 @@
}
else
{
- alpha_links = splay_tree_new ((splay_tree_compare_fn) strcmp,
+ alpha_links = splay_tree_new (splay_tree_compare_strings,
(splay_tree_delete_key_fn) free,
(splay_tree_delete_key_fn) free);
ggc_add_root (&alpha_links, 1, 1, mark_alpha_links);
diff -urN gcc-3.2/gcc/cppfiles.c sw/gcc-3.2/gcc/cppfiles.c
--- gcc-3.2/gcc/cppfiles.c 2002-01-18 14:40:28.000000000 +0100
+++ sw/gcc-3.2/gcc/cppfiles.c 2002-11-24 22:55:08.000000000 +0100
@@ -150,7 +150,7 @@
cpp_reader *pfile;
{
pfile->all_include_files
- = splay_tree_new ((splay_tree_compare_fn) strcmp,
+ = splay_tree_new (splay_tree_compare_strings,
(splay_tree_delete_key_fn) free,
destroy_node);
}
diff -urN gcc-3.2/include/splay-tree.h sw/gcc-3.2/include/splay-tree.h
--- gcc-3.2/include/splay-tree.h 2002-02-22 18:01:20.000000000 +0100
+++ sw/gcc-3.2/include/splay-tree.h 2002-11-24 22:51:33.000000000 +0100
@@ -146,6 +146,8 @@
splay_tree_key));
extern int splay_tree_compare_pointers PARAMS((splay_tree_key,
splay_tree_key));
+extern int splay_tree_compare_strings PARAMS((splay_tree_key,
+ splay_tree_key));
#ifdef __cplusplus
}
diff -urN gcc-3.2/libiberty/splay-tree.c sw/gcc-3.2/libiberty/splay-tree.c
--- gcc-3.2/libiberty/splay-tree.c 2002-04-06 00:46:55.000000000 +0200
+++ sw/gcc-3.2/libiberty/splay-tree.c 2002-11-24 22:53:49.000000000 +0100
@@ -32,6 +32,10 @@
#include <stdlib.h>
#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
#include <stdio.h>
#include "libiberty.h"
@@ -557,3 +561,13 @@
else
return 0;
}
+
+/* Splay-tree comparison function, treating the keys as pointers. */
+
+int
+splay_tree_compare_strings (k1, k2)
+ splay_tree_key k1;
+ splay_tree_key k2;
+{
+ return strcmp ((const char *)k1, (const char *)k2);
+}