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]
Other format: [Raw text]

C++ PATCH: PR 15507, 15542, 15427, 15287


This patch fixes 4 C++ regressions in 3.4; all of the patches are
quite straightforward.  Tested on i686-pc-linux-gnu, applied on the
mainline and on the branch.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-05-22  Mark Mitchell  <mark@codesourcery.com>

	PR c++/15507
	* class.c (layout_nonempty_base_or_field): Do not try to avoid
	layout conflicts for unions.

	PR c++/15542
	* typeck.c (build_x_unary_op): Instantiate template class
	specializations before looking for "operator &".

	PR c++/15427
	* typeck.c (complete_type): Layout non-dependent array types, even
	in templates.

	PR c++/15287
	* typeck.c (build_unary_op): Do not optimize "&x[y]" when in a
	template.

2004-05-22  Mark Mitchell  <mark@codesourcery.com>

	PR c++/15507
	* g++.dg/inherit/union1.C: New test.

	PR c++/15542
	* g++.dg/template/addr1.C: New test.

	PR c++/15427
	* g++.dg/template/array5.C: New test.

	PR c++/15287
	* g++.dg/template/array6.C: New test.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.595.4.7
diff -c -5 -p -r1.595.4.7 class.c
*** cp/class.c	9 Mar 2004 07:27:23 -0000	1.595.4.7
--- cp/class.c	22 May 2004 19:10:38 -0000
*************** layout_nonempty_base_or_field (record_la
*** 3421,3446 ****
        struct record_layout_info_s old_rli = *rli;
  
        /* Place this field.  */
        place_field (rli, decl);
        offset = byte_position (decl);
!  
        /* We have to check to see whether or not there is already
  	 something of the same type at the offset we're about to use.
! 	 For example:
  	 
! 	 struct S {};
! 	 struct T : public S { int i; };
! 	 struct U : public S, public T {};
  	 
  	 Here, we put S at offset zero in U.  Then, we can't put T at
  	 offset zero -- its S component would be at the same address
  	 as the S we already allocated.  So, we have to skip ahead.
  	 Since all data members, including those whose type is an
  	 empty class, have nonzero size, any overlap can happen only
  	 with a direct or indirect base-class -- it can't happen with
  	 a data member.  */
        /* G++ 3.2 did not check for overlaps when placing a non-empty
  	 virtual base.  */
        if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo))
  	break;
        if (layout_conflict_p (field_p ? type : binfo, offset, 
--- 3421,3450 ----
        struct record_layout_info_s old_rli = *rli;
  
        /* Place this field.  */
        place_field (rli, decl);
        offset = byte_position (decl);
! 
        /* We have to check to see whether or not there is already
  	 something of the same type at the offset we're about to use.
! 	 For example, consider:
  	 
! 	   struct S {};
! 	   struct T : public S { int i; };
! 	   struct U : public S, public T {};
  	 
  	 Here, we put S at offset zero in U.  Then, we can't put T at
  	 offset zero -- its S component would be at the same address
  	 as the S we already allocated.  So, we have to skip ahead.
  	 Since all data members, including those whose type is an
  	 empty class, have nonzero size, any overlap can happen only
  	 with a direct or indirect base-class -- it can't happen with
  	 a data member.  */
+       /* In a union, overlap is permitted; all members are placed at
+ 	 offset zero.  */
+       if (TREE_CODE (rli->t) == UNION_TYPE)
+ 	break;
        /* G++ 3.2 did not check for overlaps when placing a non-empty
  	 virtual base.  */
        if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo))
  	break;
        if (layout_conflict_p (field_p ? type : binfo, offset, 
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.519.2.14
diff -c -5 -p -r1.519.2.14 typeck.c
*** cp/typeck.c	1 Apr 2004 23:18:14 -0000	1.519.2.14
--- cp/typeck.c	22 May 2004 19:10:38 -0000
*************** complete_type (tree type)
*** 122,132 ****
    if (type == error_mark_node || COMPLETE_TYPE_P (type))
      ;
    else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
      {
        tree t = complete_type (TREE_TYPE (type));
!       if (COMPLETE_TYPE_P (t) && ! processing_template_decl)
  	layout_type (type);
        TYPE_NEEDS_CONSTRUCTING (type)
  	= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
        TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
  	= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
--- 122,132 ----
    if (type == error_mark_node || COMPLETE_TYPE_P (type))
      ;
    else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
      {
        tree t = complete_type (TREE_TYPE (type));
!       if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
  	layout_type (type);
        TYPE_NEEDS_CONSTRUCTING (type)
  	= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
        TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
  	= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
*************** build_x_unary_op (enum tree_code code, t
*** 3528,3543 ****
        xarg = build_non_dependent_expr (xarg);
      }
  
    exp = NULL_TREE;
  
!   /* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an
!      error message.  */
    if (code == ADDR_EXPR
        && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
!       && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg)))
! 	   && !COMPLETE_TYPE_P (TREE_TYPE (xarg)))
  	  || (TREE_CODE (xarg) == OFFSET_REF)))
      /* Don't look for a function.  */;
    else
      exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE,
  			/*overloaded_p=*/NULL);
