This is the mail archive of the gcc@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]

Hi, I did some code spelunking to find the -fall-virtual problem.


I wrote previously about a problem with -fall-virtual.
The problem was that for even a simple program the -fall-virtual
gives an internal compiler error.

It seems like the tree node does not get initialised as
a virtual function when flag_all_virtual is set. This results in a
segfault when the add_virtual_function is called (due to
flag_all_virtual) and the proper initialisation has not been done.
(More exactly it seems to be DECL_VINDEX that is null.)

I am a total novice when it comes to the gcc compiler, so please
correct me if I am wrong. But with the belief that -fall-virtual
would do the same as if I had written virtual in front of every
possible virtual function I went ahead a changed the decl.c file.

I wanted every function to be considered virtual (if
flag_all_virtual was set) unless it was impossible to add virtual to
it. So in grokdeclarator in decl.c I added
int tryvirtualp = flag_all_virtual;
And then at each point where a virtual conflict is checked the new
code looks like this:
  if ((virtualp || tryvirtualp) && staticp == 2)
    {
      if (virtualp)
      {
        cp_error ("member `%D' cannot be declared both virtual and
                  static",
                  dname);
        staticp = 0;
      }
      tryvirtualp=0;
    }

If any conflict is found and the programmer has not really asked for
virtual. We reset tryvirtualp to 0.

Later at the three places where grokfndecl is used. I check how the
virtual stuff is checking out before calling grokfndecl.

   if (tryvirtualp) virtualp = tryvirtualp;
   decl = grokfndecl (ctype, type,
                      TREE_CODE (declarator) != TEMPLATE_ID_EXPR
                       ? declarator : dname,
                       declarator,
                       virtualp, flags, quals, raises,attrlist,
                       friendp ? -1 : 0, friendp, publicp,inlinep,
                       funcdef_flag, template_count,in_namespace);

Well, now a very simple program like:
-Code------------
class A {
 int hi () { return 1; }
};
class B : public A
{
 int hi () { return 0; }
};
int main ()
{
  A *a = new B;
  return a->hi();
}
-Run like this-----
a.out ; echo $?
-------------------

does what it is intended to do. Prints 0 when compiled with
-fall-virtual and 1 when not.

But when I include iostream there is an internal Compiler error at
line 260 in streambuf.h.

Before I continue to look for this problem I would like to know if I
am hopelessly on the wrong track! :-)

Is my interpretation of -fall-virtual correct?
Is the general idea to fix the egcs code correct?

Best regards
Fredrik Ohrstrom

(The changes are appended as diffs versus the cvs 30/7.)


8029c8029
<   int virtualp, explicitp, friendp, inlinep, staticp;
---
>   int virtualp, tryvirtualp, explicitp, friendp, inlinep, staticp;
8719a8720
>   tryvirtualp = flag_all_virtual;
8727c8728,8730
<   if (virtualp && staticp == 2)
---
>   printf ("INLINEP=%d\n", inlinep);
>   
>   if ((virtualp || tryvirtualp) && staticp == 2)
8729,8731c8732,8738
<       cp_error ("member `%D' cannot be declared both virtual and static",
< 		dname);
<       staticp = 0;
---
>       if (virtualp)
>       {
> 	cp_error ("member `%D' cannot be declared both virtual and static",
> 		  dname);
> 	staticp = 0;
>       }
>       tryvirtualp=0;
8769c8776
<   if (virtualp
---
>   if ((virtualp || tryvirtualp)
8772,8773c8779,8784
<       error ("virtual outside class declaration");
<       virtualp = 0;
---
>       if (virtualp)
>       {
> 	error ("virtual outside class declaration");
> 	virtualp = 0;
>       }
>       tryvirtualp = 0;
8815c8826
<       if (virtualp)
---
>       if (virtualp || tryvirtualp)
8817,8820c8828,8835
< 	  error ("`virtual' specified for signature member function `%s'",
< 		 name);
< 	  /* Later, we'll make signature member functions virtual.  */
< 	  virtualp = 0;
---
> 	  if (virtualp)
> 	    {
> 	      error ("`virtual' specified for signature member function `%s'",
> 		     name);
> 	      /* Later, we'll make signature member functions virtual.  */
> 	      virtualp = 0;
> 	    }
> 	  tryvirtualp = 0;
9226c9241
< 		    if (virtualp)
---
> 		    if (virtualp || tryvirtualp)
9228,9229c9243,9248
< 			pedwarn ("constructors cannot be declared virtual");
< 			virtualp = 0;
---
> 			if (virtualp)
> 			  {
> 			    pedwarn ("constructors cannot be declared virtual");
> 			    virtualp = 0;
> 			  }
> 			tryvirtualp = 0;
9268c9287
< 		if (virtualp)
---
> 		if (virtualp || tryvirtualp)
9271,9273c9290,9296
< 		    error ("virtual functions cannot be friends");
< 		    RIDBIT_RESET (RID_FRIEND, specbits);
< 		    friendp = 0;
---
> 		    if (virtualp)
> 		      {
> 			error ("virtual functions cannot be friends");
> 			RIDBIT_RESET (RID_FRIEND, specbits);
> 			friendp = 0;
> 		      }
> 		    tryvirtualp = 0;
9950c9973
< 		if (virtualp && TREE_CODE (ctype) == UNION_TYPE)
---
> 		if ((virtualp || tryvirtualp) && TREE_CODE (ctype) == UNION_TYPE)
9952,9954c9975,9981
< 		    cp_error ("function `%D' declared virtual inside a union",
< 			      declarator);
< 		    return void_type_node;
---
> 		    if (virtualp)
> 		    {
> 		      cp_error ("function `%D' declared virtual inside a union",
> 				declarator);
> 		      return void_type_node;
> 		    }
> 		    tryvirtualp = 0;
9962c9989
< 		    if (virtualp)
---
> 		    if (virtualp || tryvirtualp)
9964,9966c9991,9997
< 			cp_error ("`%D' cannot be declared virtual, since it is always static",
< 				  declarator);
< 			virtualp = 0;
---
> 			if (virtualp)
> 			  {
> 			    cp_error ("`%D' cannot be declared virtual, since it is always static",
> 				      declarator);
> 			    virtualp = 0;
> 			  }
> 			tryvirtualp = 0;
9978a10010,10013
> 	    if (tryvirtualp) puts ("Tryvirtualp");
> 	    if (virtualp) puts ("Virtualp");
> 	    puts ("-----");
> 	    if (tryvirtualp) virtualp = tryvirtualp;
10002a10038,10041
> 	    if (tryvirtualp) puts ("Tryvirtualp");
> 	    if (virtualp) puts ("Virtualp");
> 	    puts ("-----");
> 	    if (tryvirtualp) virtualp = tryvirtualp;
10172c10211
< 	    if (virtualp)
---
> 	    if (virtualp || tryvirtualp)
10174,10175c10213,10218
< 		error ("virtual non-class function `%s'", name);
< 		virtualp = 0;
---
> 		if (virtualp)
> 		  {
> 		    error ("virtual non-class function `%s'", name);
> 		    virtualp = 0;
> 		  }
> 		tryvirtualp = 0;
10198a10242,10245
> 	if (tryvirtualp) puts ("Tryvirtualp");
> 	if (virtualp) puts ("Virtualp");
> 	puts ("-----");
> 	if (tryvirtualp) virtualp = tryvirtualp;

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