diff mbox

[1/2] Add OVERRIDE and FINAL macros to coretypes.h

Message ID 1462552846-17096-1-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm May 6, 2016, 4:40 p.m. UTC
C++11 adds the ability to add "override" after an implementation of a
virtual function in a subclass, to:
(A) document that this is an override of a virtual function
(B) allow the compiler to issue a warning if it isn't (e.g. a mismatch
of the type signature).

Similarly, it allows us to add a "final" to indicate that no subclass
may subsequently override the vfunc.

We use virtual functions in a few places (e.g. in the jit), so it would
be good to get this extra checking.

This patch adds OVERRIDE and FINAL as macros to coretypes.h
allowing us to get this extra checking when compiling with a compiler
that implements C++11 or later (e.g. gcc 6 by default),
but without requiring C++11.

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.

OK for trunk?

Does "final" imply "override"?  Is "final override" a tautology?

gcc/ChangeLog:
	* coretypes.h (OVERRIDE): New macro.
	(FINAL): New macro.
---
 gcc/coretypes.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Comments

Jakub Jelinek May 6, 2016, 4:20 p.m. UTC | #1
On Fri, May 06, 2016 at 12:40:45PM -0400, David Malcolm wrote:
> C++11 adds the ability to add "override" after an implementation of a
> virtual function in a subclass, to:
> (A) document that this is an override of a virtual function
> (B) allow the compiler to issue a warning if it isn't (e.g. a mismatch
> of the type signature).
> 
> Similarly, it allows us to add a "final" to indicate that no subclass
> may subsequently override the vfunc.
> 
> We use virtual functions in a few places (e.g. in the jit), so it would
> be good to get this extra checking.
> 
> This patch adds OVERRIDE and FINAL as macros to coretypes.h
> allowing us to get this extra checking when compiling with a compiler
> that implements C++11 or later (e.g. gcc 6 by default),
> but without requiring C++11.

Don't we also want CONSTEXPR similarly defined to constexpr for C++11 and
above and nothing otherwise?

	Jakub
David Malcolm May 6, 2016, 4:32 p.m. UTC | #2
On Fri, 2016-05-06 at 18:20 +0200, Jakub Jelinek wrote:
> On Fri, May 06, 2016 at 12:40:45PM -0400, David Malcolm wrote:
> > C++11 adds the ability to add "override" after an implementation of
> > a
> > virtual function in a subclass, to:
> > (A) document that this is an override of a virtual function
> > (B) allow the compiler to issue a warning if it isn't (e.g. a
> > mismatch
> > of the type signature).
> > 
> > Similarly, it allows us to add a "final" to indicate that no
> > subclass
> > may subsequently override the vfunc.
> > 
> > We use virtual functions in a few places (e.g. in the jit), so it
> > would
> > be good to get this extra checking.
> > 
> > This patch adds OVERRIDE and FINAL as macros to coretypes.h
> > allowing us to get this extra checking when compiling with a
> > compiler
> > that implements C++11 or later (e.g. gcc 6 by default),
> > but without requiring C++11.
> 
> Don't we also want CONSTEXPR similarly defined to constexpr for C++11
> and
> above and nothing otherwise?

Perhaps, but CONSTEXPR seems to be more awkward than OVERRIDE and
FINAL.  The meanings of "final" and "override" are consistent between
C++11 and C++14, but C++14 allows more things to be marked as
"constexpr" than C++11.  Hence having a single "CONSTEXPR" macro might
not be sufficient.  Perhaps there'd be CONSTEXPR_11 and CONSTEXPR_14
macros for things that are constexpr in C++11 onwards and constexpr in
C++14 onwards, respectively? (seems ugly to me).

Are the OVERRIDE and FINAL macros OK for trunk?

Thanks
Dave
Jakub Jelinek May 6, 2016, 4:37 p.m. UTC | #3
On Fri, May 06, 2016 at 12:32:47PM -0400, David Malcolm wrote:
> Perhaps, but CONSTEXPR seems to be more awkward than OVERRIDE and
> FINAL.  The meanings of "final" and "override" are consistent between
> C++11 and C++14, but C++14 allows more things to be marked as
> "constexpr" than C++11.  Hence having a single "CONSTEXPR" macro might
> not be sufficient.  Perhaps there'd be CONSTEXPR_11 and CONSTEXPR_14
> macros for things that are constexpr in C++11 onwards and constexpr in
> C++14 onwards, respectively? (seems ugly to me).

Yeah, or CONSTEXPR and CONSTEXPR14 could work, sure.

> Are the OVERRIDE and FINAL macros OK for trunk?

Yes.

	Jakub
Pedro Alves May 6, 2016, 5:56 p.m. UTC | #4
On 05/06/2016 05:40 PM, David Malcolm wrote:
> +#if __cplusplus >= 201103
> +/* C++11 claims to be available: use it: */
> +#define OVERRIDE override
> +#define FINAL final
> +#else
> +/* No C++11 support; leave the macros empty: */
> +#define OVERRIDE
> +#define FINAL
> +#endif
> +

Is there a reason this is preferred over using override/final in
the sources directly, and then define them away as empty
on pre-C++11?

I mean:

#if __cplusplus < 201103
# define override
# define final
#endif

then use override/final throughout instead of OVERRIDE/FINAL.

If building gcc as a C++11 program is supported, then it
won't be possible to use these names as symbols for
anything else anyway?

Thanks,
Pedro Alves
Pedro Alves May 6, 2016, 6:10 p.m. UTC | #5
On 05/06/2016 06:56 PM, Pedro Alves wrote:

