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: More testsuite regressions


This patch is another set of safe C++ patches to fix a variety of
regressions we've found with various tests.

There were a couple of scary bugs: my C++ pointer-to-member
representation change wasn't quite complete, with the result that we
were silently generating wrong code for (a) conversions between two
pointer member types to their common type, and (b) pointer arithmetic
where the pointers pointed to pointers-to-members.  We also refused to
do pointer-to-member const_casts, complaining in the error message
that you must use a "reference, pointer, or pointer-to-member". (!)

There are three other fixes here as well:

(1) an invalid error message about void-expressions in conditional
    expressions,

(2) an invalid error message about declaring a type named "main",

(3) a failure to handle 

      S::template g<T>()

    correctly in the case that "S" is not dependent.

Tested on i686-pc-linux-gnu, applied on the mainline and on the 3.4
branch.

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

2004-03-18  Mark Mitchell  <mark@codesourcery.com>

	* c-common.c (pointer_int_sum): Do not complain about using
	pointers to pointers-to-members.

2004-03-18  Mark Mitchell  <mark@codesourcery.com>

	* call.c (build_conditional_expr): Do not call force_rvalue for
	operands of void_type when the conditional expression itself has
	void type.
	* name-lookup.c (pushdecl): Don't consider a declaration of a
	function named "main" to be an overload of a type named "main".
	* parser.c (cp_parser_template_name): Perform name lookup when the
	template name is proceeded by "template" if the qualifying scope
	is non-dependent.
	* typeck.c (composite_pointer_type_r): Correctly handle
	pointer-to-member types.
	(build_const_cast): Likewise.

2004-03-18  Mark Mitchell  <mark@codesourcery.com>

	* g++.dg/expr/cond5.C: New test.
	* g++.dg/expr/constcast1.C: Likewise.
	* g++.dg/expr/ptrmem2.C: Likewise.
	* g++.dg/expr/ptrmem3.C: Likewise.
	* g++.dg/lookup/main1.C: Likewise.
	* g++.dg/template/lookup6.C: Likewise.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.476.4.5
diff -c -5 -p -r1.476.4.5 c-common.c
*** c-common.c	18 Feb 2004 00:08:55 -0000	1.476.4.5
--- c-common.c	19 Mar 2004 01:31:44 -0000
*************** pointer_int_sum (enum tree_code resultco
*** 2509,2524 ****
      {
        if (pedantic || warn_pointer_arith)
  	pedwarn ("pointer to member function used in arithmetic");
        size_exp = integer_one_node;
      }
-   else if (TREE_CODE (TREE_TYPE (result_type)) == OFFSET_TYPE)
-     {
-       if (pedantic || warn_pointer_arith)
- 	pedwarn ("pointer to a member used in arithmetic");
-       size_exp = integer_one_node;
-     }
    else
      size_exp = size_in_bytes (TREE_TYPE (result_type));
  
    /* If what we are about to multiply by the size of the elements
       contains a constant term, apply distributive law
--- 2509,2518 ----
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.452.2.13
diff -c -5 -p -r1.452.2.13 call.c
*** cp/call.c	16 Mar 2004 21:35:03 -0000	1.452.2.13
--- cp/call.c	19 Mar 2004 01:14:23 -0000
*************** build_conditional_expr (tree arg1, tree 
*** 3004,3025 ****
  	 --The second or the third operand (but not both) is a
  	   throw-expression (_except.throw_); the result is of the
  	   type of the other and is an rvalue.
  
  	 --Both the second and the third operands have type void; the
! 	   result is of type void and is an rvalue.  */
        if (TREE_CODE (arg2) == THROW_EXPR 
  	  && TREE_CODE (arg3) != THROW_EXPR)
  	{
! 	  arg3 = force_rvalue (arg3);
  	  arg3_type = TREE_TYPE (arg3);
  	  result_type = arg3_type;
  	}
        else if (TREE_CODE (arg2) != THROW_EXPR 
  	       && TREE_CODE (arg3) == THROW_EXPR)
  	{
! 	  arg2 = force_rvalue (arg2);
  	  arg2_type = TREE_TYPE (arg2);
  	  result_type = arg2_type;
  	}
        else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
  	result_type = void_type_node;
--- 3004,3031 ----
  	 --The second or the third operand (but not both) is a
  	   throw-expression (_except.throw_); the result is of the
  	   type of the other and is an rvalue.
  
  	 --Both the second and the third operands have type void; the
! 	   result is of type void and is an rvalue.  
! 
!          We must avoid calling force_rvalue for expressions of type
! 	 "void" because it will complain that their value is being
! 	 used.   */
        if (TREE_CODE (arg2) == THROW_EXPR 
  	  && TREE_CODE (arg3) != THROW_EXPR)
  	{
! 	  if (!VOID_TYPE_P (arg3_type))
! 	    arg3 = force_rvalue (arg3);
  	  arg3_type = TREE_TYPE (arg3);
  	  result_type = arg3_type;
  	}
        else if (TREE_CODE (arg2) != THROW_EXPR 
  	       && TREE_CODE (arg3) == THROW_EXPR)
  	{
! 	  if (!VOID_TYPE_P (arg2_type))
! 	    arg2 = force_rvalue (arg2);
  	  arg2_type = TREE_TYPE (arg2);
  	  result_type = arg2_type;
  	}
        else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
  	result_type = void_type_node;
Index: cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.34.2.7
diff -c -5 -p -r1.34.2.7 name-lookup.c
*** cp/name-lookup.c	9 Mar 2004 08:24:35 -0000	1.34.2.7
--- cp/name-lookup.c	19 Mar 2004 01:14:24 -0000
*************** pushdecl (tree x)
*** 710,720 ****
  		  else if (TREE_CODE (t) == FUNCTION_DECL)
  		    check_default_args (t);
  
  		  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  		}