--- 3528,3549 ----
        xarg = build_non_dependent_expr (xarg);
      }
  
    exp = NULL_TREE;
  
!   /* [expr.unary.op] says:
! 
!        The address of an object of incomplete type can be taken.
! 
!      (And is just the ordinary address operator, not an overloaded
!      "operator &".)  However, if the type is a template
!      specialization, we must complete the type at this point so that
!      an overloaded "operator &" will be available if required.  */
    if (code == ADDR_EXPR
        && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
!       && ((CLASS_TYPE_P (TREE_TYPE (xarg))
! 	   && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
  	  || (TREE_CODE (xarg) == OFFSET_REF)))
      /* Don't look for a function.  */;
    else
      exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE,
  			/*overloaded_p=*/NULL);
*************** build_unary_op (enum tree_code code, tre
*** 3942,3953 ****
  	    /* Don't let this be an lvalue.  */
  	    return non_lvalue (arg);
  	  return arg;
  	}
  
!       /* For &x[y], return x+y.  */
!       if (TREE_CODE (arg) == ARRAY_REF)
  	{
  	  if (!cxx_mark_addressable (TREE_OPERAND (arg, 0)))
  	    return error_mark_node;
  	  return cp_build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
  				     TREE_OPERAND (arg, 1));
--- 3948,3963 ----
  	    /* Don't let this be an lvalue.  */
  	    return non_lvalue (arg);
  	  return arg;
  	}
  
!       /* For &x[y], return x+y.  But, in a template, ARG may be an
! 	 ARRAY_REF representing a non-dependent expression.  In that
! 	 case, there may be an overloaded "operator []" that will be
! 	 chosen at instantiation time; we must not try to optimize
! 	 here.  */
!       if (TREE_CODE (arg) == ARRAY_REF && !processing_template_decl)
  	{
  	  if (!cxx_mark_addressable (TREE_OPERAND (arg, 0)))
  	    return error_mark_node;
  	  return cp_build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
  				     TREE_OPERAND (arg, 1));
Index: testsuite/g++.dg/inherit/union1.C
===================================================================
RCS file: testsuite/g++.dg/inherit/union1.C
diff -N testsuite/g++.dg/inherit/union1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/union1.C	22 May 2004 19:10:40 -0000
***************
*** 0 ****
--- 1,14 ----
+ // PR c++/15507
+ 
+ struct A {
+   // empty
+ };
+ 
+ struct B : A {
+   int b;
+ };
+ 
+ union U {
+   A a;
+   B b;
+ };
Index: testsuite/g++.dg/template/addr1.C
===================================================================
RCS file: testsuite/g++.dg/template/addr1.C
diff -N testsuite/g++.dg/template/addr1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/addr1.C	22 May 2004 19:10:41 -0000
***************
*** 0 ****
--- 1,12 ----
+ // PR c++/15542
+ 
+ template <typename> struct S_T { 
+   const char** operator & (); 
+ }; 
+  
+ template <class T> void foo(T **) {} 
+  
+ template <typename> void templateTest() { 
+   S_T<const char> s_t; 
+   foo(&s_t); 
+ } 
Index: testsuite/g++.dg/template/array5.C
===================================================================
RCS file: testsuite/g++.dg/template/array5.C
diff -N testsuite/g++.dg/template/array5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/array5.C	22 May 2004 19:10:41 -0000
***************
*** 0 ****
--- 1,14 ----
+ // PR c++/15427
+ 
+ template<class T>
+ struct A
+ {
+   T foo;
+ };
+ 
+ template<class T>
+ struct B
+ {
+   A<int> _squares[2];
+ };
+ 
Index: testsuite/g++.dg/template/array6.C
===================================================================
RCS file: testsuite/g++.dg/template/array6.C
diff -N testsuite/g++.dg/template/array6.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/array6.C	22 May 2004 19:10:41 -0000
***************
*** 0 ****
--- 1,13 ----
+ // PR c++/15287
+ 
+ struct S {}; 
+  
+ struct Array { 
+   S operator[](int); 
+ } array; 
+  
+ void (S::*mem_fun_ptr)(); 
+  
+ template <int> void foo() { 
+   (array[0].*mem_fun_ptr)(); 
+ } 


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