This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix bug 136 - output language constants
- To: gcc-patches at gcc dot gnu dot org
- Subject: Fix bug 136 - output language constants
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Thu, 22 Jun 2000 10:44:09 +0100
- Organization: Codesourcery LLC
Hi,
I've installed the attached patch to varasm's constant machinery. It
was falling over when trying to cache a language dependant constant.
In the test case's case a C++ pointer to member function. This patch
uses the lang_expand_constant hook to DTRT in compare_constant_1 and
record_constant_1. That exposed a signedness problem with the recording
mechanism, which I fixed by adjusting things to use an unsigned char
buffer -- tree codes can be >127.
approved by Mark, built and tested on i686-pc-linux-gnu
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-06-22 Nathan Sidwell <nathan@codesourcery.com>
* varasm.c (constant_descriptor): Make contents unsigned char.
(mark_const_hash_entry): Adjust.
(const_hash): Just hash the code of unknown nodes.
(compare_constant_1): Adjust for unsigned char.
Use language specific expander on unknown nodes.
(record_constant_1): Likewise.
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.124
diff -c -3 -p -r1.124 varasm.c
*** varasm.c 2000/06/09 21:47:39 1.124
--- varasm.c 2000/06/22 07:21:23
*************** static void decode_addr_const PARAMS ((
*** 156,162 ****
static int const_hash PARAMS ((tree));
static int compare_constant PARAMS ((tree,
struct constant_descriptor *));
! static char *compare_constant_1 PARAMS ((tree, char *));
static struct constant_descriptor *record_constant PARAMS ((tree));
static void record_constant_1 PARAMS ((tree));
static tree copy_constant PARAMS ((tree));
--- 156,162 ----
static int const_hash PARAMS ((tree));
static int compare_constant PARAMS ((tree,
struct constant_descriptor *));
! static const unsigned char *compare_constant_1 PARAMS ((tree, const unsigned char *));
static struct constant_descriptor *record_constant PARAMS ((tree));
static void record_constant_1 PARAMS ((tree));
static tree copy_constant PARAMS ((tree));
*************** struct constant_descriptor
*** 2329,2335 ****
struct constant_descriptor *next;
char *label;
rtx rtl;
! char contents[1];
};
#define HASHBITS 30
--- 2329,2335 ----
struct constant_descriptor *next;
char *label;
rtx rtl;
! unsigned char contents[1];
};
#define HASHBITS 30
*************** mark_const_hash_entry (ptr)
*** 2346,2352 ****
while (desc)
{
! ggc_mark_string (desc->label);
ggc_mark_rtx (desc->rtl);
desc = desc->next;
}
--- 2346,2352 ----
while (desc)
{
! ggc_mark_string ((const char *)desc->label);
ggc_mark_rtx (desc->rtl);
desc = desc->next;
}
*************** const_hash (exp)
*** 2457,2463 ****
return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2;
default:
! abort ();
}
/* Compute hashing function */
--- 2457,2464 ----
return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2;
default:
! /* A language specific constant. Just hash the code. */
! return code % MAX_HASH_TABLE;
}
/* Compute hashing function */
*************** compare_constant (exp, desc)
*** 2490,2505 ****
against a subdescriptor, and if it succeeds it returns the
address of the subdescriptor for the next operand. */
! static char *
compare_constant_1 (exp, p)
tree exp;
! char *p;
{
! register const char *strp;
register int len;
register enum tree_code code = TREE_CODE (exp);
! if (code != (enum tree_code) *p++)
return 0;
/* Either set STRP, P and LEN to pointers and length to compare and exit the
--- 2491,2506 ----
against a subdescriptor, and if it succeeds it returns the
address of the subdescriptor for the next operand. */
! static const unsigned char *
compare_constant_1 (exp, p)
tree exp;
! const unsigned char *p;
{
! register const unsigned char *strp;
register int len;
register enum tree_code code = TREE_CODE (exp);
! if (code != (enum tree_code) *p++)
return 0;
/* Either set STRP, P and LEN to pointers and length to compare and exit the
*************** compare_constant_1 (exp, p)
*** 2512,2518 ****
if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
return 0;
! strp = (char *) &TREE_INT_CST_LOW (exp);
len = 2 * sizeof TREE_INT_CST_LOW (exp);
break;
--- 2513,2519 ----
if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
return 0;
! strp = (unsigned char *) &TREE_INT_CST_LOW (exp);
len = 2 * sizeof TREE_INT_CST_LOW (exp);
break;
*************** compare_constant_1 (exp, p)
*** 2521,2527 ****
if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
return 0;
! strp = (char *) &TREE_REAL_CST (exp);
len = sizeof TREE_REAL_CST (exp);
break;
--- 2522,2528 ----
if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
return 0;
! strp = (unsigned char *) &TREE_REAL_CST (exp);
len = sizeof TREE_REAL_CST (exp);
break;
*************** compare_constant_1 (exp, p)
*** 2532,2538 ****
if ((enum machine_mode) *p++ != TYPE_MODE (TREE_TYPE (exp)))
return 0;
! strp = TREE_STRING_POINTER (exp);
len = TREE_STRING_LENGTH (exp);
if (bcmp ((char *) &TREE_STRING_LENGTH (exp), p,
sizeof TREE_STRING_LENGTH (exp)))
--- 2533,2539 ----
if ((enum machine_mode) *p++ != TYPE_MODE (TREE_TYPE (exp)))
return 0;
! strp = (unsigned char *)TREE_STRING_POINTER (exp);
len = TREE_STRING_LENGTH (exp);
if (bcmp ((char *) &TREE_STRING_LENGTH (exp), p,
sizeof TREE_STRING_LENGTH (exp)))
*************** compare_constant_1 (exp, p)
*** 2555,2561 ****
unsigned char *tmp = (unsigned char *) alloca (len);
get_set_constructor_bytes (exp, tmp, len);
! strp = (char *) tmp;
if (bcmp ((char *) &xlen, p, sizeof xlen))
return 0;
--- 2556,2562 ----
unsigned char *tmp = (unsigned char *) alloca (len);
get_set_constructor_bytes (exp, tmp, len);
! strp = (unsigned char *) tmp;
if (bcmp ((char *) &xlen, p, sizeof xlen))
return 0;
*************** compare_constant_1 (exp, p)
*** 2667,2673 ****
struct addr_const value;
decode_addr_const (exp, &value);
! strp = (char *) &value.offset;
len = sizeof value.offset;
/* Compare the offset. */
while (--len >= 0)
--- 2668,2674 ----
struct addr_const value;
decode_addr_const (exp, &value);
! strp = (unsigned char *) &value.offset;
len = sizeof value.offset;
/* Compare the offset. */
while (--len >= 0)
*************** compare_constant_1 (exp, p)
*** 2675,2682 ****
return 0;
/* Compare symbol name. */
! strp = XSTR (value.base, 0);
! len = strlen (strp) + 1;
}
break;
--- 2676,2683 ----
return 0;
/* Compare symbol name. */
! strp = (unsigned char *) XSTR (value.base, 0);
! len = strlen ((char *) strp) + 1;
}
break;
*************** compare_constant_1 (exp, p)
*** 2695,2701 ****
return compare_constant_1 (TREE_OPERAND (exp, 0), p);
default:
! abort ();
}
/* Compare constant contents. */
--- 2696,2707 ----
return compare_constant_1 (TREE_OPERAND (exp, 0), p);
default:
! if (lang_expand_constant)
! {
! exp = (*lang_expand_constant) (exp);
! return compare_constant_1 (exp, p);
! }
! return 0;
}
/* Compare constant contents. */
*************** static void
*** 2736,2742 ****
record_constant_1 (exp)
tree exp;
{
! register char *strp;
register int len;
register enum tree_code code = TREE_CODE (exp);
--- 2742,2748 ----
record_constant_1 (exp)
tree exp;
{
! register unsigned char *strp;
register int len;
register enum tree_code code = TREE_CODE (exp);
*************** record_constant_1 (exp)
*** 2746,2758 ****
{
case INTEGER_CST:
obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
! strp = (char *) &TREE_INT_CST_LOW (exp);
len = 2 * sizeof TREE_INT_CST_LOW (exp);
break;
case REAL_CST:
obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
! strp = (char *) &TREE_REAL_CST (exp);
len = sizeof TREE_REAL_CST (exp);
break;
--- 2752,2764 ----
{
case INTEGER_CST:
obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
! strp = (unsigned char *) &TREE_INT_CST_LOW (exp);
len = 2 * sizeof TREE_INT_CST_LOW (exp);
break;
case REAL_CST:
obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
! strp = (unsigned char *) &TREE_REAL_CST (exp);
len = sizeof TREE_REAL_CST (exp);
break;
*************** record_constant_1 (exp)
*** 2761,2767 ****
return;
obstack_1grow (&permanent_obstack, TYPE_MODE (TREE_TYPE (exp)));
! strp = TREE_STRING_POINTER (exp);
len = TREE_STRING_LENGTH (exp);
obstack_grow (&permanent_obstack, (char *) &TREE_STRING_LENGTH (exp),
sizeof TREE_STRING_LENGTH (exp));
--- 2767,2773 ----
return;
obstack_1grow (&permanent_obstack, TYPE_MODE (TREE_TYPE (exp)));
! strp = (unsigned char *) TREE_STRING_POINTER (exp);
len = TREE_STRING_LENGTH (exp);
obstack_grow (&permanent_obstack, (char *) &TREE_STRING_LENGTH (exp),
sizeof TREE_STRING_LENGTH (exp));
*************** record_constant_1 (exp)
*** 2893,2899 ****
return;
default:
! abort ();
}
/* Record constant contents. */
--- 2899,2910 ----
return;
default:
! if (lang_expand_constant)
! {
! exp = (*lang_expand_constant) (exp);
! record_constant_1 (exp);
! }
! return;
}
/* Record constant contents. */
2000-06-22 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.other/init15.C: New test.
Index: testsuite/g++.old-deja/g++.other/init15.C
===================================================================
RCS file: init15.C
diff -N init15.C
*** /dev/null Tue May 5 13:32:27 1998
--- init15.C Thu Jun 22 02:34:40 2000
***************
*** 0 ****
--- 1,22 ----
+ // Build don't link:
+ // Copyright (C) 2000 Free Software Foundation
+ // Contributed by Nathan Sidwell 21 June 2000 <nathan@codesourcery.com>
+
+ // Origin GNATS bug report 136 from
+ // language specific constants caused the backend's constant caching machinery
+ // to fall over.
+
+ struct A {
+ char *name;
+ int reserved;
+ int a;
+ int b;
+ void (A::*func)();
+ void Fn ();
+ };
+
+ void Interpret() {
+ struct A cmd_list =
+ {"a",0,0, 0,&A::Fn}
+ ;
+ }