This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 23896
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 15 Sep 2005 18:52:21 -0700
- Subject: C++ PATCH: PR 23896
- Reply-to: mark at codesourcery dot com
This patch fixes yet another problem with static data members in
templates. When substituting into "sizeof (S<I>::x)" we need to
remember to evaluate "I", even though we don't need to evaluate
"S<I>::x".
Tested on x86_64-unknown-linux-gnu, applied on the mainline and on the
4.0 branch. (This is a regression from 4.0.1.)
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2005-09-15 Mark Mitchell <mark@codesourcery.com>
PR c++/23896
* pt.c (tsubst_aggr_type): Make sure skip_evaluation is false when
processing template arguments.
2005-09-15 Mark Mitchell <mark@codesourcery.com>
PR c++/23896
* g++.dg/template/static17.C: New test.
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.1036
diff -c -5 -p -r1.1036 pt.c
*** gcc/cp/pt.c 15 Sep 2005 16:51:37 -0000 1.1036
--- gcc/cp/pt.c 15 Sep 2005 21:16:42 -0000
*************** tsubst_aggr_type (tree t,
*** 6067,6076 ****
--- 6067,6081 ----
if (TYPE_TEMPLATE_INFO (t))
{
tree argvec;
tree context;
tree r;
+ bool saved_skip_evaluation;
+
+ /* In "sizeof(X<I>)" we need to evaluate "I". */
+ saved_skip_evaluation = skip_evaluation;
+ skip_evaluation = false;
/* First, determine the context for the type we are looking
up. */
context = TYPE_CONTEXT (t);
if (context)
*************** tsubst_aggr_type (tree t,
*** 6087,6102 ****
then our ARGS will be {int, double}, but, when looking up
S we only want {double}. */
argvec = tsubst_template_args (TYPE_TI_ARGS (t), args,
complain, in_decl);
if (argvec == error_mark_node)
! return error_mark_node;
!
! r = lookup_template_class (t, argvec, in_decl, context,
! entering_scope, complain);
! return cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
}
else
/* This is not a template type, so there's nothing to do. */
return t;
--- 6092,6112 ----
then our ARGS will be {int, double}, but, when looking up
S we only want {double}. */
argvec = tsubst_template_args (TYPE_TI_ARGS (t), args,
complain, in_decl);
if (argvec == error_mark_node)
! r = error_mark_node;
! else
! {
! r = lookup_template_class (t, argvec, in_decl, context,
! entering_scope, complain);
! r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
! }
!
! skip_evaluation = saved_skip_evaluation;
! return r;
}
else
/* This is not a template type, so there's nothing to do. */
return t;
Index: gcc/testsuite/g++.dg/template/static17.C
===================================================================
RCS file: gcc/testsuite/g++.dg/template/static17.C
diff -N gcc/testsuite/g++.dg/template/static17.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/template/static17.C 15 Sep 2005 21:16:42 -0000
***************
*** 0 ****
--- 1,13 ----
+ // PR c++/23896
+
+ template <int> struct X {};
+
+ template <typename T> struct length {
+ static const int value = 2;
+ };
+
+ template <typename T> void foo () {
+ sizeof(X<length<T>::value>);
+ }
+
+ template void foo<int>();