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 16162


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;
  }


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