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]

971114 PATCH: check for non-aggregates used as base classes


The 971114 "gcc/cp/parse.y" doesn't properly identify non-aggregate
types used as base classes.

First, the rule:

	base_class: base_class_access_list see_typename base_class.1

uses "IS_AGGR_TYPE" instead of "is_aggr_type" to check "base_class.1",
so no error is reported for code like:

	typedef int an_int;
	class bar : public an_int {};

The base class is silently ignored.  Without the "public" access
specifier, the "base_class: base_class.1" rule is used, so an error
*is* correctly reported.  The enclosed patch fixes the problem by
using "is_aggr_type" to report the error.

Second, it's possible for a "typename_sub" to be associated with a
non-aggregate type.  Several rules do unchecked "TYPE_MAIN_DECL"s on
"typename_sub"s, which would be NULL for, say, an "INTEGER_TYPE",
causing an internal compiler error:

	class foo {
		typedef int an_int;
	};
	class bar : foo::an_int {};  // causes internal compiler error

or, in other cases, some very strange semantics:

	#include <iostream.h>
	struct foo {
		foo(int x) { cerr << "foo's int constructor (" << x << ")\n"; };
	};
	struct bar : foo {
		typedef int an_int;
		bar() : bar::an_int(3) {};  // will call foo::foo(3)
	};
	main() { bar b; }

There was one use of "typename_sub", namely the rule:

	structsp: TYPENAME_KEYWORD typename_sub

that I didn't understand.  Would a non-aggregate type be valid here?
If not, then "typename_sub" always needs to be aggregate, so a single
check could be made in the "typename_sub" rule.  In the enclosed
patch, I instead explicitly checked all the other uses of
"typename_sub" using "is_aggr_type".

Comparing "make g++-check" before and after the patch, there were no
changes, so it hopefully doesn't break anything else.

Kevin <buhr@stat.wisc.edu>

			*	*	*

*** egcs-971114/gcc/cp/parse.y.orig	Fri Nov 21 12:57:06 1997
--- egcs-971114/gcc/cp/parse.y	Thu Nov 20 17:40:25 1997
***************
*** 820,830 ****
  	| nonnested_type LEFT_RIGHT
  		{ expand_member_init (current_class_ref, $1, void_type_node); }
  	| typename_sub '(' nonnull_exprlist ')'
! 		{ expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1),
! 				      $3); }
  	| typename_sub LEFT_RIGHT
! 		{ expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1),
! 				      void_type_node); }
  	;
  
  identifier:
--- 820,832 ----
  	| nonnested_type LEFT_RIGHT
  		{ expand_member_init (current_class_ref, $1, void_type_node); }
  	| typename_sub '(' nonnull_exprlist ')'
! 		{ if (is_aggr_type ($1, 1))
! 		    expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1),
! 					$3); }
  	| typename_sub LEFT_RIGHT
! 		{ if (is_aggr_type ($1, 1))
! 		    expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1),
! 					void_type_node); }
  	;
  
  identifier:
***************
*** 2476,2482 ****
  		  tree type = TREE_TYPE ($3);
  		  if (current_aggr == signature_type_node)
  		    error ("access and source specifiers not allowed in signature");
! 		  if (! IS_AGGR_TYPE (type))
  		    $$ = NULL_TREE;
  		  else if (current_aggr == signature_type_node
  			   && (! type) && (! IS_SIGNATURE (type)))
--- 2478,2484 ----
  		  tree 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)))
***************
*** 2502,2508 ****
  
  base_class.1:
  	  typename_sub
! 		{ $$ = TYPE_MAIN_DECL ($1); }
  	| nonnested_type
  	| SIGOF '(' expr ')'
  		{
--- 2504,2515 ----
  
  base_class.1:
  	  typename_sub
! 		{ 
! 		  if (! is_aggr_type ($1, 1))
! 		    $$ = NULL_TREE;
! 		  else
! 		    $$ = TYPE_MAIN_DECL ($1); 
! 		}
  	| nonnested_type
  	| SIGOF '(' expr ')'
  		{


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