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 10558


This patch fixes PR 10558 in the old parser by complaining about uses
of class templates as expressions.

Tested on i686-pc-linux-gnu, applied on the branch.  (Although I will
add the testcase to the mainline as well.)

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-07-10  Mark Mitchell  <mark@codesourcery.com>

	PR c++/10558
	* parse.y (class_template_ok_as_expr): New variable.
	(template_arg_1): New non-terminal.
	(primary): Issue errors about uses of class templates as
	expressions.

2003-07-11  Mark Mitchell  <mark@codesourcery.com>

	PR c++/10558
	* g++.dg/parse/template8.C: New test.

Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Attic/parse.y,v
retrieving revision 1.284.2.7
diff -c -5 -p -r1.284.2.7 parse.y
*** cp/parse.y	10 Jul 2003 12:43:11 -0000	1.284.2.7
--- cp/parse.y	11 Jul 2003 08:38:59 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 54,63 ****
--- 54,64 ----
     give malloced_yyvs its proper type.  This is ok since all we need from
     it is to be able to free it.  */
  
  static short *malloced_yyss;
  static void *malloced_yyvs;
+ static int class_template_ok_as_expr;
  
  #define yyoverflow(MSG, SS, SSSIZE, VS, VSSIZE, YYSSZ)			\
  do {									\
    size_t newsize;							\
    short *newss;								\
*************** check_class_key (key, aggr)
*** 447,457 ****
  %type <ttype> template_parm_list template_parm
  %type <ttype> template_type_parm template_template_parm
  %type <code>  template_close_bracket
  %type <ttype> apparent_template_type
  %type <ttype> template_type template_arg_list template_arg_list_opt
! %type <ttype> template_arg
  %type <ttype> condition xcond paren_cond_or_null
  %type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
  %type <ttype> complete_type_name notype_identifier nonnested_type
  %type <ttype> complex_type_name nested_name_specifier_1
  %type <ttype> new_initializer new_placement
--- 448,458 ----
  %type <ttype> template_parm_list template_parm
  %type <ttype> template_type_parm template_template_parm
  %type <code>  template_close_bracket
  %type <ttype> apparent_template_type
  %type <ttype> template_type template_arg_list template_arg_list_opt
! %type <ttype> template_arg template_arg_1
  %type <ttype> condition xcond paren_cond_or_null
  %type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
  %type <ttype> complete_type_name notype_identifier nonnested_type
  %type <ttype> complex_type_name nested_name_specifier_1
  %type <ttype> new_initializer new_placement
*************** template_close_bracket:
*** 1119,1139 ****
  	;
  
  template_arg_list_opt:
           /* empty */
                   { $$ = NULL_TREE; }
!        | template_arg_list
         ;
  
  template_arg_list:
          template_arg
  		{ $$ = build_tree_list (NULL_TREE, $$); }
  	| template_arg_list ',' template_arg
  		{ $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); }
  	;
  
  template_arg:
  	  type_id
  		{ $$ = groktypename ($1.t); }
  	| PTYPENAME
  		{
  		  $$ = lastiddecl;
--- 1120,1149 ----
  	;
  
  template_arg_list_opt:
           /* empty */
                   { $$ = NULL_TREE; }
!        | template_arg_list 
         ;
  
  template_arg_list:
          template_arg
  		{ $$ = build_tree_list (NULL_TREE, $$); }
  	| template_arg_list ',' template_arg
  		{ $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); }
  	;
  
  template_arg:
+                 { ++class_template_ok_as_expr; }
+         template_arg_1 
+                 { 
+ 		  --class_template_ok_as_expr; 
+ 		  $$ = $2; 
+ 		}
+         ;
+ 
+ template_arg_1:
  	  type_id
  		{ $$ = groktypename ($1.t); }
  	| PTYPENAME
  		{
  		  $$ = lastiddecl;
*************** primary:
*** 1702,1712 ****
  		    $$ = parse_scoped_id ($2);
  		  else
  		    $$ = $2;
  		}
  	| overqualified_id  %prec HYPERUNARY
! 		{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
  	| overqualified_id '(' nonnull_exprlist ')'
                  { $$ = parse_finish_call_expr ($1, $3, 0); }
  	| overqualified_id LEFT_RIGHT
  		{ $$ = parse_finish_call_expr ($1, NULL_TREE, 0); }
          | object object_template_id %prec UNARY
--- 1712,1729 ----
  		    $$ = parse_scoped_id ($2);
  		  else
  		    $$ = $2;
  		}
  	| overqualified_id  %prec HYPERUNARY
! 		{ $$ = build_offset_ref (OP0 ($$), OP1 ($$));
! 		  if (!class_template_ok_as_expr 
! 		      && DECL_CLASS_TEMPLATE_P ($$))
! 		    {
! 		      error ("invalid use of template `%D'", $$); 
! 		      $$ = error_mark_node;
! 		    }
!                 }
  	| overqualified_id '(' nonnull_exprlist ')'
                  { $$ = parse_finish_call_expr ($1, $3, 0); }
  	| overqualified_id LEFT_RIGHT
  		{ $$ = parse_finish_call_expr ($1, NULL_TREE, 0); }
          | object object_template_id %prec UNARY
Index: testsuite/g++.dg/parse/template8.C
===================================================================
RCS file: testsuite/g++.dg/parse/template8.C
diff -N testsuite/g++.dg/parse/template8.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/template8.C	11 Jul 2003 08:28:12 -0000
***************
*** 0 ****
--- 1,16 ----
+ namespace N
+ {
+ 
+ template <typename> struct A
+ {
+   template <typename T> A(A<T>);
+ };
+ 
+ }
+ 
+ void foo(N::A<int>);
+ 
+ void bar()
+ {
+   foo(N::A); // { dg-error "" }
+ }


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