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]

[C++ PATCH]: Fix bug 635


Hi,
I've installed the attached patch for bug 635. duplicate_decls wasn't
preserving DECL_DEFINED_IN_CLASS_P, so instantiate_decl was getting things
wrong. while at it I renamed DECL_DEFINED_IN_CLASS_P to
DECL_INITIALIZED_IN_CLASS_P, as that's what it's actually saying.

built & tested on i686-pc-linux-gnu, approved by Mark.

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
2001-01-08  Nathan Sidwell  <nathan@codesourcery.com>

	* cp-tree.h (lang_decl_flags): Rename defined_in_class to
	initialized_in_class.
	(DECL_DEFINED_IN_CLASS_P): Rename to ...
	(DECL_INITIALIZED_IN_CLASS_P): ... here, to reflect true meaning.
	* decl.c (duplicate_decls): Preseve DECL_INITIALIZED_IN_CLASS_P.
	(cp_finish_decl): Adjust for DECL_INITIALIZED_IN_CLASS_P.
	* pt.c (check_default_tmpl_args): Adjust for
	DECL_INITIALIZED_IN_CLASS_P.
	(instantiate_class_template): Likewise.
	(instantiate_decl): Check DECL_INITIALIZED_IN_CLASS_P.
	
	* class.c (finish_struct): Constify saved_filename.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.351
diff -c -3 -p -r1.351 class.c
*** class.c	2001/01/08 11:45:18	1.351
--- class.c	2001/01/08 14:34:53
*************** tree
*** 5328,5334 ****
  finish_struct (t, attributes)
       tree t, attributes;
  {
!   char *saved_filename = input_filename;
    int saved_lineno = lineno;
  
    /* Now that we've got all the field declarations, reverse everything
--- 5328,5334 ----
  finish_struct (t, attributes)
       tree t, attributes;
  {
!   const char *saved_filename = input_filename;
    int saved_lineno = lineno;
  
    /* Now that we've got all the field declarations, reverse everything
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.556
diff -c -3 -p -r1.556 cp-tree.h
*** cp-tree.h	2001/01/04 23:53:54	1.556
--- cp-tree.h	2001/01/08 14:34:55
*************** struct lang_decl_flags
*** 1812,1818 ****
    unsigned declared_inline : 1;
    unsigned not_really_extern : 1;
    unsigned needs_final_overrider : 1;
!   unsigned defined_in_class : 1;
  
    unsigned pending_inline_p : 1;
    unsigned global_ctor_p : 1;
--- 1812,1818 ----
    unsigned declared_inline : 1;
    unsigned not_really_extern : 1;
    unsigned needs_final_overrider : 1;
!   unsigned initialized_in_class : 1;
  
    unsigned pending_inline_p : 1;
    unsigned global_ctor_p : 1;
*************** struct lang_decl
*** 2042,2051 ****
     should be allocated.  */
  #define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3(NODE))
  
! /* Nonzero if the DECL was defined in the class definition itself,
     rather than outside the class.  */
! #define DECL_DEFINED_IN_CLASS_P(DECL) \
!  (DECL_LANG_SPECIFIC (DECL)->decl_flags.defined_in_class)
  
  /* Nonzero for FUNCTION_DECL means that this decl is just a
     friend declaration, and should not be added to the list of
--- 2042,2051 ----
     should be allocated.  */
  #define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3(NODE))
  
! /* Nonzero if the DECL was initialized in the class definition itself,
     rather than outside the class.  */
! #define DECL_INITIALIZED_IN_CLASS_P(DECL) \
!  (DECL_LANG_SPECIFIC (DECL)->decl_flags.initialized_in_class)
  
  /* Nonzero for FUNCTION_DECL means that this decl is just a
     friend declaration, and should not be added to the list of
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.733
diff -c -3 -p -r1.733 decl.c
*** decl.c	2001/01/08 11:45:19	1.733
--- decl.c	2001/01/08 14:35:01
*************** duplicate_decls (newdecl, olddecl)
*** 3573,3578 ****
--- 3573,3580 ----
        DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
        DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
        DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
+       DECL_INITIALIZED_IN_CLASS_P (newdecl)
+         |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
        olddecl_friend = DECL_FRIEND_P (olddecl);
  
        /* Only functions have DECL_BEFRIENDING_CLASSES.  */
*************** cp_finish_decl (decl, init, asmspec_tree
*** 7931,7937 ****
        && CP_DECL_CONTEXT (decl) == current_class_type
        && TYPE_BEING_DEFINED (current_class_type)
        && (DECL_INITIAL (decl) || init))
!     DECL_DEFINED_IN_CLASS_P (decl) = 1;
  
    if (TREE_CODE (decl) == VAR_DECL
        && DECL_CONTEXT (decl)
--- 7933,7939 ----
        && CP_DECL_CONTEXT (decl) == current_class_type
        && TYPE_BEING_DEFINED (current_class_type)
        && (DECL_INITIAL (decl) || init))
!     DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
  
    if (TREE_CODE (decl) == VAR_DECL
        && DECL_CONTEXT (decl)
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.498
diff -c -3 -p -r1.498 pt.c
*** pt.c	2001/01/04 19:28:56	1.498
--- pt.c	2001/01/08 14:35:05
***************
*** 1,6 ****
  /* Handle parameterized types (templates) for GNU C++.
!    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
!    Free Software Foundation, Inc.
     Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
     Rewritten by Jason Merrill (jason@cygnus.com).
  
--- 1,6 ----
  /* Handle parameterized types (templates) for GNU C++.
!    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
!    2001  Free Software Foundation, Inc.
     Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
     Rewritten by Jason Merrill (jason@cygnus.com).
  
*************** check_default_tmpl_args (decl, parms, is
*** 2300,2306 ****
  			      current_class_type)))
        /* And, if it was a member function, it really was defined in
  	 the scope of the class.  */
!       && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_DEFINED_IN_CLASS_P (decl)))
      /* We already checked these parameters when the template was
         declared, so there's no need to do it again now.  This function
         was defined in class scope, but we're processing it's body now
--- 2300,2306 ----
  			      current_class_type)))
        /* And, if it was a member function, it really was defined in
  	 the scope of the class.  */
