From: mrs@cygnus.com (Mike Stump)
Subject: Re:  GCC 2.1: errors in cp-decl.c, cp-parse.y
Organization: GNUs Not Usenet
Distribution: gnu
Date: Wed, 8 Apr 1992 08:10:26 GMT

> From: gb@cs.purdue.edu (Gerald Baumgartner)
> Newsgroups: gnu.g++.bug
> Subject: GCC 2.1: errors in cp-decl.c, cp-parse.y
> Message-Id: <18352@ector.cs.purdue.edu>
> Date: 7 Apr 92 03:03:45 GMT
> Organization: Department of Computer Science, Purdue University

Thanks a lot for your report, it proved very useful.

Yes, the ifdefs should be ifs, and no, the *= shoud not be -=.
Yes, all the calls to finish_decl in cp-parse.y were wrong.

The below patch fixes the problem.  (Or something like it.)  It should
be fixed in the next version of gcc.

> There are some run-time errors in GCC 2.1, cp-decl.c, (detected with Saber-C).

> In cp-decl.c, line 578, there is the field declaration
> (in struct binding_level):

> 	#ifdef PARANOID
> 	    unsigned char depth;
> 	#endif

> And in line 711 (function pop_binding_level), the sign of this unsigned
> char is reversed:

> 	#ifdef PARANOID
> 	    level->depth *= -1;
> 	#endif

> What should that be, a substraction (level->depth -= 1;)?

> And shouldn't there be `#if PARANOID' instead of `#ifdef PARANOID'?
> In cp-tree.h, line 26, PARANOID is set to 0:

> 	#ifndef PARANOID
> 	#define PARANOID 0
> 	#endif

> There is a more serious error with the use of finish_decl (cp-decl.c,
> line 5068).  The function is supposed to be passed four parameters.
> The fourth parameter, `need_pop', tells whether obstacks should be
> popped.  In ALL the calls to finish_decl from cp-parse.y, only three
> parameters are passed.

--------------
Doing diffs in .:
*** ./cp-decl.c.~1~	Thu Apr  2 13:37:41 1992
--- ./cp-decl.c	Wed Apr  8 00:51:44 1992
***************
*** 587,593 ****
  
      /* Three bits left for this word.  */
  
! #ifdef PARANOID
      unsigned char depth;
  #endif
    };
--- 587,593 ----
  
      /* Three bits left for this word.  */
  
! #if PARANOID
      unsigned char depth;
  #endif
    };
***************
*** 690,696 ****
    newlevel->more_cleanups_ok = 1;
    newlevel->more_exceptions_ok = 1;
    newlevel->keep = keep;
! #ifdef PARANOID
    newlevel->depth = (newlevel->level_chain
  		     ? newlevel->level_chain->depth + 1
  		     : 0);
--- 690,696 ----
    newlevel->more_cleanups_ok = 1;
    newlevel->more_exceptions_ok = 1;
    newlevel->keep = keep;
! #if PARANOID
    newlevel->depth = (newlevel->level_chain
  		     ? newlevel->level_chain->depth + 1
  		     : 0);
***************
*** 720,727 ****
      memset (level, 0x69, sizeof (*level));
  #else
      free_binding_level = level;
! #ifdef PARANOID
!     level->depth *= -1;
  #endif
  #endif
      if (current_binding_level->parm_flag == 2)
--- 720,727 ----
      memset (level, 0x69, sizeof (*level));
  #else
      free_binding_level = level;
! #if PARANOID
!     level->depth = ~0;	/* ~0 assumes that the depth is unsigned. */
  #endif
  #endif
      if (current_binding_level->parm_flag == 2)
***************
*** 5113,5119 ****
     the normal rules.
  
     For functions that take default parameters, DECL points to its
!    "maximal" instantiation.  finish_decl must then also declared its
     subsequently lower and lower forms of instantiation, checking for
     ambiguity as it goes.  This can be sped up later.  */
  
--- 5113,5119 ----
     the normal rules.
  
     For functions that take default parameters, DECL points to its