! 	      else if (DECL_MAIN_P (x))
  		{
  		  /* A redeclaration of main, but not a duplicate of the
  		     previous one.
  		     
  		     [basic.start.main]
--- 710,720 ----
  		  else if (TREE_CODE (t) == FUNCTION_DECL)
  		    check_default_args (t);
  
  		  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  		}
! 	      else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL)
  		{
  		  /* A redeclaration of main, but not a duplicate of the
  		     previous one.
  		     
  		     [basic.start.main]
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.157.2.22
diff -c -5 -p -r1.157.2.22 parser.c
*** cp/parser.c	16 Mar 2004 21:35:08 -0000	1.157.2.22
--- cp/parser.c	19 Mar 2004 01:14:25 -0000
*************** cp_parser_template_name (cp_parser* pars
*** 8116,8126 ****
  	    }
  	  if (is_identifier)
  	    *is_identifier = true;
  	  return identifier;
  	}
!       if (template_keyword_p)
  	return identifier;
      }
  
    /* Look up the name.  */
    decl = cp_parser_lookup_name (parser, identifier,
--- 8116,8134 ----
  	    }
  	  if (is_identifier)
  	    *is_identifier = true;
  	  return identifier;
  	}
! 
!       /* If the "template" keyword is present, then there is generally
! 	 no point in doing name-lookup, so we just return IDENTIFIER.
! 	 But, if the qualifying scope is non-dependent then we can
! 	 (and must) do name-lookup normally.  */
!       if (template_keyword_p
! 	  && (!parser->scope
! 	      || (TYPE_P (parser->scope) 
! 		  && dependent_type_p (parser->scope))))
  	return identifier;
      }
  
    /* Look up the name.  */
    decl = cp_parser_lookup_name (parser, identifier,
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.519.2.10
diff -c -5 -p -r1.519.2.10 typeck.c
*** cp/typeck.c	16 Mar 2004 21:35:16 -0000	1.519.2.10
--- cp/typeck.c	19 Mar 2004 01:14:25 -0000
*************** composite_pointer_type_r (tree t1, tree 
*** 441,451 ****
        result_type = void_type_node;
      }
    result_type = cp_build_qualified_type (result_type,
  					 (cp_type_quals (pointee1)
  					  | cp_type_quals (pointee2)));
-   result_type = build_pointer_type (result_type);
    /* If the original types were pointers to members, so is the
       result.  */
    if (TYPE_PTR_TO_MEMBER_P (t1))
      {
        if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
--- 441,450 ----
*************** composite_pointer_type_r (tree t1, tree 
*** 454,463 ****
--- 453,464 ----
  		 "lacks a cast",
  		 location, t1, t2);
        result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
  				       result_type);
      }