> If building gcc as a C++11 program is supported, then it
> won't be possible to use these names as symbols for
> anything else anyway?

Just found out the above is not true.  Apparently I've
been stuck in C++98 for too long...  Sorry about the noise.

I was going to suggest to put this in include/ansidecl.h,
so that all C++ libraries / programs in binutils-gdb use the same
thing, instead of each reinventing the wheel, and I found
there's already something there:

    /* This is used to mark a class or virtual function as final.  */
#if __cplusplus >= 201103L
#define GCC_FINAL final
#elif GCC_VERSION >= 4007
#define GCC_FINAL __final
#else
#define GCC_FINAL
#endif

From:

 https://gcc.gnu.org/ml/gcc-patches/2015-08/msg00455.html

Apparently the patch that actually uses that was reverted,
as I can't find any use.

I like your names without the GCC_ prefix better though,
for the same reason of standardizing binutils-gdb + gcc
on the same symbols.
Pedro Alves May 6, 2016, 6:30 p.m. UTC | #6
On 05/06/2016 07:33 PM, Trevor Saunders wrote:
> On Fri, May 06, 2016 at 07:10:33PM +0100, Pedro Alves wrote:

>> I like your names without the GCC_ prefix better though,
>> for the same reason of standardizing binutils-gdb + gcc
>> on the same symbols.
> 
> I agree, though I'm not really sure when gdb / binutils stuff will
> support building as C++11.

gdb already builds as a C++ compiler by default today, and will
switch to C++-only right after the next release (couple months),
the latest.

Thanks,
Pedro Alves
Trevor Saunders May 6, 2016, 6:33 p.m. UTC | #7
On Fri, May 06, 2016 at 07:10:33PM +0100, Pedro Alves wrote:
> On 05/06/2016 06:56 PM, Pedro Alves wrote:
> 
> > If building gcc as a C++11 program is supported, then it
> > won't be possible to use these names as symbols for
> > anything else anyway?
> 
> Just found out the above is not true.  Apparently I've
> been stuck in C++98 for too long...  Sorry about the noise.
> 
> I was going to suggest to put this in include/ansidecl.h,
> so that all C++ libraries / programs in binutils-gdb use the same
> thing, instead of each reinventing the wheel, and I found
> there's already something there:
> 
>     /* This is used to mark a class or virtual function as final.  */
> #if __cplusplus >= 201103L
> #define GCC_FINAL final
> #elif GCC_VERSION >= 4007
> #define GCC_FINAL __final
> #else
> #define GCC_FINAL
> #endif
> 
> From:
> 
>  https://gcc.gnu.org/ml/gcc-patches/2015-08/msg00455.html
> 
> Apparently the patch that actually uses that was reverted,
> as I can't find any use.

Yeah, I wanted to use it to work around gdb not dealing well with stuff
in the anon namespace, but somehow that broke aix, and some people
objected and I haven't gotten back to it.

> I like your names without the GCC_ prefix better though,
> for the same reason of standardizing binutils-gdb + gcc
> on the same symbols.

I agree, though I'm not really sure when gdb / binutils stuff will
support building as C++11.

Trev

> 
> 
> -- 
> Thanks,
> Pedro Alves
Jason Merrill May 6, 2016, 8:47 p.m. UTC | #8
On Fri, May 6, 2016 at 1:56 PM, Pedro Alves <palves@redhat.com> wrote:
> On 05/06/2016 05:40 PM, David Malcolm wrote:
>> +#if __cplusplus >= 201103
>> +/* C++11 claims to be available: use it: */
>> +#define OVERRIDE override
>> +#define FINAL final
>> +#else
>> +/* No C++11 support; leave the macros empty: */
>> +#define OVERRIDE
>> +#define FINAL
>> +#endif
>> +
>
> Is there a reason this is preferred over using override/final in
> the sources directly, and then define them away as empty
> on pre-C++11?
>
> I mean:
>
> #if __cplusplus < 201103
> # define override
> # define final
> #endif
>
> then use override/final throughout instead of OVERRIDE/FINAL.

This would break any existing use of those identifiers; they are not
keywords, so a variable named "final" is perfectly valid C++11.

Jason
diff mbox

Patch

diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 2932d73..b3a91a6 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -361,6 +361,31 @@  typedef void (*gt_pointer_operator) (void *, void *);
 typedef unsigned char uchar;
 #endif
 
+/* C++11 adds the ability to add "override" after an implementation of a
+   virtual function in a subclass, to:
+     (A) document that this is an override of a virtual function
+     (B) allow the compiler to issue a warning if it isn't (e.g. a mismatch
+         of the type signature).
+
+   Similarly, it allows us to add a "final" to indicate that no subclass
+   may subsequently override the vfunc.
+
+   Provide OVERRIDE and FINAL as macros, allowing us to get these benefits
+   when compiling with C++11 support, but without requiring C++11.
+
+   For gcc, use "-std=c++11" to enable C++11 support; gcc 6 onwards enables
+   this by default (actually GNU++14).  */
+
+#if __cplusplus >= 201103
+/* C++11 claims to be available: use it: */
+#define OVERRIDE override
+#define FINAL final
+#else
+/* No C++11 support; leave the macros empty: */
+#define OVERRIDE
+#define FINAL
+#endif
+
 /* Most host source files will require the following headers.  */
 #if !defined (GENERATOR_FILE) && !defined (USED_FOR_TARGET)
 #include "machmode.h"