This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH to warn on use of typename outside of templates



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;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]