|
|
727081 |
2003-07-10 Mark Mitchell <mark@codesourcery.com>
|
|
|
727081 |
|
|
|
727081 |
PR c++/10558
|
|
|
727081 |
* parse.y (class_template_ok_as_expr): New variable.
|
|
|
727081 |
(template_arg_1): New non-terminal.
|
|
|
727081 |
(primary): Issue errors about uses of class templates as
|
|
|
727081 |
expressions.
|
|
|
727081 |
|
|
|
727081 |
* g++.dg/parse/template8.C: New test.
|
|
|
727081 |
|
|
|
727081 |
--- gcc/cp/parse.y 10 Jul 2003 12:43:11 -0000 1.284.2.7
|
|
|
727081 |
+++ gcc/cp/parse.y 11 Jul 2003 08:39:55 -0000 1.284.2.8
|
|
|
727081 |
@@ -53,6 +53,8 @@ extern struct obstack permanent_obstack;
|
|
|
727081 |
/* Like YYERROR but do call yyerror. */
|
|
|
727081 |
#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
|
|
|
727081 |
|
|
|
727081 |
+static int class_template_ok_as_expr;
|
|
|
727081 |
+
|
|
|
727081 |
#define OP0(NODE) (TREE_OPERAND (NODE, 0))
|
|
|
727081 |
#define OP1(NODE) (TREE_OPERAND (NODE, 1))
|
|
|
727081 |
|
|
|
727081 |
@@ -422,7 +424,7 @@ cp_parse_init ()
|
|
|
727081 |
%type template_close_bracket
|
|
|
727081 |
%type <ttype> apparent_template_type
|
|
|
727081 |
%type <ttype> template_type template_arg_list template_arg_list_opt
|
|
|
727081 |
-%type <ttype> template_arg
|
|
|
727081 |
+%type <ttype> template_arg template_arg_1
|
|
|
727081 |
%type <ttype> condition xcond paren_cond_or_null
|
|
|
727081 |
%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
|
|
|
727081 |
%type <ttype> complete_type_name notype_identifier nonnested_type
|
|
|
727081 |
@@ -1108,7 +1110,7 @@ template_close_bracket:
|
|
|
727081 |
template_arg_list_opt:
|
|
|
727081 |
/* empty */
|
|
|
727081 |
{ $$ = NULL_TREE; }
|
|
|
727081 |
- | template_arg_list
|
|
|
727081 |
+ | template_arg_list
|
|
|
727081 |
;
|
|
|
727081 |
|
|
|
727081 |
template_arg_list:
|
|
|
727081 |
@@ -1119,6 +1121,15 @@ template_arg_list:
|
|
|
727081 |
;
|
|
|
727081 |
|
|
|
727081 |
template_arg:
|
|
|
727081 |
+ { ++class_template_ok_as_expr; }
|
|
|
727081 |
+ template_arg_1
|
|
|
727081 |
+ {
|
|
|
727081 |
+ --class_template_ok_as_expr;
|
|
|
727081 |
+ $$ = $2;
|
|
|
727081 |
+ }
|
|
|
727081 |
+ ;
|
|
|
727081 |
+
|
|
|
727081 |
+template_arg_1:
|
|
|
727081 |
type_id
|
|
|
727081 |
{ $$ = groktypename ($1.t); }
|
|
|
727081 |
| PTYPENAME
|
|
|
727081 |
@@ -1695,7 +1706,14 @@ primary:
|
|
|
727081 |
$$ = $2;
|
|
|
727081 |
}
|
|
|
727081 |
| overqualified_id %prec HYPERUNARY
|
|
|
727081 |
- { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
|
|
|
727081 |
+ { $$ = build_offset_ref (OP0 ($$), OP1 ($$));
|
|
|
727081 |
+ if (!class_template_ok_as_expr
|
|
|
727081 |
+ && DECL_CLASS_TEMPLATE_P ($$))
|
|
|
727081 |
+ {
|
|
|
727081 |
+ error ("invalid use of template `%D'", $$);
|
|
|
727081 |
+ $$ = error_mark_node;
|
|
|
727081 |
+ }
|
|
|
727081 |
+ }
|
|
|
727081 |
| overqualified_id '(' nonnull_exprlist ')'
|
|
|
727081 |
{ $$ = finish_qualified_call_expr ($1, $3); }
|
|
|
727081 |
| overqualified_id LEFT_RIGHT
|
|
|
727081 |
--- gcc/testsuite/g++.dg/parse/template8.C 2005-01-27 14:27:08.338732320 +0100
|
|
|
727081 |
+++ gcc/testsuite/g++.dg/parse/template8.C 2003-07-16 18:05:35.000000000 +0200
|
|
|
727081 |
@@ -0,0 +1,16 @@
|
|
|
727081 |
+namespace N
|
|
|
727081 |
+{
|
|
|
727081 |
+
|
|
|
727081 |
+template <typename> struct A
|
|
|
727081 |
+{
|
|
|
727081 |
+ template <typename T> A(A<T>);
|
|
|
727081 |
+};
|
|
|
727081 |
+
|
|
|
727081 |
+}
|
|
|
727081 |
+
|
|
|
727081 |
+void foo(N::A<int>);
|
|
|
727081 |
+
|
|
|
727081 |
+void bar()
|
|
|
727081 |
+{
|
|
|
727081 |
+ foo(N::A); // { dg-error "" }
|
|
|
727081 |
+}
|