This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Fix PR 5333
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 23 Feb 2003 23:41:46 -0800
- Subject: C++ PATCH: Fix PR 5333
- Reply-to: mark at codesourcery dot com
PR 5333 is an ICE-on-illegal-code. Here's a fix for the mainline,
tested on i686-pc-linux-gnu, and applied.
On the 3.3 branch, there's no easy fix. The key problem is that we
are trying to do a variant on the implicit typename extension:
allowing the user to omit both the "typename" and "template" keyword,
in this situation. In so doing, we lose key information -- and with
the old parser I don't see an easy, safe way around this.
Therefore, I'm going to close the bug, with a note. Since this is an
ICE-on-illegal, I think that's acceptable.
--
Mark Mitchell mark at codesourcery dot com
CodeSourcery, LLC http://www.codesourcery.com
2003-02-23 Mark Mitchell <mark at codesourcery dot com>
PR c++/5333
* cp-tree.h (CLASSTYPE_PRIMARY_TEMPLATE): New macro.
* parser.c (cp_parser_diagnose_invalid_type_name): Use it.
* pt.c (instantiate_class_template): Don't try to instantiate
dependent types.
(resolve_typename_type): Use CLASSTYPE_PRIMARY_TEMPLATE.
2003-02-23 Mark Mitchell <mark at codesourcery dot com>
PR c++/5333
* g++.dg/parse/fused-params1.C: Adjust error messages.
* g++.dg/template/nested3.C: New test.
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.813
diff -c -5 -p -r1.813 cp-tree.h
*** cp/cp-tree.h 20 Feb 2003 17:51:42 -0000 1.813
--- cp/cp-tree.h 24 Feb 2003 07:39:41 -0000
*************** struct lang_decl GTY(())
*** 2314,2323 ****
--- 2314,2329 ----
#define ENUM_TI_TEMPLATE(NODE) \
TI_TEMPLATE (ENUM_TEMPLATE_INFO (NODE))
#define ENUM_TI_ARGS(NODE) \
TI_ARGS (ENUM_TEMPLATE_INFO (NODE))
+ /* For a template instantiation TYPE, returns the TYPE corresponding
+ to the primary template. */
+ #define CLASSTYPE_PRIMARY_TEMPLATE_TYPE(TYPE) \
+ TREE_TYPE (DECL_TEMPLATE_RESULT (DECL_PRIMARY_TEMPLATE \
+ (CLASSTYPE_TI_TEMPLATE ((TYPE)))))
+
/* Like DECL_TI_TEMPLATE, but for an ENUMERAL_, RECORD_, or UNION_TYPE. */
#define TYPE_TI_TEMPLATE(NODE) \
(TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))
/* Like DECL_TI_ARGS, but for an ENUMERAL_, RECORD_, or UNION_TYPE. */
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.44
diff -c -5 -p -r1.44 parser.c
*** cp/parser.c 20 Feb 2003 17:51:43 -0000 1.44
--- cp/parser.c 24 Feb 2003 07:39:44 -0000
*************** cp_parser_diagnose_invalid_type_name (cp
*** 1952,1965 ****
tree field;
/* Go from a particular instantiation of the
template (which will have an empty TYPE_FIELDs),
to the main version. */
if (CLASSTYPE_USE_TEMPLATE (base_type))
! base_type = (TREE_TYPE
! (DECL_TEMPLATE_RESULT
! (DECL_PRIMARY_TEMPLATE
! (CLASSTYPE_TI_TEMPLATE (base_type)))));
for (field = TYPE_FIELDS (base_type);
field;
field = TREE_CHAIN (field))
if (TREE_CODE (field) == TYPE_DECL
&& DECL_NAME (field) == name)
--- 1952,1962 ----
tree field;
/* Go from a particular instantiation of the
template (which will have an empty TYPE_FIELDs),
to the main version. */
if (CLASSTYPE_USE_TEMPLATE (base_type))
! base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type);
for (field = TYPE_FIELDS (base_type);
field;
field = TREE_CHAIN (field))
if (TREE_CODE (field) == TYPE_DECL
&& DECL_NAME (field) == name)
*************** cp_parser_unary_operator (cp_token* toke
*** 4524,4533 ****
--- 4521,4531 ----
}
}
/* Parse a new-expression.
+ new-expression:
:: [opt] new new-placement [opt] new-type-id new-initializer [opt]
:: [opt] new new-placement [opt] ( type-id ) new-initializer [opt]
Returns a representation of the expression. */
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.662
diff -c -5 -p -r1.662 pt.c
*** cp/pt.c 20 Feb 2003 17:51:43 -0000 1.662
--- cp/pt.c 24 Feb 2003 07:39:47 -0000
*************** instantiate_class_template (type)
*** 5149,5159 ****
tree pbinfo;
if (type == error_mark_node)
return error_mark_node;
! if (TYPE_BEING_DEFINED (type) || COMPLETE_TYPE_P (type))
return type;
/* Figure out which template is being instantiated. */
template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
--- 5149,5161 ----
tree pbinfo;
if (type == error_mark_node)
return error_mark_node;
! if (TYPE_BEING_DEFINED (type)
! || COMPLETE_TYPE_P (type)
! || dependent_type_p (type))
return type;
/* Figure out which template is being instantiated. */
template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
*************** resolve_typename_type (tree type, bool o
*** 11524,11533 ****
--- 11526,11539 ----
return type;
/* If the SCOPE is not the current instantiation, there's no reason
to look inside it. */
if (only_current_p && !currently_open_class (scope))
return error_mark_node;
+ /* If SCOPE is a partial instantiation, it will not have a valid
+ TYPE_FIELDS list, so use the original template. */
+ if (CLASSTYPE_USE_TEMPLATE (scope))
+ scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope);
/* Enter the SCOPE so that name lookup will be resolved as if we
were in the class definition. In particular, SCOPE will no
longer be considered a dependent type. */
push_scope (scope);
/* Look up the declaration. */
Index: testsuite/g++.dg/parse/fused-params1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/parse/fused-params1.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 fused-params1.C
*** testsuite/g++.dg/parse/fused-params1.C 6 Feb 2003 22:34:55 -0000 1.1
--- testsuite/g++.dg/parse/fused-params1.C 24 Feb 2003 07:39:49 -0000
***************
*** 1,12 ****
// PR c++/8785
// Origin: Alexander Zvyagin <Alexander dot Zviagine at cern dot ch>
// { dg-do compile }
template <int N,typename T> struct A
! {
typedef T X;
! template <int M> void foo (const A<M,X>&); // { dg-error "candidate" }
};
template <int N,int M,typename T>
void A<N,T>::foo (const A<M,X>&) {} // { dg-error "" }
--- 1,12 ----
// PR c++/8785
// Origin: Alexander Zvyagin <Alexander dot Zviagine at cern dot ch>
// { dg-do compile }
template <int N,typename T> struct A
! { // { dg-error "" }
typedef T X;
! template <int M> void foo (const A<M,X>&);
};
template <int N,int M,typename T>
void A<N,T>::foo (const A<M,X>&) {} // { dg-error "" }
Index: testsuite/g++.dg/template/nested3.C
===================================================================
RCS file: testsuite/g++.dg/template/nested3.C
diff -N testsuite/g++.dg/template/nested3.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/nested3.C 24 Feb 2003 07:39:49 -0000
***************
*** 0 ****
--- 1,28 ----
+ template <class T1, class T2>
+ class A {
+ template <class S>
+ class SubA {
+ int _k;
+ };
+ T1 _t1;
+ T2 _t2;
+ };
+
+ template <class U>
+ class B {
+ class SubB1 {
+ B _i;
+ };
+
+ class SubB2 {
+ int _j;
+ };
+ A<U,SubB1>::SubA<SubB2> _a; // { dg-error "" }
+ };
+
+
+ int main() {
+ B<char> objB;
+
+ return 0;
+ }