This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 11847
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 2 Sep 2003 13:51:54 -0700
- Subject: C++ PATCH: PR 11847
- Reply-to: mark at codesourcery dot com
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>;