This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 16162
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 14 Sep 2004 09:17:15 -0700
- Subject: C++ PATCH: PR 16162
- Reply-to: mark at codesourcery dot com
This patch fixes PR c++/16162 on the 3.4 branch. Unfortunately, the
patch causes us to emit inferior diagnostics on
g++.dg/template/nested3.C; I think this is a good tradeoff, given that
we are fixing a rejects-valid.
Tested on i686-pc-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2004-09-13 Mark Mitchell <mark@codesourcery.com>
PR c++/16162
* parser.c (cp_parser_id_expression): Correct value for
is_declarator.
(cp_parser_nested_name_specifier_opt): Look through typenames as
necessary.
(cp_parser_template_name): Honor check_dependency_p.
2004-09-13 Mark Mitchell <mark@codesourcery.com>
PR c++/16162
* g++.dg/template/decl2.C: New test.
* g++.dg/template/nested3.C: Expect inferior diagnostics.
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.157.2.38
diff -c -5 -p -r1.157.2.38 parser.c
*** cp/parser.c 12 Aug 2004 10:29:23 -0000 1.157.2.38
--- cp/parser.c 14 Sep 2004 16:09:04 -0000
*************** cp_parser_id_expression (cp_parser *pars
*** 2699,2709 ****
nested_name_specifier_p
= (cp_parser_nested_name_specifier_opt (parser,
/*typename_keyword_p=*/false,
check_dependency_p,
/*type_p=*/false,
! /*is_declarator=*/false)
!= NULL_TREE);
/* If there is a nested-name-specifier, then we are looking at
the first qualified-id production. */
if (nested_name_specifier_p)
{
--- 2699,2709 ----
nested_name_specifier_p
= (cp_parser_nested_name_specifier_opt (parser,
/*typename_keyword_p=*/false,
check_dependency_p,
/*type_p=*/false,
! declarator_p)
!= NULL_TREE);
/* If there is a nested-name-specifier, then we are looking at
the first qualified-id production. */
if (nested_name_specifier_p)
{
*************** cp_parser_nested_name_specifier_opt (cp_
*** 3139,3148 ****
--- 3139,3156 ----
/* Save the old scope since the name lookup we are about to do
might destroy it. */
old_scope = parser->scope;
saved_qualifying_scope = parser->qualifying_scope;
+ /* In a declarator-id like "X<T>::I::Y<T>" we must be able to
+ look up names in "X<T>::I" in order to determine that "Y" is
+ a template. So, if we have a typename at this point, we make
+ an effort to look through it. */
+ if (is_declaration && parser->scope
+ && TREE_CODE (parser->scope) == TYPENAME_TYPE)
+ parser->scope = resolve_typename_type (parser->scope,
+ /*only_current_p=*/false);
/* Parse the qualifying entity. */
new_scope
= cp_parser_class_or_namespace_name (parser,
typename_keyword_p,
template_keyword_p,
*************** cp_parser_template_name (cp_parser* pars
*** 8093,8102 ****
--- 8101,8111 ----
we want to treat "X<int>" as a template-id. */
if (is_declaration
&& !template_keyword_p
&& parser->scope && TYPE_P (parser->scope)
+ && check_dependency_p
&& dependent_type_p (parser->scope)
/* Do not do this for dtors (or ctors), since they never
need the template keyword before their name. */
&& !constructor_name_p (identifier, parser->scope))
{
Index: testsuite/g++.dg/template/decl2.C
===================================================================
RCS file: testsuite/g++.dg/template/decl2.C
diff -N testsuite/g++.dg/template/decl2.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/decl2.C 14 Sep 2004 16:09:04 -0000
***************
*** 0 ****
--- 1,13 ----
+ // PR c++/16162
+
+ template <int N> struct O {
+ struct I {
+ template <typename T> struct II {
+ void f();
+ };
+ };
+ };
+
+ template <int N>
+ template <typename T>
+ void O<N>::I::II<T>::f () {}
Index: testsuite/g++.dg/template/nested3.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/nested3.C,v
retrieving revision 1.2
diff -c -5 -p -r1.2 nested3.C
*** testsuite/g++.dg/template/nested3.C 1 Dec 2003 05:58:23 -0000 1.2
--- testsuite/g++.dg/template/nested3.C 14 Sep 2004 16:09:04 -0000
*************** class A {
*** 3,28 ****
template <class S>
class SubA {
int _k;
};
T1 _t1;
! T2 _t2; // { dg-error "instantiated" }
};
template <class U>
! class B { // { dg-error "" }
class SubB1 {
! B _i; // { dg-error "" }
};
class SubB2 {
int _j;
};
A<U,SubB1>::SubA<SubB2> _a; // { dg-error "" }
};
int main() {
! B<char> objB; // { dg-error "instantiated" }
return 0;
}
--- 3,28 ----
template <class S>
class SubA {
int _k;
};
T1 _t1;
! T2 _t2; // { dg-error "instantiated" "" { xfail *-*-* } }
};
template <class U>
! class B { // { dg-error "" "" { xfail *-*-* } }
class SubB1 {
! B _i; // { dg-error "" "" { xfail *-*-* } }
};
class SubB2 {
int _j;
};
A<U,SubB1>::SubA<SubB2> _a; // { dg-error "" }
};
int main() {
! B<char> objB; // { dg-error "instantiated" "" { xfail *-*-* } }
return 0;
}