!    "maximal" instantiation.  `finish_decl' must then also declared its
     subsequently lower and lower forms of instantiation, checking for
     ambiguity as it goes.  This can be sped up later.  */
  
*** ./cp-parse.y.~1~	Thu Apr  2 13:37:59 1992
--- ./cp-parse.y	Wed Apr  8 00:55:31 1992
***************
*** 447,453 ****
  		  int momentary;
  		  momentary = suspend_momentary ();
  		  d = start_decl ($2, /*current_declspecs*/0, 0, $3);
! 		  finish_decl (d, NULL_TREE, $4);
  
  #if 0 /* Need to sort out destructor templates, and not give warnings
           for them.  */
--- 447,453 ----
  		  int momentary;
  		  momentary = suspend_momentary ();
  		  d = start_decl ($2, /*current_declspecs*/0, 0, $3);
! 		  finish_decl (d, NULL_TREE, $4, 0);
  
  #if 0 /* Need to sort out destructor templates, and not give warnings
           for them.  */
***************
*** 471,477 ****
  		  current_declspecs = $2;
  		  momentary = suspend_momentary ();
  		  d = start_decl ($3, current_declspecs, 0, $4);
! 		  finish_decl (d, NULL_TREE, $5);
  		  end_exception_decls ();
  		  end_template_decl ($1, d, 0);
  		  if ($7 != ';')
--- 471,477 ----
  		  current_declspecs = $2;
  		  momentary = suspend_momentary ();
  		  d = start_decl ($3, current_declspecs, 0, $4);
! 		  finish_decl (d, NULL_TREE, $5, 0);
  		  end_exception_decls ();
  		  end_template_decl ($1, d, 0);
  		  if ($7 != ';')
***************
*** 485,491 ****
  	| template_header declmods declarator fn_tmpl_end
  		{
  		  tree d = start_decl ($3, $<ttype>2, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE);
  		  end_template_decl ($1, d, 0);
  		  if ($4 != ';')
  		    reinit_parse_for_template ($4, $1, d);
--- 485,491 ----
  	| template_header declmods declarator fn_tmpl_end
  		{
  		  tree d = start_decl ($3, $<ttype>2, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE, 0);
  		  end_template_decl ($1, d, 0);
  		  if ($4 != ';')
  		    reinit_parse_for_template ($4, $1, d);
***************
*** 514,520 ****
  	| declmods declarator ';'
  		{ tree d;
  		  d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE);
  		}
  	| typed_declspecs initdecls ';'
  		{
--- 514,520 ----
  	| declmods declarator ';'
  		{ tree d;
  		  d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE, 0);
  		}
  	| typed_declspecs initdecls ';'
  		{
***************
*** 525,531 ****
  	| typed_declspecs declarator ';'
  		{ tree d;
  		  d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE);
  		  end_exception_decls ();
  		  note_list_got_semicolon ($<ttype>$);
  		}
--- 525,531 ----
  	| typed_declspecs declarator ';'
  		{ tree d;
  		  d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE, 0);
  		  end_exception_decls ();
  		  note_list_got_semicolon ($<ttype>$);
  		}
***************
*** 1598,1604 ****
  		{ tree d;
  		  int yes = suspend_momentary ();
  		  d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE);
  		  resume_momentary (yes);
  		  note_list_got_semicolon ($<ttype>$);
  		}
--- 1598,1604 ----
  		{ tree d;
  		  int yes = suspend_momentary ();
  		  d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE, 0);
  		  resume_momentary (yes);
  		  note_list_got_semicolon ($<ttype>$);
  		}
***************
*** 1609,1615 ****
  		{ tree d;
  		  int yes = suspend_momentary ();
  		  d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE);
  		  resume_momentary (yes);
  		}
  	| typed_declspecs ';'
--- 1609,1615 ----
  		{ tree d;
  		  int yes = suspend_momentary ();
  		  d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
! 		  finish_decl (d, NULL_TREE, NULL_TREE, 0);
  		  resume_momentary (yes);
  		}
  	| typed_declspecs ';'
***************
*** 1754,1760 ****
  		  $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>6, $7, $3);
  		  $$ = $<itype>5; }
  	| declarator maybe_raises maybeasm maybe_attribute
  		{ tree d;
--- 1754,1760 ----
  		  $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>6, $7, $3, 0);
  		  $$ = $<itype>5; }
  	| declarator maybe_raises maybeasm maybe_attribute
  		{ tree d;
***************
*** 1761,1767 ****
  		  current_declspecs = $<ttype>0;
  		  $$ = suspend_momentary ();
  		  d = start_decl ($1, current_declspecs, 0, $2);
! 		  finish_decl (d, NULL_TREE, $3); }
  	;
  
  initdcl:
--- 1761,1767 ----
  		  current_declspecs = $<ttype>0;
  		  $$ = suspend_momentary ();
  		  d = start_decl ($1, current_declspecs, 0, $2);
! 		  finish_decl (d, NULL_TREE, $3, 0); }
  	;
  
  initdcl:
***************
*** 1769,1778 ****
  		{ $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>6, $7, $3); }
  	| declarator maybe_raises maybeasm maybe_attribute
  		{ tree d = start_decl ($$, current_declspecs, 0, $2);
! 		  finish_decl (d, NULL_TREE, $3); }
  	;
  
  notype_initdcl0:
--- 1769,1778 ----
  		{ $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>6, $7, $3, 0); }
  	| declarator maybe_raises maybeasm maybe_attribute
  		{ tree d = start_decl ($$, current_declspecs, 0, $2);
! 		  finish_decl (d, NULL_TREE, $3, 0); }
  	;
  
  notype_initdcl0:
***************
*** 1782,1788 ****
  		  $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>6, $7, $3);
  		  $$ = $<itype>5; }
  	| notype_declarator maybe_raises maybeasm maybe_attribute
  		{ tree d;
--- 1782,1788 ----
  		  $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  	  init
  /* Note how the declaration of the variable is in effect while its init is parsed! */
! 		{ finish_decl ($<ttype>6, $7, $3, 0);
  		  $$ = $<itype>5; }
  	| notype_declarator maybe_raises maybeasm maybe_attribute
  		{ tree d;
***************
*** 1789,1795 ****
  		  current_declspecs = $<ttype>0;
  		  $$ = suspend_momentary ();
  		  d = start_decl ($1, current_declspecs, 0, $2);
! 		  finish_decl (d, NULL_TREE, $3); }
  	;
  
  /* the * rules are dummies to accept the Apollo extended syntax
--- 1789,1795 ----
  		  current_declspecs = $<ttype>0;
  		  $$ = suspend_momentary ();
  		  d = start_decl ($1, current_declspecs, 0, $2);
! 		  finish_decl (d, NULL_TREE, $3, 0); }
  	;
  
  /* the * rules are dummies to accept the Apollo extended syntax

Newsgroups: gnu.g++.bug