This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 10558
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 11 Jul 2003 01:39:17 -0700
- Subject: C++ PATCH: PR 10558
- Reply-to: mark at codesourcery dot com
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 "" }
+ }