This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Fix bug 136 - output language constants


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}
+   ;
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]