Blob Blame History Raw
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.

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

--- gcc/cp/parse.y	10 Jul 2003 12:43:11 -0000	1.284.2.7
+++ gcc/cp/parse.y	11 Jul 2003 08:39:55 -0000	1.284.2.8
@@ -53,6 +53,8 @@ extern struct obstack permanent_obstack;
 /* Like YYERROR but do call yyerror.  */
 #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
 
+static int class_template_ok_as_expr;
+
 #define OP0(NODE) (TREE_OPERAND (NODE, 0))
 #define OP1(NODE) (TREE_OPERAND (NODE, 1))
 
@@ -422,7 +424,7 @@ cp_parse_init ()
 %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> 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
@@ -1108,7 +1110,7 @@ template_close_bracket:
 template_arg_list_opt:
          /* empty */
                  { $$ = NULL_TREE; }
-       | template_arg_list
+       | template_arg_list 
        ;
 
 template_arg_list:
@@ -1119,6 +1121,15 @@ template_arg_list:
 	;
 
 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
@@ -1695,7 +1706,14 @@ primary:
 		    $$ = $2;
 		}
 	| overqualified_id  %prec HYPERUNARY
-		{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
+		{ $$ = 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 ')'
                 { $$ = finish_qualified_call_expr ($1, $3); }
 	| overqualified_id LEFT_RIGHT
--- gcc/testsuite/g++.dg/parse/template8.C	2005-01-27 14:27:08.338732320 +0100
+++ gcc/testsuite/g++.dg/parse/template8.C	2003-07-16 18:05:35.000000000 +0200
@@ -0,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 "" }
+}