!       && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_INITIALIZED_IN_CLASS_P (decl)))
      /* We already checked these parameters when the template was
         declared, so there's no need to do it again now.  This function
         was defined in class scope, but we're processing it's body now
*************** instantiate_class_template (type)
*** 5059,5065 ****
  	  {
  	    tree init;
  
! 	    if (DECL_DEFINED_IN_CLASS_P (r))
  	      init = tsubst_expr (DECL_INITIAL (t), args,
  				  /*complain=*/1, NULL_TREE);
  	    else
--- 5059,5065 ----
  	  {
  	    tree init;
  
! 	    if (DECL_INITIALIZED_IN_CLASS_P (r))
  	      init = tsubst_expr (DECL_INITIAL (t), args,
  				  /*complain=*/1, NULL_TREE);
  	    else
*************** instantiate_class_template (type)
*** 5069,5075 ****
  					    /*asmspec_tree=*/NULL_TREE, 
  					    /*flags=*/0);
  
! 	    if (DECL_DEFINED_IN_CLASS_P (r))
  	      check_static_variable_definition (r, TREE_TYPE (r));
  	  }
  	
--- 5069,5075 ----
  					    /*asmspec_tree=*/NULL_TREE, 
  					    /*flags=*/0);
  
! 	    if (DECL_INITIALIZED_IN_CLASS_P (r))
  	      check_static_variable_definition (r, TREE_TYPE (r));
  	  }
  	
*************** instantiate_decl (d, defer_ok)
*** 9728,9739 ****
  	import_export_decl (d);
      }
  
!   /* We need to set up DECL_INITIAL regardless of pattern_defined if
!      the variable is a static const initialized in the class body.  */
!   if (TREE_CODE (d) == VAR_DECL 
!       && TREE_READONLY (d)
!       && DECL_INITIAL (d) == NULL_TREE
!       && DECL_INITIAL (code_pattern) != NULL_TREE)
      ;
    /* Reject all external templates except inline functions.  */
    else if (DECL_INTERFACE_KNOWN (d)
--- 9728,9736 ----
  	import_export_decl (d);
      }
  
!   /* We need to set up DECL_INITIAL regardless, if
!      the variable is initialized in the class body.  */
!   if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d))
      ;
    /* Reject all external templates except inline functions.  */
    else if (DECL_INTERFACE_KNOWN (d)

// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 14 Nov 2000 <nathan@codesourcery.com>

// Bug 635. We failed to emit initializer code for out-of-class defined
// static const members of template instantiations.

static int inited = 0;

static bool setFlag()
{
  inited++;
  return true;
}

template<typename T> struct X
{
  static const bool cflag;
  static bool flag;
  static const bool iflag = true;
  static const bool jflag = true;
};

template<typename T> const bool X<T>::cflag (setFlag ());
template<typename T> bool X<T>::flag (setFlag ());
template<typename T> const bool X<T>::iflag;

int main ()
{
  X<int> a;
  if (!a.flag)
    return 1;
  if (!a.cflag)
    return 2;
  if (!a.iflag)
    return 3;
  if (!a.jflag)
    return 5;
  if (!X<float>::flag)
    return 5;
  if (!X<float>::cflag)
    return 6;
  if (!X<float>::iflag)
    return 7;
  if (!X<float>::jflag)
    return 8;
  if (inited != 4)
    return 9;
  return 0;
}

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