PATCH for casting to class type

Mark Mitchell mmitchell@usa.net
Tue May 5 00:50:00 GMT 1998


Jason --

  Here's a patch that improves the handling of arrays to class type.
For example, the following code didn't compile correctly, but does
now.  Is this OK?

  typedef int Array_T[2];

  struct S1 {
    S1(const Array_T&);
  };

  struct S2 {
    S1 g();
    Array_T a;
  };

  S1 S2::g()
  {
    return S1(a);
  }

  void h()
  {
    S2 s2;
    s2.g();
  }

-- 
Mark Mitchell <mmitchell@usa.net>
http://home.earthlink.net/~mbmitchell
Consulting Services Available

Index: cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.58
diff -c -p -r1.58 cp-tree.h
*** cp-tree.h	1998/04/26 16:29:58	1.58
--- cp-tree.h	1998/05/04 15:56:47
*************** enum languages { lang_c, lang_cplusplus,
*** 392,397 ****
--- 395,404 ----
  #define IS_OVERLOAD_TYPE(t) \
    (IS_AGGR_TYPE (t) || TREE_CODE (t) == ENUMERAL_TYPE)
  
+ /* Retruns non-zero iff NODE is a class, struct, or union type.  */
+ #define IS_CLASS_TYPE(NODE) \
+   (IS_AGGR_TYPE_CODE (TREE_CODE (NODE)) && !TYPE_PTRMEMFUNC_P (NODE))
+ 
  /* In a *_TYPE, nonzero means a built-in type.  */
  #define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6(NODE)
  
Index: cp/typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.61
diff -c -p -r1.61 typeck.c
*** typeck.c	1998/04/26 16:30:11	1.61
--- typeck.c	1998/05/04 15:59:21
*************** build_c_cast (type, expr)
*** 5620,5635 ****
  
        /* Convert functions and arrays to pointers and
  	 convert references to their expanded types,
! 	 but don't convert any other types.  */
!       if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
! 	  || (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE
! 	      /* Don't do the default conversion if we want a
! 		 pointer to a function.  */
! 	      && ! (TREE_CODE (type) == POINTER_TYPE
! 		    && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
! 	  || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
! 	  || TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
! 	value = default_conversion (value);
        otype = TREE_TYPE (value);
  
        /* Optionally warn about potentially worrisome casts.  */
--- 5643,5678 ----
  
        /* Convert functions and arrays to pointers and
  	 convert references to their expanded types,
! 	 but don't convert any other types.  If, however, we are
! 	 casting to a class type, there's no reason to do this: the
! 	 cast will only succeed if there is a converting constructor,
! 	 and the default conversions will be done at that point.  In
! 	 fact, doing the default conversion here is actually harmful
! 	 in cases like this:
! 
! 	     typedef int A[2];
!              struct S { S(const A&); };
! 
!          since we don't want the array-to-pointer conversion done.  */
!       if (!IS_CLASS_TYPE (type))
! 	{
! 	  if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
! 	      || (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE
! 		  /* Don't do the default conversion if we want a
! 		     pointer to a function.  */
! 		  && ! (TREE_CODE (type) == POINTER_TYPE
! 			&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
! 	      || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
! 	      || TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
! 	  value = default_conversion (value);
! 	}
!       else if (TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
! 	/* However, even for class types, we still need to strip away
! 	   the reference type, since the call to convert_force below
! 	   does not expect the input expression to be of reference
! 	   type.  */
! 	value = convert_from_reference (value);
! 	
        otype = TREE_TYPE (value);
  
        /* Optionally warn about potentially worrisome casts.  */
Index: cvt1.C
===================================================================
RCS file: cvt1.C
diff -N cvt1.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- cvt1.C	Mon May  4 09:58:07 1998
***************
*** 0 ****
--- 1,23 ----
+ // Build don't link:
+ 
+ typedef int Array_T[2];
+ 
+ struct S1 {
+   S1(const Array_T&);
+ };
+ 
+ struct S2 {
+   S1 g();
+   Array_T a;
+ };
+ 
+ S1 S2::g()
+ {
+   return S1(a);
+ }
+ 
+ void h()
+ {
+   S2 s2;
+   s2.g();
+ }



More information about the Gcc-bugs mailing list