+   else
+     result_type = build_pointer_type (result_type);
  
    /* Merge the attributes.  */
    attributes = (*targetm.merge_type_attributes) (t1, t2);
    return build_type_attribute_variant (result_type, attributes);
  }
*************** build_const_cast (tree type, tree expr)
*** 4725,4735 ****
  	/* There might turn out to be side effects inside expr.  */
  	TREE_SIDE_EFFECTS (t) = 1;
        return t;
      }
  
!   if (!POINTER_TYPE_P (type))
      error ("invalid use of const_cast with type `%T', which is not a pointer, reference, nor a pointer-to-data-member type", type);
    else if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
      {
        error ("invalid use of const_cast with type `%T', which is a pointer or reference to a function type", type);
        return error_mark_node;
--- 4726,4736 ----
  	/* There might turn out to be side effects inside expr.  */
  	TREE_SIDE_EFFECTS (t) = 1;
        return t;
      }
  
!   if (!POINTER_TYPE_P (type) && !TYPE_PTRMEM_P (type))
      error ("invalid use of const_cast with type `%T', which is not a pointer, reference, nor a pointer-to-data-member type", type);
    else if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
      {
        error ("invalid use of const_cast with type `%T', which is a pointer or reference to a function type", type);
        return error_mark_node;
Index: testsuite/g++.dg/expr/cond5.C
===================================================================
RCS file: testsuite/g++.dg/expr/cond5.C
diff -N testsuite/g++.dg/expr/cond5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/expr/cond5.C	19 Mar 2004 01:14:26 -0000
***************
*** 0 ****
--- 1,3 ----
+ void f() {
+   true ? throw 1 : (void)7;
+ }
Index: testsuite/g++.dg/expr/constcast1.C
===================================================================
RCS file: testsuite/g++.dg/expr/constcast1.C
diff -N testsuite/g++.dg/expr/constcast1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/expr/constcast1.C	19 Mar 2004 01:14:26 -0000
***************
*** 0 ****
--- 1,9 ----
+ struct S {
+   int i;
+ };
+ 
+ void f() {
+   int const S::*p;
+   const_cast<int const S::*>(p);
+ }
+ 
Index: testsuite/g++.dg/expr/ptrmem2.C
===================================================================
RCS file: testsuite/g++.dg/expr/ptrmem2.C
diff -N testsuite/g++.dg/expr/ptrmem2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/expr/ptrmem2.C	19 Mar 2004 01:14:26 -0000
***************
*** 0 ****
--- 1,12 ----
+ struct S {
+   int i;
+ };
+ 
+ int S::**p;
+ int S::*q;
+ 
+ void f() {
+   p[1] = q;
+ }
+ 
+ 
Index: testsuite/g++.dg/expr/ptrmem3.C
===================================================================
RCS file: testsuite/g++.dg/expr/ptrmem3.C
diff -N testsuite/g++.dg/expr/ptrmem3.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/expr/ptrmem3.C	19 Mar 2004 01:14:26 -0000
***************
*** 0 ****
--- 1,9 ----
+ struct S {};
+ struct T : public S {};
+ 
+ void f() {
+   int S::*s;
+   int T::*t;
+   (t ? t : s) == t;
+ }
+ 
Index: testsuite/g++.dg/lookup/main1.C
===================================================================
RCS file: testsuite/g++.dg/lookup/main1.C
diff -N testsuite/g++.dg/lookup/main1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/lookup/main1.C	19 Mar 2004 01:14:26 -0000
***************
*** 0 ****
--- 1,3 ----
+ struct main {};
+ 
+ int main () {}
Index: testsuite/g++.dg/template/lookup6.C
===================================================================
RCS file: testsuite/g++.dg/template/lookup6.C
diff -N testsuite/g++.dg/template/lookup6.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/lookup6.C	19 Mar 2004 01:14:26 -0000
***************
*** 0 ****
--- 1,11 ----
+ struct S
+ {
+   template<typename T> static void g();
+ };
+ 
+ template<typename T>
+ void f() { return S::template g<T>(); }
+ 
+ void g() {
+   f<int>();
+ }


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