2003-07-10 Mark Mitchell 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 template_close_bracket %type apparent_template_type %type template_type template_arg_list template_arg_list_opt -%type template_arg +%type template_arg template_arg_1 %type condition xcond paren_cond_or_null %type type_name nested_name_specifier nested_type ptr_to_mem %type 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 struct A +{ + template A(A); +}; + +} + +void foo(N::A); + +void bar() +{ + foo(N::A); // { dg-error "" } +}