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 11847


This patch fixes PR c++/11847, a template regression coming from our
implementation of two-phase name lookup.  There was a latent bug in
convert_nontype_argument; it was forming a non-canonical expression.
(An ADDR_EXPR should always have a TREE_TYPE of POINTER_TYPE; if it
wants to have REFERENCE_TYPE, a NOP_EXPR must be inserted.)

Tested on i686-pc-linux-gnu, applied on the mainline

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

2003-09-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/11847
	* pt.c (convert_nontype_argument): Correct representation of
	REFERENCE_TYPE expressions.

2003-09-02  Mark Mitchell  <mark@codesourcery.com>

	PR c++/11847
	* g++.dg/template/class1.C: New test.

Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.770
diff -c -5 -p -r1.770 pt.c
*** cp/pt.c	2 Sep 2003 17:32:28 -0000	1.770
--- cp/pt.c	2 Sep 2003 20:34:19 -0000
*************** convert_nontype_argument (tree type, tre
*** 3207,3219 ****
      case REFERENCE_TYPE:
        {
  	tree type_referred_to = TREE_TYPE (type);
  
  	/* If this expression already has reference type, get the
! 	   underling object.  */
  	if (TREE_CODE (expr_type) == REFERENCE_TYPE) 
  	  {
  	    my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
  	    expr = TREE_OPERAND (expr, 0);
  	    expr_type = TREE_TYPE (expr);
  	  }
  
--- 3207,3222 ----
      case REFERENCE_TYPE:
        {
  	tree type_referred_to = TREE_TYPE (type);
  
  	/* If this expression already has reference type, get the
! 	   underlying object.  */
  	if (TREE_CODE (expr_type) == REFERENCE_TYPE) 
  	  {
+ 	    if (TREE_CODE (expr) == NOP_EXPR
+ 		&& TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
+ 	      STRIP_NOPS (expr);
  	    my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
  	    expr = TREE_OPERAND (expr, 0);
  	    expr_type = TREE_TYPE (expr);
  	  }
  
*************** convert_nontype_argument (tree type, tre
*** 3263,3273 ****
  		|| !real_lvalue_p (expr))
  	      return error_mark_node;
  	  }
  
  	cxx_mark_addressable (expr);
! 	return build1 (ADDR_EXPR, type, expr);
        }
        break;
  
      case RECORD_TYPE:
        {
--- 3266,3276 ----
  		|| !real_lvalue_p (expr))
  	      return error_mark_node;
  	  }
  
  	cxx_mark_addressable (expr);
! 	return build_nop (type, build_address (expr));
        }
        break;
  
      case RECORD_TYPE:
        {
Index: testsuite/g++.dg/template/class1.C
===================================================================
RCS file: testsuite/g++.dg/template/class1.C
diff -N testsuite/g++.dg/template/class1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/class1.C	2 Sep 2003 20:34:20 -0000
***************
*** 0 ****
--- 1,9 ----
+ extern const int a;
+ 
+ template <const int&> class X {};
+ 
+ template <typename> struct Y {
+     X<a> x;
+ };
+ 
+ template struct Y<int>;


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