public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/47940] New: can call a pure virtual from a constructor/destructor
@ 2011-03-01 10:10 mlg7 at yandex dot ru
  2011-03-01 10:14 ` [Bug c++/47940] " pinskia at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: mlg7 at yandex dot ru @ 2011-03-01 10:10 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940

           Summary: can call a pure virtual from a constructor/destructor
           Product: gcc
           Version: 4.4.5
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: mlg7@yandex.ru


A colleague of mine have been examining a crash that
boils down to the following:
--hellobug.cpp--
class Base {
public:
    Base() { usefunc(); }
    virtual void func()=0;
    void usefunc() { func(); }
};

class Derived: public Base {
public:
    virtual void func() {}
};

int main() {
    Derived d;
    return 0;
}
--eof--

$ g++ -Wall -Wextra hellobug.cpp
{just nothing}
$ ./a.out 
pure virtual method called
terminate called without an active exception
Aborted

That is, "you asked for it, you got it" [1].
==
[1] from "Real Programmers Don't"
==

A variation:

==byebug.cpp==
#include <stdio.h>
class Base {
public:
    ~Base() { usefunc(); }
    virtual void func()=0;
    void usefunc() { func(); }
};

class Derived: public Base {
public:
    virtual void func() {}
};

int main() {
    Derived d;
    printf("life is good\n");
    return 0;
}
==eof==

$ g++ -Wall -Wextra byebug.cpp
{again nothing}
$ ./a.out 
life is good
pure virtual method called
terminate called without an active exception
Aborted


I have to note that in a big software project, 
the mistake is not so obvious.
But what can be done?


Functions that call pure virtual functions cannot
be called from constructors and destructors.
This may be discovered at compile-time, and the above
text makes a good error/warning message.



WHAT I GET: no warning
WHAT I WOULD EXPECT: a warning or an error message:
"Functions that call pure virtual functions cannot
be called from constructors and destructors"


$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.4.4-14ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.4 --enable-shared --enable-multiarch
--enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls
--with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc
--disable-werror --with-arch-32=i686 --with-tune=generic
--enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu
--target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/47940] can call a pure virtual from a constructor/destructor
  2011-03-01 10:10 [Bug c++/47940] New: can call a pure virtual from a constructor/destructor mlg7 at yandex dot ru
@ 2011-03-01 10:14 ` pinskia at gcc dot gnu.org
  2011-03-01 11:34 ` mlg7 at yandex dot ru
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2011-03-01 10:14 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> 2011-03-01 10:13:57 UTC ---
This is hard to detect really.  Basically what the function usefunc needs to
marked as calling a virtual function.  If the call was direct to func instead,
it would be better.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/47940] can call a pure virtual from a constructor/destructor
  2011-03-01 10:10 [Bug c++/47940] New: can call a pure virtual from a constructor/destructor mlg7 at yandex dot ru
  2011-03-01 10:14 ` [Bug c++/47940] " pinskia at gcc dot gnu.org
@ 2011-03-01 11:34 ` mlg7 at yandex dot ru
  2011-03-01 12:19 ` [Bug c++/47940] warn about calls to " redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: mlg7 at yandex dot ru @ 2011-03-01 11:34 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940

--- Comment #2 from mlg <mlg7 at yandex dot ru> 2011-03-01 11:34:30 UTC ---
Yes it _is_ hard to detect. My colleague was suspecting
a build system bug/feature at first (hours for a full rebuild).
If it was a direct call, there would be a linker error.

>If the call was direct to func instead,
>it would be better.

Unfortunately or fortunately, refactoring a huge 
real world application to make bugs easier 
for the compiler to detect is not an option.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/47940] warn about calls to a pure virtual from a constructor/destructor
  2011-03-01 10:10 [Bug c++/47940] New: can call a pure virtual from a constructor/destructor mlg7 at yandex dot ru
  2011-03-01 10:14 ` [Bug c++/47940] " pinskia at gcc dot gnu.org
  2011-03-01 11:34 ` mlg7 at yandex dot ru
@ 2011-03-01 12:19 ` redi at gcc dot gnu.org
  2011-03-01 12:30 ` redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2011-03-01 12:19 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic
            Summary|can call a pure virtual     |warn about calls to a pure
                   |from a                      |virtual from a
                   |constructor/destructor      |constructor/destructor

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-03-01 12:19:40 UTC ---
(In reply to comment #2)
> If it was a direct call, there would be a linker error.

Not if the pure virtual has a definition, and not with all compilers.
G++ does warn about that case though.

None of the compilers I tested issued a diagnostic about indirectly making a
virtual call to a pure virtual function.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/47940] warn about calls to a pure virtual from a constructor/destructor
  2011-03-01 10:10 [Bug c++/47940] New: can call a pure virtual from a constructor/destructor mlg7 at yandex dot ru
                   ` (2 preceding siblings ...)
  2011-03-01 12:19 ` [Bug c++/47940] warn about calls to " redi at gcc dot gnu.org
