PATCH to warn on use of typename outside of templates
Mark Mitchell
mark@markmitchell.com
Fri Aug 28 12:06:00 GMT 1998
It's not legal to use `typename X::Y' outside of a template; this
patch causes a warning on such code.
It also reduces code duplication in the parser.
--
Mark Mitchell mark@markmitchell.com
Mark Mitchell Consulting http://www.markmitchell.com
Index: testsuite/g++.old-deja/g++.pt/typename10.C
===================================================================
RCS file: typename10.C
diff -N typename10.C
*** /dev/null Mon Dec 31 20:00:00 1979
--- typename10.C Fri Aug 28 11:47:45 1998
***************
*** 0 ****
--- 1,7 ----
+ // Build don't link:
+
+ struct S {
+ typedef int I;
+ };
+
+ void f(typename S::I); // ERROR - using typename outside of template
Index: cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.120
diff -c -p -r1.120 cp-tree.h
*** cp-tree.h 1998/08/27 10:17:30 1.120
--- cp-tree.h 1998/08/28 18:52:02
*************** extern tree finish_member_class_template
*** 2978,2983 ****
--- 2978,2984 ----
extern void finish_template_decl PROTO((tree));
extern tree finish_template_type PROTO((tree, tree, int));
extern void enter_scope_of PROTO((tree));
+ extern tree finish_base_specifier PROTO((tree, tree, int));
/* in sig.c */
extern tree build_signature_pointer_type PROTO((tree, int, int));
Index: cp/parse.y
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/parse.y,v
retrieving revision 1.84
diff -c -p -r1.84 parse.y
*** parse.y 1998/08/27 10:17:37 1.84
--- parse.y 1998/08/28 18:53:34
*************** structsp:
*** 2090,2096 ****
$$.new_type_flag = 0; }
| TYPENAME_KEYWORD typename_sub
{ $$.t = $2;
! $$.new_type_flag = 0; }
/* C++ extensions, merged with C to avoid shift/reduce conflicts */
| class_head left_curly
opt.component_decl_list '}' maybe_attribute
--- 2090,2098 ----
$$.new_type_flag = 0; }
| TYPENAME_KEYWORD typename_sub
{ $$.t = $2;
! $$.new_type_flag = 0;
! if (!processing_template_decl)
! cp_pedwarn ("using `typename' outside of template"); }
/* C++ extensions, merged with C to avoid shift/reduce conflicts */
| class_head left_curly
opt.component_decl_list '}' maybe_attribute
*************** base_class_list:
*** 2251,2321 ****
base_class:
base_class.1
! {
! tree type;
! if ($1 == NULL_TREE)
! {
! error ("invalid base class");
! type = error_mark_node;
! }
! else
! type = TREE_TYPE ($1);
! if (! is_aggr_type (type, 1))
! $$ = NULL_TREE;
! else if (current_aggr == signature_type_node
! && (! type) && (! IS_SIGNATURE (type)))
! {
! error ("class name not allowed as base signature");
! $$ = NULL_TREE;
! }
! else if (current_aggr == signature_type_node)
! {
! sorry ("signature inheritance, base type `%s' ignored",
! IDENTIFIER_POINTER ($$));
! $$ = build_tree_list (access_public_node, type);
! }
! else if (type && IS_SIGNATURE (type))
! {
! error ("signature name not allowed as base class");
! $$ = NULL_TREE;
! }
! else
! $$ = build_tree_list (access_default_node, type);
! }
| base_class_access_list see_typename base_class.1
! {
! tree type;
! if ($3 == NULL_TREE)
! {
! error ("invalid base class");
! type = error_mark_node;
! }
! else
! type = TREE_TYPE ($3);
! if (current_aggr == signature_type_node)
! error ("access and source specifiers not allowed in signature");
! if (! is_aggr_type (type, 1))
! $$ = NULL_TREE;
! else if (current_aggr == signature_type_node
! && (! type) && (! IS_SIGNATURE (type)))
! {
! error ("class name not allowed as base signature");
! $$ = NULL_TREE;
! }
! else if (current_aggr == signature_type_node)
! {
! sorry ("signature inheritance, base type `%s' ignored",
! IDENTIFIER_POINTER ($$));
! $$ = build_tree_list (access_public_node, type);
! }
! else if (type && IS_SIGNATURE (type))
! {
! error ("signature name not allowed as base class");
! $$ = NULL_TREE;
! }
! else
! $$ = build_tree_list ($$, type);
! }
;
base_class.1:
--- 2253,2265 ----
base_class:
base_class.1
! { $$ = finish_base_specifier (access_default_node, $1,
! current_aggr
! == signature_type_node); }
| base_class_access_list see_typename base_class.1
! { $$ = finish_base_specifier ($1, $3,
! current_aggr
! == signature_type_node); }
;
base_class.1:
Index: cp/semantics.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/semantics.c,v
retrieving revision 1.23
diff -c -p -r1.23 semantics.c
*** semantics.c 1998/08/17 22:33:58 1.23
--- semantics.c 1998/08/28 18:54:12
*************** enter_scope_of (sr)
*** 1448,1450 ****
--- 1448,1500 ----
TREE_COMPLEXITY (sr) = current_class_depth;
}
}
+
+ /* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER.
+ Return a TREE_LIST containing the ACCESS_SPECIFIER and the
+ BASE_CLASS, or NULL_TREE if an error occurred. The
+ ACCESSS_SPECIFIER is one of
+ access_{default,public,protected_private}[_virtual]_node.*/
+
+ tree
+ finish_base_specifier (access_specifier, base_class,
+ current_aggr_is_signature)
+ tree access_specifier;
+ tree base_class;
+ int current_aggr_is_signature;
+ {
+ tree type;
+ tree result;
+
+ if (base_class == NULL_TREE)
+ {
+ error ("invalid base class");
+ type = error_mark_node;
+ }
+ else
+ type = TREE_TYPE (base_class);
+ if (current_aggr_is_signature && access_specifier)
+ error ("access and source specifiers not allowed in signature");
+ if (! is_aggr_type (type, 1))
+ result = NULL_TREE;
+ else if (current_aggr_is_signature
+ && (! type) && (! IS_SIGNATURE (type)))
+ {
+ error ("class name not allowed as base signature");
+ result = NULL_TREE;
+ }
+ else if (current_aggr_is_signature)
+ {
+ sorry ("signature inheritance, base type `%s' ignored",
+ IDENTIFIER_POINTER (access_specifier));
+ result = build_tree_list (access_public_node, type);
+ }
+ else if (type && IS_SIGNATURE (type))
+ {
+ error ("signature name not allowed as base class");
+ result = NULL_TREE;
+ }
+ else
+ result = build_tree_list (access_specifier, type);
+
+ return result;
+ }
More information about the Gcc-bugs
mailing list