This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Hi, I did some code spelunking to find the -fall-virtual problem.
- To: egcs at cygnus dot com
- Subject: Hi, I did some code spelunking to find the -fall-virtual problem.
- From: "Fredrik Öhrström" <fredrik dot ohrstrom at qvant dot com>
- Date: Tue, 30 Jun 1998 12:34:58 +0000
- Organization: Swedbank Markets
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;