@ 2011-03-01 12:30 ` redi at gcc dot gnu.org
  2011-03-01 12:32 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2011-03-01 12:30 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-03-01 12:30:06 UTC ---
(In reply to comment #0)
> 
> Functions that call pure virtual functions cannot
> be called from constructors and destructors.
> This may be discovered at compile-time, and the above
> text makes a good error/warning message.

I'm not sure it makes a good diagnostic, consider:

struct abc {
  abc(bool nasal_demons) { if (nasal_demons) fly(); }
  void fly() { doFly(); }
  virtual void doFly() = 0;
};

Ideally the diagnostic for this would say "may call a pure virtual" for cases
where it can't be determined.

But then I don't really like the current diagnostic for direct calls either:

warning: abstract virtual 'virtual void abc::doFly()' called from constructor

I don't like the duplication of the word "virtual" and I don't like the term
"abstract virtual" - the class is abstract, the function is pure virtual.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/47940] warn about calls to a pure virtual from a constructor/destructor
  2011-03-01 10:10 [Bug c++/47940] New: can call a pure virtual from a constructor/destructor mlg7 at yandex dot ru
                   ` (3 preceding siblings ...)
  2011-03-01 12:30 ` redi at gcc dot gnu.org
@ 2011-03-01 12:32 ` redi at gcc dot gnu.org
  2011-03-01 17:23 ` mlg7 at yandex dot ru
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2011-03-01 12:32 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-03-01 12:32:19 UTC ---
(In reply to comment #4)
> "abstract virtual" - the class is abstract, the function is pure virtual.

I forgot I already changed that ;)
http://gcc.gnu.org/ml/gcc-cvs/2010-05/msg00437.html


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/47940] warn about calls to a pure virtual from a constructor/destructor
  2011-03-01 10:10 [Bug c++/47940] New: can call a pure virtual from a constructor/destructor mlg7 at yandex dot ru
                   ` (4 preceding siblings ...)
  2011-03-01 12:32 ` redi at gcc dot gnu.org
@ 2011-03-01 17:23 ` mlg7 at yandex dot ru
  2024-06-11 14:31 ` pinskia at gcc dot gnu.org
  2024-06-11 14:32 ` [Bug c++/47940] warn about calls to a pure virtual indirectly " pinskia at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: mlg7 at yandex dot ru @ 2011-03-01 17:23 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940

--- Comment #6 from mlg <mlg7 at yandex dot ru> 2011-03-01 17:23:41 UTC ---
(In reply to comment #4)
> (In reply to comment #0)
> > 
> > Functions that call pure virtual functions cannot
> > be called from constructors and destructors.
> > This may be discovered at compile-time, and the above
> > text makes a good error/warning message.
> 
> I'm not sure it makes a good diagnostic, consider:
> 
> struct abc {
>   abc(bool nasal_demons) { if (nasal_demons) fly(); }
>   void fly() { doFly(); }
>   virtual void doFly() = 0;
> };
>

That is the most dangerous situation: the crashing call is
buried [deep] in the control flow.
The deeper it is buried, the more valuable a warning/error
message would be.

Ok, "a pure virtual function may be called indirectly 
from a constructor/destructor"

> Ideally the diagnostic for this would say "may call a pure virtual" for cases
> where it can't be determined.

Probably you are right, a kind of "I know what I'm doing"
pragma would be useful as well.

I also want to note that the top-level function may be virtual:
[NOTE: usefunc() is virtual here]
==byebug2.cpp==
#include <stdio.h>
class Base {
public:
    ~Base() { usefunc(); }
    virtual void func()=0;
    virtual void usefunc() { func(); }
};

class Derived: public Base {
public:
    virtual void func() {}
};

int main() {
    Derived d;
    printf("life is good\n");
    return 0;
}
==eof==
$ g++ -Wall -Wextra byebug2.cpp
$ ./a.out 
life is good
pure virtual method called
terminate called without an active exception
Aborted


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/47940] warn about calls to a pure virtual from a constructor/destructor
  2011-03-01 10:10 [Bug c++/47940] New: can call a pure virtual from a constructor/destructor mlg7 at yandex dot ru
                   ` (5 preceding siblings ...)
  2011-03-01 17:23 ` mlg7 at yandex dot ru
@ 2024-06-11 14:31 ` pinskia at gcc dot gnu.org
  2024-06-11 14:32 ` [Bug c++/47940] warn about calls to a pure virtual indirectly " pinskia at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-06-11 14:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |redi at gcc dot gnu.org

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 115435 has been marked as a duplicate of this bug. ***

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c++/47940] warn about calls to a pure virtual indirectly from a constructor/destructor
  2011-03-01 10:10 [Bug c++/47940] New: can call a pure virtual from a constructor/destructor mlg7 at yandex dot ru
                   ` (6 preceding siblings ...)
  2024-06-11 14:31 ` pinskia at gcc dot gnu.org
@ 2024-06-11 14:32 ` pinskia at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2024-06-11 14:32 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47940

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2024-06-11
             Blocks|                            |87403
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=1925,
                   |                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=6006
     Ever confirmed|0                           |1
            Summary|warn about calls to a pure  |warn about calls to a pure
                   |virtual from a              |virtual indirectly from a
                   |constructor/destructor      |constructor/destructor

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87403
[Bug 87403] [Meta-bug] Issues that suggest a new warning

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-06-11 14:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-01 10:10 [Bug c++/47940] New: can call a pure virtual from a constructor/destructor mlg7 at yandex dot ru
2011-03-01 10:14 ` [Bug c++/47940] " pinskia at gcc dot gnu.org
2011-03-01 11:34 ` mlg7 at yandex dot ru
2011-03-01 12:19 ` [Bug c++/47940] warn about calls to " redi at gcc dot gnu.org
2011-03-01 12:30 ` redi at gcc dot gnu.org
2011-03-01 12:32 ` redi at gcc dot gnu.org
2011-03-01 17:23 ` mlg7 at yandex dot ru
2024-06-11 14:31 ` pinskia at gcc dot gnu.org
2024-06-11 14:32 ` [Bug c++/47940] warn about calls to a pure virtual indirectly " pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).