* [PATCH RFC] bootstrap: Update requirement to C++11. @ 2020-05-14 21:05 Jason Merrill 2020-05-14 21:09 ` Jakub Jelinek 2020-05-15 7:14 ` Richard Biener 0 siblings, 2 replies; 29+ messages in thread From: Jason Merrill @ 2020-05-14 21:05 UTC (permalink / raw) To: gcc-patches There seemed to be general agreement last November that we would move to allowing C++11 features to be used in GCC 11; this patch implements that direction. Are changes needed anywhere else? ChangeLog 2020-05-14 Jason Merrill <jason@redhat.com> * configure.ac: Update bootstrap dialect to -std=gnu++11. gcc/ChangeLog 2020-05-14 Jason Merrill <jason@redhat.com> * doc/install.texi (Prerequisites): Update boostrap compiler requirement to C++11/GCC 4.8. --- gcc/doc/install.texi | 14 ++++++++------ configure.ac | 6 +++--- ChangeLog | 4 ++++ configure | 6 +++--- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 876b04f9c45..f47e3c76f73 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -238,15 +238,17 @@ described below. @heading Tools/packages necessary for building GCC @table @asis -@item ISO C++98 compiler -Necessary to bootstrap GCC, although versions of GCC prior -to 4.8 also allow bootstrapping with a ISO C89 compiler and versions -of GCC prior to 3.4 also allow bootstrapping with a traditional -(K&R) C compiler. +@item ISO C++11 compiler +Necessary to bootstrap GCC. + +Versions of GCC prior to 11 also allow bootstrapping with an ISO C++98 +compiler, versions of GCC prior to 4.8 also allow bootstrapping with a +ISO C89 compiler, and versions of GCC prior to 3.4 also allow +bootstrapping with a traditional (K&R) C compiler. To build all languages in a cross-compiler or other configuration where 3-stage bootstrap is not performed, you need to start with an existing -GCC binary (version 3.4 or later) because source code for language +GCC binary (version 4.8 or later) because source code for language frontends other than C might use GCC extensions. Note that to bootstrap GCC with versions of GCC earlier than 3.4, you diff --git a/configure.ac b/configure.ac index c78d9cbea62..63d92b73061 100644 --- a/configure.ac +++ b/configure.ac @@ -1462,10 +1462,10 @@ case "$have_compiler:$host:$target:$enable_bootstrap" in ;; esac -# When bootstrapping with GCC, build stage 1 in C++98 mode to ensure that a -# C++98 compiler can still start the bootstrap. +# When bootstrapping with GCC, build stage 1 in C++11 mode to ensure that a +# C++11 compiler can still start the bootstrap. if test "$enable_bootstrap:$GXX" = "yes:yes"; then - CXX="$CXX -std=gnu++98" + CXX="$CXX -std=gnu++11" fi # Used for setting $lt_cv_objdir diff --git a/ChangeLog b/ChangeLog index a7fcf77b9b2..1d281855a3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2020-05-14 Jason Merrill <jason@redhat.com> + + * configure.ac: Update bootstrap dialect to -std=gnu++11. + 2020-04-29 Thomas Schwinge <thomas@codesourcery.com> PR target/92713 diff --git a/configure b/configure index 4cc938ebb7d..9b39035bbcc 100755 --- a/configure +++ b/configure @@ -5523,10 +5523,10 @@ $as_echo "$as_me: WARNING: trying to bootstrap a cross compiler" >&2;} ;; esac -# When bootstrapping with GCC, build stage 1 in C++98 mode to ensure that a -# C++98 compiler can still start the bootstrap. +# When bootstrapping with GCC, build stage 1 in C++11 mode to ensure that a +# C++11 compiler can still start the bootstrap. if test "$enable_bootstrap:$GXX" = "yes:yes"; then - CXX="$CXX -std=gnu++98" + CXX="$CXX -std=gnu++11" fi # Used for setting $lt_cv_objdir base-commit: 4e1592f8e1d6366699e05c0824fc3dc39ca7314b -- 2.18.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-14 21:05 [PATCH RFC] bootstrap: Update requirement to C++11 Jason Merrill @ 2020-05-14 21:09 ` Jakub Jelinek 2020-05-15 7:14 ` Richard Biener 1 sibling, 0 replies; 29+ messages in thread From: Jakub Jelinek @ 2020-05-14 21:09 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches On Thu, May 14, 2020 at 05:05:59PM -0400, Jason Merrill via Gcc-patches wrote: > +Versions of GCC prior to 11 also allow bootstrapping with an ISO C++98 > +compiler, versions of GCC prior to 4.8 also allow bootstrapping with a > +ISO C89 compiler, and versions of GCC prior to 3.4 also allow > +bootstrapping with a traditional (K&R) C compiler. > > To build all languages in a cross-compiler or other configuration where > 3-stage bootstrap is not performed, you need to start with an existing > -GCC binary (version 3.4 or later) because source code for language > +GCC binary (version 4.8 or later) because source code for language > frontends other than C might use GCC extensions. > > Note that to bootstrap GCC with versions of GCC earlier than 3.4, you Probably this paragraph needs adjustments too. Jakub ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-14 21:05 [PATCH RFC] bootstrap: Update requirement to C++11 Jason Merrill 2020-05-14 21:09 ` Jakub Jelinek @ 2020-05-15 7:14 ` Richard Biener 2020-05-15 8:30 ` Richard Sandiford 2020-05-15 17:30 ` Jason Merrill 1 sibling, 2 replies; 29+ messages in thread From: Richard Biener @ 2020-05-15 7:14 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches On Thu, May 14, 2020 at 11:53 PM Jason Merrill via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > There seemed to be general agreement last November that we would move to > allowing C++11 features to be used in GCC 11; this patch implements that > direction. Are changes needed anywhere else? > > ChangeLog > 2020-05-14 Jason Merrill <jason@redhat.com> > > * configure.ac: Update bootstrap dialect to -std=gnu++11. > > gcc/ChangeLog > 2020-05-14 Jason Merrill <jason@redhat.com> > > * doc/install.texi (Prerequisites): Update boostrap compiler > requirement to C++11/GCC 4.8. > --- > gcc/doc/install.texi | 14 ++++++++------ > configure.ac | 6 +++--- > ChangeLog | 4 ++++ > configure | 6 +++--- > 4 files changed, 18 insertions(+), 12 deletions(-) > > diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi > index 876b04f9c45..f47e3c76f73 100644 > --- a/gcc/doc/install.texi > +++ b/gcc/doc/install.texi > @@ -238,15 +238,17 @@ described below. > > @heading Tools/packages necessary for building GCC > @table @asis > -@item ISO C++98 compiler > -Necessary to bootstrap GCC, although versions of GCC prior > -to 4.8 also allow bootstrapping with a ISO C89 compiler and versions > -of GCC prior to 3.4 also allow bootstrapping with a traditional > -(K&R) C compiler. > +@item ISO C++11 compiler > +Necessary to bootstrap GCC. > + > +Versions of GCC prior to 11 also allow bootstrapping with an ISO C++98 > +compiler, versions of GCC prior to 4.8 also allow bootstrapping with a > +ISO C89 compiler, and versions of GCC prior to 3.4 also allow > +bootstrapping with a traditional (K&R) C compiler. > > To build all languages in a cross-compiler or other configuration where > 3-stage bootstrap is not performed, you need to start with an existing > -GCC binary (version 3.4 or later) because source code for language > +GCC binary (version 4.8 or later) because source code for language > frontends other than C might use GCC extensions. > > Note that to bootstrap GCC with versions of GCC earlier than 3.4, you > diff --git a/configure.ac b/configure.ac > index c78d9cbea62..63d92b73061 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -1462,10 +1462,10 @@ case "$have_compiler:$host:$target:$enable_bootstrap" in > ;; > esac > > -# When bootstrapping with GCC, build stage 1 in C++98 mode to ensure that a > -# C++98 compiler can still start the bootstrap. > +# When bootstrapping with GCC, build stage 1 in C++11 mode to ensure that a > +# C++11 compiler can still start the bootstrap. > if test "$enable_bootstrap:$GXX" = "yes:yes"; then > - CXX="$CXX -std=gnu++98" > + CXX="$CXX -std=gnu++11" So I just spotted this - since we're requiring a ISO C++11 compiler shouldn't we build stage1 with -std=c++11 rather than gnu++11 (whatever the detailed differences are here)? Also not sure what level of -pedantic we'd need to avoid GNU extensions even with -std=c++11. Of course there are (I hope) a lot less GNU extensions for C++ than there were for C and hopefully no extra in gnu++11 compared to gnu++98 which we checked previously. Note I think what's missing is some general blurb in our coding conventions as to how much of C++11 we are supposed to use in non-infrastructure parts of GCC (I expect things like hash-table.h to use more C++ features than, say, tree-ssa-alias.c). There also does not seem to be a configure check which may present users with a more useful error message than later cryptic fail of build? I suppose we cannot simply check __cplusplus for this, can we? Do other common host compilers need additional options to enable C++11? Should we try to second guess such flags via configury? For example GCC 4.8 defaults to -std=gnu++98 and the above only seems to apply to the bootstrap case so GCC 4.8 cannot be used to build cross compilers without adjusting CC and CXX? Thanks, Richard. > fi > > # Used for setting $lt_cv_objdir > diff --git a/ChangeLog b/ChangeLog > index a7fcf77b9b2..1d281855a3e 100644 > --- a/ChangeLog > +++ b/ChangeLog > @@ -1,3 +1,7 @@ > +2020-05-14 Jason Merrill <jason@redhat.com> > + > + * configure.ac: Update bootstrap dialect to -std=gnu++11. > + > 2020-04-29 Thomas Schwinge <thomas@codesourcery.com> > > PR target/92713 > diff --git a/configure b/configure > index 4cc938ebb7d..9b39035bbcc 100755 > --- a/configure > +++ b/configure > @@ -5523,10 +5523,10 @@ $as_echo "$as_me: WARNING: trying to bootstrap a cross compiler" >&2;} > ;; > esac > > -# When bootstrapping with GCC, build stage 1 in C++98 mode to ensure that a > -# C++98 compiler can still start the bootstrap. > +# When bootstrapping with GCC, build stage 1 in C++11 mode to ensure that a > +# C++11 compiler can still start the bootstrap. > if test "$enable_bootstrap:$GXX" = "yes:yes"; then > - CXX="$CXX -std=gnu++98" > + CXX="$CXX -std=gnu++11" > fi > > # Used for setting $lt_cv_objdir > > base-commit: 4e1592f8e1d6366699e05c0824fc3dc39ca7314b > -- > 2.18.1 > ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 7:14 ` Richard Biener @ 2020-05-15 8:30 ` Richard Sandiford 2020-05-15 9:26 ` Richard Biener 2020-05-15 17:30 ` Jason Merrill 1 sibling, 1 reply; 29+ messages in thread From: Richard Sandiford @ 2020-05-15 8:30 UTC (permalink / raw) To: Richard Biener via Gcc-patches Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes: > Note I think what's missing is some general blurb in our coding conventions > as to how much of C++11 we are supposed to use in non-infrastructure parts > of GCC (I expect things like hash-table.h to use more C++ features than, > say, tree-ssa-alias.c). I guess there are two aspects to that: - Are there any specific features we should avoid using at all? TBH I hope not. Trying to police this based on C++ feature sounds difficulty and might be counterproductive. IMO it should just (continue to) be based on principles like avoiding abstraction for abstraction's sake, and keeping compiler performance and code size in mind. Even tree-ssa-alias.c should be able to use any C++ feature if there's a justification. - Coding conventions for when features should be used. "auto" is an obvious one. Maybe also lambdas (which should help avoid the horrible "void *" callback parameters we have all over the place now). Maybe also guidelines to actively use certain features, e.g. - use "= default" where possible - prefer range-based for loops to macros - mark "operator bool()" conversions as explicit - use "override" where applicable (all obvious I guess), etc. Thanks, Richard ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 8:30 ` Richard Sandiford @ 2020-05-15 9:26 ` Richard Biener 2020-05-15 9:58 ` Richard Sandiford 0 siblings, 1 reply; 29+ messages in thread From: Richard Biener @ 2020-05-15 9:26 UTC (permalink / raw) To: Richard Biener via Gcc-patches, Jason Merrill, Richard Biener, Richard Sandiford On Fri, May 15, 2020 at 10:30 AM Richard Sandiford <richard.sandiford@arm.com> wrote: > > Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes: > > Note I think what's missing is some general blurb in our coding conventions > > as to how much of C++11 we are supposed to use in non-infrastructure parts > > of GCC (I expect things like hash-table.h to use more C++ features than, > > say, tree-ssa-alias.c). > > I guess there are two aspects to that: > > - Are there any specific features we should avoid using at all? > TBH I hope not. Trying to police this based on C++ feature sounds > difficulty and might be counterproductive. > > IMO it should just (continue to) be based on principles like avoiding > abstraction for abstraction's sake, and keeping compiler performance > and code size in mind. Even tree-ssa-alias.c should be able to use > any C++ feature if there's a justification. > > - Coding conventions for when features should be used. "auto" is an > obvious one. Maybe also lambdas (which should help avoid the horrible > "void *" callback parameters we have all over the place now). > > Maybe also guidelines to actively use certain features, e.g. > > - use "= default" where possible > > - prefer range-based for loops to macros > > - mark "operator bool()" conversions as explicit > > - use "override" where applicable > > (all obvious I guess), etc. I think the most important thing is that refactoring for the sake of refactoring is bad iff it does not improve on consistency throughout the code base. We should really try hard to use C++ features consistently - this makes the code base easier to understand. We've moved more and more to stronly-typed data structures so I'd not like to see 'auto' everywhere - it should be still obvious what kind of objects we're working with where they matter. IMHO they do not matter for example for iterators. I don't care about the iterator type but about the type of the object and the container. Richard. > Thanks, > Richard ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 9:26 ` Richard Biener @ 2020-05-15 9:58 ` Richard Sandiford 2020-05-15 10:15 ` Richard Biener 2020-05-15 17:36 ` [PATCH RFC] bootstrap: Update requirement to C++11 Jason Merrill 0 siblings, 2 replies; 29+ messages in thread From: Richard Sandiford @ 2020-05-15 9:58 UTC (permalink / raw) To: Richard Biener; +Cc: Richard Biener via Gcc-patches, Jason Merrill Richard Biener <richard.guenther@gmail.com> writes: > On Fri, May 15, 2020 at 10:30 AM Richard Sandiford > <richard.sandiford@arm.com> wrote: >> >> Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes: >> > Note I think what's missing is some general blurb in our coding conventions >> > as to how much of C++11 we are supposed to use in non-infrastructure parts >> > of GCC (I expect things like hash-table.h to use more C++ features than, >> > say, tree-ssa-alias.c). >> >> I guess there are two aspects to that: >> >> - Are there any specific features we should avoid using at all? >> TBH I hope not. Trying to police this based on C++ feature sounds >> difficulty and might be counterproductive. >> >> IMO it should just (continue to) be based on principles like avoiding >> abstraction for abstraction's sake, and keeping compiler performance >> and code size in mind. Even tree-ssa-alias.c should be able to use >> any C++ feature if there's a justification. >> >> - Coding conventions for when features should be used. "auto" is an >> obvious one. Maybe also lambdas (which should help avoid the horrible >> "void *" callback parameters we have all over the place now). >> >> Maybe also guidelines to actively use certain features, e.g. >> >> - use "= default" where possible >> >> - prefer range-based for loops to macros >> >> - mark "operator bool()" conversions as explicit >> >> - use "override" where applicable >> >> (all obvious I guess), etc. > > I think the most important thing is that refactoring for the sake > of refactoring is bad iff it does not improve on consistency > throughout the code base. We should really try hard to use > C++ features consistently - this makes the code base easier > to understand. Agreed. One of the reasons I'm keen to have something in the coding standards is that things became less consistent after the C->C++ switch. Maybe we should reconsider some of the existing coding standards too. E.g.: Define all members outside the class definition. That is, there are no function bodies or member initializers inside the class definition. isn't widely followed. That's a bit of a tangent though. (FTR, I've no attachment to the current conventions and didn't contribute anything to them. More consistency would be good though.) > We've moved more and more to stronly-typed data structures > so I'd not like to see 'auto' everywhere - it should be still > obvious what kind of objects we're working with where they > matter. IMHO they do not matter for example for iterators. > I don't care about the iterator type but about the type of > the object and the container. Also agreed. :-) How about this as a starting point: --------------------------------------------------------------- Use auto for: - the result of casts or other expressions that give the type explicitly. E.g.: if (auto *table = dyn_cast <rtx_jump_table_data *> (insn)) instead of: if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn)) - iterator types. E.g.: auto it = foo.begin (); instead of: foo_type::iterator it = foo.begin (); - expressions that provide an alternative view of something, when the expression is bound to a read-only temporary. E.g.: auto val1 = wi::to_wide (...); auto val2 = wi::uhwi (12, 16); instead of: wide_int val1 = wi::to_wide (...); wide_int val2 = wi::uhwi (12, 16); (Using "wide_int" is less efficient than using the natural type of the expression.) - the type of a lambda expression. E.g.: auto f = [] (int x) { return x + 1; }; Do not use auto otherwise. --------------------------------------------------------------- One thing I wondered about is whether we should encourage auto for normal integer results. It would avoid problems with values being silently truncated to a narrower type (e.g. HOST_WIDE_INT->int). On the other hand, that kind of truncation will still happen in things like function calls and member variable assignments. Using "auto" could also hide important signedness choices. So not using "auto" is probably better there... Richard ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 9:58 ` Richard Sandiford @ 2020-05-15 10:15 ` Richard Biener 2020-05-15 14:08 ` Richard Sandiford 2020-05-15 17:36 ` [PATCH RFC] bootstrap: Update requirement to C++11 Jason Merrill 1 sibling, 1 reply; 29+ messages in thread From: Richard Biener @ 2020-05-15 10:15 UTC (permalink / raw) To: Richard Biener, Richard Biener via Gcc-patches, Jason Merrill, Richard Sandiford On Fri, May 15, 2020 at 11:58 AM Richard Sandiford <richard.sandiford@arm.com> wrote: > > Richard Biener <richard.guenther@gmail.com> writes: > > On Fri, May 15, 2020 at 10:30 AM Richard Sandiford > > <richard.sandiford@arm.com> wrote: > >> > >> Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes: > >> > Note I think what's missing is some general blurb in our coding conventions > >> > as to how much of C++11 we are supposed to use in non-infrastructure parts > >> > of GCC (I expect things like hash-table.h to use more C++ features than, > >> > say, tree-ssa-alias.c). > >> > >> I guess there are two aspects to that: > >> > >> - Are there any specific features we should avoid using at all? > >> TBH I hope not. Trying to police this based on C++ feature sounds > >> difficulty and might be counterproductive. > >> > >> IMO it should just (continue to) be based on principles like avoiding > >> abstraction for abstraction's sake, and keeping compiler performance > >> and code size in mind. Even tree-ssa-alias.c should be able to use > >> any C++ feature if there's a justification. > >> > >> - Coding conventions for when features should be used. "auto" is an > >> obvious one. Maybe also lambdas (which should help avoid the horrible > >> "void *" callback parameters we have all over the place now). > >> > >> Maybe also guidelines to actively use certain features, e.g. > >> > >> - use "= default" where possible > >> > >> - prefer range-based for loops to macros > >> > >> - mark "operator bool()" conversions as explicit > >> > >> - use "override" where applicable > >> > >> (all obvious I guess), etc. > > > > I think the most important thing is that refactoring for the sake > > of refactoring is bad iff it does not improve on consistency > > throughout the code base. We should really try hard to use > > C++ features consistently - this makes the code base easier > > to understand. > > Agreed. One of the reasons I'm keen to have something in the > coding standards is that things became less consistent after > the C->C++ switch. Yeah. I'm really hoping that we can unify all of the various iteration styles used. In general, even if I don't like it too much personally, I'm leaning towards STL style of thing because of the idea "C++ attracts more developers". Now C++ range-for makes me like it much more so that's one good reason for adopting C++11, turn all of them over to range-for style (only!). > Maybe we should reconsider some of the existing coding standards too. > E.g.: > > Define all members outside the class definition. > That is, there are no function bodies or member initializers > inside the class definition. > > isn't widely followed. That's a bit of a tangent though. > (FTR, I've no attachment to the current conventions and didn't > contribute anything to them. More consistency would be good though.) > > > We've moved more and more to stronly-typed data structures > > so I'd not like to see 'auto' everywhere - it should be still > > obvious what kind of objects we're working with where they > > matter. IMHO they do not matter for example for iterators. > > I don't care about the iterator type but about the type of > > the object and the container. > > Also agreed. :-) How about this as a starting point: > > --------------------------------------------------------------- > Use auto for: > > - the result of casts or other expressions that give the type > explicitly. E.g.: > > if (auto *table = dyn_cast <rtx_jump_table_data *> (insn)) > > instead of: > > if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn)) > > - iterator types. E.g.: > > auto it = foo.begin (); > > instead of: > > foo_type::iterator it = foo.begin (); > > - expressions that provide an alternative view of something, > when the expression is bound to a read-only temporary. E.g.: > > auto val1 = wi::to_wide (...); > auto val2 = wi::uhwi (12, 16); > > instead of: > > wide_int val1 = wi::to_wide (...); > wide_int val2 = wi::uhwi (12, 16); > > (Using "wide_int" is less efficient than using the natural type of > the expression.) > > - the type of a lambda expression. E.g.: > > auto f = [] (int x) { return x + 1; }; Those are all good examples. Mind putting that into a patch for the coding conventions? > Do not use auto otherwise. > --------------------------------------------------------------- > > One thing I wondered about is whether we should encourage auto > for normal integer results. It would avoid problems with values > being silently truncated to a narrower type (e.g. HOST_WIDE_INT->int). > On the other hand, that kind of truncation will still happen in things > like function calls and member variable assignments. Using "auto" could > also hide important signedness choices. So not using "auto" is probably > better there... Agreed. Richard. > Richard ^ permalink raw reply [flat|nested] 29+ messages in thread
* (no subject) 2020-05-15 10:15 ` Richard Biener @ 2020-05-15 14:08 ` Richard Sandiford 2020-05-16 1:47 ` Martin Sebor 0 siblings, 1 reply; 29+ messages in thread From: Richard Sandiford @ 2020-05-15 14:08 UTC (permalink / raw) To: Richard Biener; +Cc: Richard Biener via Gcc-patches, Jason Merrill [-- Attachment #1: Type: text/plain, Size: 1706 bytes --] >> > We've moved more and more to stronly-typed data structures >> > so I'd not like to see 'auto' everywhere - it should be still >> > obvious what kind of objects we're working with where they >> > matter. IMHO they do not matter for example for iterators. >> > I don't care about the iterator type but about the type of >> > the object and the container. >> >> Also agreed. :-) How about this as a starting point: >> >> --------------------------------------------------------------- >> Use auto for: >> >> - the result of casts or other expressions that give the type >> explicitly. E.g.: >> >> if (auto *table = dyn_cast <rtx_jump_table_data *> (insn)) >> >> instead of: >> >> if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn)) >> >> - iterator types. E.g.: >> >> auto it = foo.begin (); >> >> instead of: >> >> foo_type::iterator it = foo.begin (); >> >> - expressions that provide an alternative view of something, >> when the expression is bound to a read-only temporary. E.g.: >> >> auto val1 = wi::to_wide (...); >> auto val2 = wi::uhwi (12, 16); >> >> instead of: >> >> wide_int val1 = wi::to_wide (...); >> wide_int val2 = wi::uhwi (12, 16); >> >> (Using "wide_int" is less efficient than using the natural type of >> the expression.) >> >> - the type of a lambda expression. E.g.: >> >> auto f = [] (int x) { return x + 1; }; > > Those are all good examples. Mind putting that into a patch > for the coding conventions? How's this? I added "new" expressions as another example of the first category. I'm sure I've missed other good uses, but we can always add to the list later if necessary. Thanks, Richard [-- Attachment #2: 0001-Describe-coding-conventions-surrounding-auto.patch --] [-- Type: text/plain, Size: 4621 bytes --] From 10b27e367de0fa9d5bf91544385401cdcbdb8c00 Mon Sep 17 00:00:00 2001 From: Richard Sandiford <richard.sandiford@arm.com> Date: Fri, 15 May 2020 14:58:46 +0100 Subject: [PATCH] Describe coding conventions surrounding "auto" --- htdocs/codingconventions.html | 53 +++++++++++++++++++++++++++++++++++ htdocs/codingrationale.html | 17 +++++++++++ 2 files changed, 70 insertions(+) diff --git a/htdocs/codingconventions.html b/htdocs/codingconventions.html index f4732ef6..ae49fb91 100644 --- a/htdocs/codingconventions.html +++ b/htdocs/codingconventions.html @@ -51,6 +51,7 @@ the conventions separately from any other changes to the code.</p> <li><a href="#Cxx_Language">Language Use</a> <ul> <li><a href="#Variable">Variable Definitions</a></li> + <li><a href="#Auto">Use of <code>auto</code></a></li> <li><a href="#Struct_Use">Struct Definitions</a></li> <li><a href="#Class_Use">Class Definitions</a></li> <li><a href="#Constructors">Constructors and Destructors</a></li> @@ -884,6 +885,58 @@ Variables may be simultaneously defined and tested in control expressions. <a href="codingrationale.html#variables">Rationale and Discussion</a> </p> +<h4 id="Auto">Use of <code>auto</code></h4> + +<p><code>auto</code> should be used in the following circumstances: +<ul> + <li><p>when the expression gives the C++ type explicitly. For example</p> + + <blockquote> +<pre>if (<b>auto *</b>table = dyn_cast <<b>rtx_jump_table_data *</b>> (insn)) // OK + ... +if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn)) // Avoid + ... +<b>auto *</b>map = new <b>hash_map <tree, size_t></b>; // OK +hash_map <tree, size_t> *map = new hash_map <tree, size_t>; // Avoid</pre></blockquote> + + <p>This rule does not apply to abbreviated type names embedded in + an identifier, such as the result of <code>tree_to_shwi</code>.</p> + </li> + <li> + <p>when the expression simply provides an alternative view of an object + and is bound to a read-only temporary. For example:</p> + + <blockquote> +<pre><b>auto</b> wioff = <b>wi::to_wide (off);</b> // OK +wide_int wioff = wi::to_wide (off); // Avoid if wioff is read-only +<b>auto</b> minus1 = <b>std::shwi (-1, prec);</b> // OK +wide_int minus1 = std::shwi (-1, prec); // Avoid if minus1 is read-only</pre></blockquote> + + <p>In principle this rule applies to other views of an object too, + such as a reversed view of a list, or a sequential view of a + <code>hash_set</code>. It does not apply to general temporaries.</p> + </li> + <li> + <p>the type of an iterator. For example:</p> + + <blockquote> +<pre><b>auto</b> it = <b>std::find (names.begin (), names.end (), needle)</b>; // OK +vector <name_map>::iterator it = std::find (names.begin (), + names.end (), needle); // Avoid</pre></blockquote> + </li> + <li> + <p>the type of a lambda expression. For example:</p> + + <blockquote> +<pre><b>auto</b> f = <b>[] (int x) { return x + 1; }</b>; // OK</pre></blockquote> + </li> +</ul></p> + +<p><code>auto</code> should <b>not</b> be used in other contexts.</p> + +<p> +<a href="codingrationale.html#auto">Rationale and Discussion</a> +</p> <h4 id="Struct_Use">Struct Definitions</h4> diff --git a/htdocs/codingrationale.html b/htdocs/codingrationale.html index 0b44f1da..a919023c 100644 --- a/htdocs/codingrationale.html +++ b/htdocs/codingrationale.html @@ -50,6 +50,23 @@ if (info *q = get_any_available_info ()) { } </code></pre></blockquote> +<h4 id="auto">Use of <code>auto</code></h4> + +<p>The reason for preferring <code>auto</code> in expressions like: +<blockquote><pre>auto wioff = wi::to_wide (off);</pre></blockquote> +is that using the natural type of the expression is more efficient than +converting it to types like <code>wide_int</code>.</p> + +<p>The reason for excluding other uses of <code>auto</code> is that +in most other cases the type carries useful information. For example: +<blockquote><pre>for (const std::pair <const char *, tree> &elt : indirect_pool) + ...</pre></blockquote> +makes it obvious that <code>elt</code> is a pair and gives the types of +<code>elt.first</code> and <code>elt.second</code>. In contrast: +<blockquote><pre>for (const auto &elt : indirect_pool) + ...</pre></blockquote> +gives no immediate indication what <code>elt</code> is or what can +be done with it.</p> <h4 id="struct">Struct Definitions</h4> -- 2.17.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: 2020-05-15 14:08 ` Richard Sandiford @ 2020-05-16 1:47 ` Martin Sebor 2020-05-16 2:45 ` Re: Jason Merrill 0 siblings, 1 reply; 29+ messages in thread From: Martin Sebor @ 2020-05-16 1:47 UTC (permalink / raw) To: Richard Biener, Richard Biener via Gcc-patches, Jason Merrill, richard.sandiford On 5/15/20 8:08 AM, Richard Sandiford wrote: >>>> We've moved more and more to stronly-typed data structures >>>> so I'd not like to see 'auto' everywhere - it should be still >>>> obvious what kind of objects we're working with where they >>>> matter. IMHO they do not matter for example for iterators. >>>> I don't care about the iterator type but about the type of >>>> the object and the container. >>> Also agreed. :-) How about this as a starting point: >>> >>> --------------------------------------------------------------- >>> Use auto for: >>> >>> - the result of casts or other expressions that give the type >>> explicitly. E.g.: >>> >>> if (auto *table = dyn_cast <rtx_jump_table_data *> (insn)) >>> >>> instead of: >>> >>> if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn)) >>> >>> - iterator types. E.g.: >>> >>> auto it = foo.begin (); >>> >>> instead of: >>> >>> foo_type::iterator it = foo.begin (); >>> >>> - expressions that provide an alternative view of something, >>> when the expression is bound to a read-only temporary. E.g.: >>> >>> auto val1 = wi::to_wide (...); >>> auto val2 = wi::uhwi (12, 16); >>> >>> instead of: >>> >>> wide_int val1 = wi::to_wide (...); >>> wide_int val2 = wi::uhwi (12, 16); >>> >>> (Using "wide_int" is less efficient than using the natural type of >>> the expression.) >>> >>> - the type of a lambda expression. E.g.: >>> >>> auto f = [] (int x) { return x + 1; }; >> Those are all good examples. Mind putting that into a patch >> for the coding conventions? > How's this? I added "new" expressions as another example of the > first category. > > I'm sure I've missed other good uses, but we can always add to the > list later if necessary. > > Thanks, > Richard > > > 0001-Describe-coding-conventions-surrounding-auto.patch > > From 10b27e367de0fa9d5bf91544385401cdcbdb8c00 Mon Sep 17 00:00:00 2001 > From: Richard Sandiford<richard.sandiford@arm.com> > Date: Fri, 15 May 2020 14:58:46 +0100 > Subject: [PATCH] Describe coding conventions surrounding "auto" > > --- > htdocs/codingconventions.html | 53 +++++++++++++++++++++++++++++++++++ > htdocs/codingrationale.html | 17 +++++++++++ > 2 files changed, 70 insertions(+) > > diff --git a/htdocs/codingconventions.html b/htdocs/codingconventions.html > index f4732ef6..ae49fb91 100644 > --- a/htdocs/codingconventions.html > +++ b/htdocs/codingconventions.html > @@ -51,6 +51,7 @@ the conventions separately from any other changes to the code.</p> > <li><a href="#Cxx_Language">Language Use</a> > <ul> > <li><a href="#Variable">Variable Definitions</a></li> > + <li><a href="#Auto">Use of <code>auto</code></a></li> > <li><a href="#Struct_Use">Struct Definitions</a></li> > <li><a href="#Class_Use">Class Definitions</a></li> > <li><a href="#Constructors">Constructors and Destructors</a></li> > @@ -884,6 +885,58 @@ Variables may be simultaneously defined and tested in control expressions. > <a href="codingrationale.html#variables">Rationale and Discussion</a> > </p> > > +<h4 id="Auto">Use of <code>auto</code></h4> > + > +<p><code>auto</code> should be used in the following circumstances: > +<ul> > + <li><p>when the expression gives the C++ type explicitly. For example</p> > + > + <blockquote> > +<pre>if (<b>auto *</b>table = dyn_cast <<b>rtx_jump_table_data *</b>> (insn)) // OK > + ... > +if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn)) // Avoid > + ... > +<b>auto *</b>map = new <b>hash_map <tree, size_t></b>; // OK > +hash_map <tree, size_t> *map = new hash_map <tree, size_t>; // Avoid</pre></blockquote> > + > + <p>This rule does not apply to abbreviated type names embedded in > + an identifier, such as the result of <code>tree_to_shwi</code>.</p> > + </li> > + <li> > + <p>when the expression simply provides an alternative view of an object > + and is bound to a read-only temporary. For example:</p> > + > + <blockquote> > +<pre><b>auto</b> wioff = <b>wi::to_wide (off);</b> // OK > +wide_int wioff = wi::to_wide (off); // Avoid if wioff is read-only > +<b>auto</b> minus1 = <b>std::shwi (-1, prec);</b> // OK > +wide_int minus1 = std::shwi (-1, prec); // Avoid if minus1 is read-only</pre></blockquote> > + > + <p>In principle this rule applies to other views of an object too, > + such as a reversed view of a list, or a sequential view of a > + <code>hash_set</code>. It does not apply to general temporaries.</p> > + </li> > + <li> > + <p>the type of an iterator. For example:</p> > + > + <blockquote> > +<pre><b>auto</b> it = <b>std::find (names.begin (), names.end (), needle)</b>; // OK > +vector <name_map>::iterator it = std::find (names.begin (), > + names.end (), needle); // Avoid</pre></blockquote> > + </li> > + <li> > + <p>the type of a lambda expression. For example:</p> > + > + <blockquote> > +<pre><b>auto</b> f = <b>[] (int x) { return x + 1; }</b>; // OK</pre></blockquote> > + </li> > +</ul></p> > + > +<p><code>auto</code> should <b>not</b> be used in other contexts.</p> This seems like a severe (and unnecessary) restriction... > + > +<p> > +<a href="codingrationale.html#auto">Rationale and Discussion</a> > +</p> > > <h4 id="Struct_Use">Struct Definitions</h4> > > diff --git a/htdocs/codingrationale.html b/htdocs/codingrationale.html > index 0b44f1da..a919023c 100644 > --- a/htdocs/codingrationale.html > +++ b/htdocs/codingrationale.html > @@ -50,6 +50,23 @@ if (info *q = get_any_available_info ()) { > } > </code></pre></blockquote> > > +<h4 id="auto">Use of <code>auto</code></h4> > + > +<p>The reason for preferring <code>auto</code> in expressions like: > +<blockquote><pre>auto wioff = wi::to_wide (off);</pre></blockquote> > +is that using the natural type of the expression is more efficient than > +converting it to types like <code>wide_int</code>.</p> > + > +<p>The reason for excluding other uses of <code>auto</code> is that > +in most other cases the type carries useful information. For example: > +<blockquote><pre>for (const std::pair <const char *, tree> &elt : indirect_pool) > + ...</pre></blockquote> > +makes it obvious that <code>elt</code> is a pair and gives the types of > +<code>elt.first</code> and <code>elt.second</code>. In contrast: > +<blockquote><pre>for (const auto &elt : indirect_pool) > + ...</pre></blockquote> > +gives no immediate indication what <code>elt</code> is or what can > +be done with it.</p> ...there are countless constructs in C++ 98 as well in C where there is no such indication yet we don't (and very well can't) try to avoid using them. Examples include macros, members of structures defined far away from the point of their use, results of ordinary function calls, results of overloaded functions or templates, default function arguments, default template parameters, etc. By way of a random example from genrecog.c: int_set::iterator end = std::set_union (trans1->labels.begin (), trans1->labels.end (), combined->begin (), combined->end (), next->begin ()); There is no immediate indication precisely what type int_set::iterator is. All we can tell is that that it's some sort of an iterator, and that should be good enough. It lets us (even forces us to) write code that satisfies the requirements of the abstraction (whatever it happens to be), and avoid tying it closely to the implementation. That's a good thing. Unless there is a sound technical reason for avoiding it (e.g., unacceptable inefficiency or known safety problems) I'd say leave it to everyone's judgment what convenience features to use. If something turns out to be a problem we'll deal with it then. Martin ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: 2020-05-16 1:47 ` Martin Sebor @ 2020-05-16 2:45 ` Jason Merrill 2020-05-16 10:43 ` [PATCH] Describe coding conventions surrounding "auto" Richard Sandiford 0 siblings, 1 reply; 29+ messages in thread From: Jason Merrill @ 2020-05-16 2:45 UTC (permalink / raw) To: Martin Sebor Cc: Richard Biener, Richard Biener via Gcc-patches, Richard Sandiford On Fri, May 15, 2020 at 9:47 PM Martin Sebor <msebor@gmail.com> wrote: > On 5/15/20 8:08 AM, Richard Sandiford wrote: > >>>> We've moved more and more to stronly-typed data structures > >>>> so I'd not like to see 'auto' everywhere - it should be still > >>>> obvious what kind of objects we're working with where they > >>>> matter. IMHO they do not matter for example for iterators. > >>>> I don't care about the iterator type but about the type of > >>>> the object and the container. > >>> Also agreed. :-) How about this as a starting point: > >>> > >>> --------------------------------------------------------------- > >>> Use auto for: > >>> > >>> - the result of casts or other expressions that give the type > >>> explicitly. E.g.: > >>> > >>> if (auto *table = dyn_cast <rtx_jump_table_data *> (insn)) > >>> > >>> instead of: > >>> > >>> if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> > (insn)) > >>> > >>> - iterator types. E.g.: > >>> > >>> auto it = foo.begin (); > >>> > >>> instead of: > >>> > >>> foo_type::iterator it = foo.begin (); > >>> > >>> - expressions that provide an alternative view of something, > >>> when the expression is bound to a read-only temporary. E.g.: > >>> > >>> auto val1 = wi::to_wide (...); > >>> auto val2 = wi::uhwi (12, 16); > >>> > >>> instead of: > >>> > >>> wide_int val1 = wi::to_wide (...); > >>> wide_int val2 = wi::uhwi (12, 16); > >>> > >>> (Using "wide_int" is less efficient than using the natural type of > >>> the expression.) > >>> > >>> - the type of a lambda expression. E.g.: > >>> > >>> auto f = [] (int x) { return x + 1; }; > >> Those are all good examples. Mind putting that into a patch > >> for the coding conventions? > > How's this? I added "new" expressions as another example of the > > first category. > > > > I'm sure I've missed other good uses, but we can always add to the > > list later if necessary. > > > > Thanks, > > Richard > > > > > > 0001-Describe-coding-conventions-surrounding-auto.patch > > > > From 10b27e367de0fa9d5bf91544385401cdcbdb8c00 Mon Sep 17 00:00:00 2001 > > From: Richard Sandiford<richard.sandiford@arm.com> > > Date: Fri, 15 May 2020 14:58:46 +0100 > > Subject: [PATCH] Describe coding conventions surrounding "auto" > > > > --- > > htdocs/codingconventions.html | 53 +++++++++++++++++++++++++++++++++++ > > htdocs/codingrationale.html | 17 +++++++++++ > > 2 files changed, 70 insertions(+) > > > > diff --git a/htdocs/codingconventions.html > b/htdocs/codingconventions.html > > index f4732ef6..ae49fb91 100644 > > --- a/htdocs/codingconventions.html > > +++ b/htdocs/codingconventions.html > > @@ -51,6 +51,7 @@ the conventions separately from any other changes to > the code.</p> > > <li><a href="#Cxx_Language">Language Use</a> > > <ul> > > <li><a href="#Variable">Variable Definitions</a></li> > > + <li><a href="#Auto">Use of <code>auto</code></a></li> > > <li><a href="#Struct_Use">Struct Definitions</a></li> > > <li><a href="#Class_Use">Class Definitions</a></li> > > <li><a href="#Constructors">Constructors and > Destructors</a></li> > > @@ -884,6 +885,58 @@ Variables may be simultaneously defined and tested > in control expressions. > > <a href="codingrationale.html#variables">Rationale and Discussion</a> > > </p> > > > > +<h4 id="Auto">Use of <code>auto</code></h4> > > + > > +<p><code>auto</code> should be used in the following circumstances: > > +<ul> > > + <li><p>when the expression gives the C++ type explicitly. For > example</p> > > + > > + <blockquote> > > +<pre>if (<b>auto *</b>table = dyn_cast <<b>rtx_jump_table_data > *</b>> (insn)) // OK > > + ... > > +if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> > (insn)) // Avoid > > + ... > > +<b>auto *</b>map = new <b>hash_map <tree, size_t></b>; > // OK > > +hash_map <tree, size_t> *map = new hash_map <tree, size_t>; > // Avoid</pre></blockquote> > > + > > + <p>This rule does not apply to abbreviated type names embedded in > > + an identifier, such as the result of <code>tree_to_shwi</code>.</p> > > + </li> > > + <li> > > + <p>when the expression simply provides an alternative view of an > object > > + and is bound to a read-only temporary. For example:</p> > > + > > + <blockquote> > > +<pre><b>auto</b> wioff = <b>wi::to_wide (off);</b> // OK > > +wide_int wioff = wi::to_wide (off); // Avoid if wioff is read-only > > +<b>auto</b> minus1 = <b>std::shwi (-1, prec);</b> // OK > > +wide_int minus1 = std::shwi (-1, prec); // Avoid if minus1 is > read-only</pre></blockquote> > > + > > + <p>In principle this rule applies to other views of an object too, > > + such as a reversed view of a list, or a sequential view of a > > + <code>hash_set</code>. It does not apply to general > temporaries.</p> > > + </li> > > + <li> > > + <p>the type of an iterator. For example:</p> > > + > > + <blockquote> > > +<pre><b>auto</b> it = <b>std::find (names.begin (), names.end (), > needle)</b>; // OK > > +vector <name_map>::iterator it = std::find (names.begin (), > > + names.end (), needle); // > Avoid</pre></blockquote> > > + </li> > > + <li> > > + <p>the type of a lambda expression. For example:</p> > > + > > + <blockquote> > > +<pre><b>auto</b> f = <b>[] (int x) { return x + 1; }</b>; // > OK</pre></blockquote> > > + </li> > > +</ul></p> > > + > > +<p><code>auto</code> should <b>not</b> be used in other contexts.</p> > > This seems like a severe (and unnecessary) restriction... > > > + > > +<p> > > +<a href="codingrationale.html#auto">Rationale and Discussion</a> > > +</p> > > > > <h4 id="Struct_Use">Struct Definitions</h4> > > > > diff --git a/htdocs/codingrationale.html b/htdocs/codingrationale.html > > index 0b44f1da..a919023c 100644 > > --- a/htdocs/codingrationale.html > > +++ b/htdocs/codingrationale.html > > @@ -50,6 +50,23 @@ if (info *q = get_any_available_info ()) { > > } > > </code></pre></blockquote> > > > > +<h4 id="auto">Use of <code>auto</code></h4> > > + > > +<p>The reason for preferring <code>auto</code> in expressions like: > > +<blockquote><pre>auto wioff = wi::to_wide (off);</pre></blockquote> > > +is that using the natural type of the expression is more efficient than > > +converting it to types like <code>wide_int</code>.</p> > > + > > +<p>The reason for excluding other uses of <code>auto</code> is that > > +in most other cases the type carries useful information. For example: > > +<blockquote><pre>for (const std::pair <const char *, tree> > &elt : indirect_pool) > > + ...</pre></blockquote> > > +makes it obvious that <code>elt</code> is a pair and gives the types of > > +<code>elt.first</code> and <code>elt.second</code>. In contrast: > > +<blockquote><pre>for (const auto &elt : indirect_pool) > > + ...</pre></blockquote> > > +gives no immediate indication what <code>elt</code> is or what can > > +be done with it.</p> > > ...there are countless constructs in C++ 98 as well in C where there > is no such indication yet we don't (and very well can't) try to avoid > using them. Examples include macros, members of structures defined > far away from the point of their use, results of ordinary function > calls, results of overloaded functions or templates, default function > arguments, default template parameters, etc. > > By way of a random example from genrecog.c: > > int_set::iterator end > = std::set_union (trans1->labels.begin (), trans1->labels.end (), > combined->begin (), combined->end (), > next->begin ()); > > There is no immediate indication precisely what type int_set::iterator > is. All we can tell is that that it's some sort of an iterator, and > that should be good enough. It lets us (even forces us to) write code > that satisfies the requirements of the abstraction (whatever it happens > to be), and avoid tying it closely to the implementation. That's > a good thing. > > Unless there is a sound technical reason for avoiding it (e.g., > unacceptable inefficiency or known safety problems) I'd say leave > it to everyone's judgment what convenience features to use. If > something turns out to be a problem we'll deal with it then. > I agree with this. If using 'auto' makes the code harder to read, that's a good comment for code review, but it's hard to write a general rule for this sort of thing. Jason ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Describe coding conventions surrounding "auto" 2020-05-16 2:45 ` Re: Jason Merrill @ 2020-05-16 10:43 ` Richard Sandiford 2020-05-18 16:37 ` Martin Sebor 0 siblings, 1 reply; 29+ messages in thread From: Richard Sandiford @ 2020-05-16 10:43 UTC (permalink / raw) To: Jason Merrill Cc: Martin Sebor, Richard Biener, Richard Biener via Gcc-patches Sorry for the empty subject line earlier... Jason Merrill <jason@redhat.com> writes: > On Fri, May 15, 2020 at 9:47 PM Martin Sebor <msebor@gmail.com> wrote: > >> On 5/15/20 8:08 AM, Richard Sandiford wrote: >> >> Those are all good examples. Mind putting that into a patch >> >> for the coding conventions? >> > How's this? I added "new" expressions as another example of the >> > first category. >> > >> > I'm sure I've missed other good uses, but we can always add to the >> > list later if necessary. >> > >> > Thanks, >> > Richard >> > >> > >> > 0001-Describe-coding-conventions-surrounding-auto.patch >> > >> > From 10b27e367de0fa9d5bf91544385401cdcbdb8c00 Mon Sep 17 00:00:00 2001 >> > From: Richard Sandiford<richard.sandiford@arm.com> >> > Date: Fri, 15 May 2020 14:58:46 +0100 >> > Subject: [PATCH] Describe coding conventions surrounding "auto" >> > >> > --- >> > htdocs/codingconventions.html | 53 +++++++++++++++++++++++++++++++++++ >> > htdocs/codingrationale.html | 17 +++++++++++ >> > 2 files changed, 70 insertions(+) >> > >> > diff --git a/htdocs/codingconventions.html >> b/htdocs/codingconventions.html >> > index f4732ef6..ae49fb91 100644 >> > --- a/htdocs/codingconventions.html >> > +++ b/htdocs/codingconventions.html >> > @@ -51,6 +51,7 @@ the conventions separately from any other changes to >> the code.</p> >> > <li><a href="#Cxx_Language">Language Use</a> >> > <ul> >> > <li><a href="#Variable">Variable Definitions</a></li> >> > + <li><a href="#Auto">Use of <code>auto</code></a></li> >> > <li><a href="#Struct_Use">Struct Definitions</a></li> >> > <li><a href="#Class_Use">Class Definitions</a></li> >> > <li><a href="#Constructors">Constructors and >> Destructors</a></li> >> > @@ -884,6 +885,58 @@ Variables may be simultaneously defined and tested >> in control expressions. >> > <a href="codingrationale.html#variables">Rationale and Discussion</a> >> > </p> >> > >> > +<h4 id="Auto">Use of <code>auto</code></h4> >> > + >> > +<p><code>auto</code> should be used in the following circumstances: >> > +<ul> >> > + <li><p>when the expression gives the C++ type explicitly. For >> example</p> >> > + >> > + <blockquote> >> > +<pre>if (<b>auto *</b>table = dyn_cast <<b>rtx_jump_table_data >> *</b>> (insn)) // OK >> > + ... >> > +if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> >> (insn)) // Avoid >> > + ... >> > +<b>auto *</b>map = new <b>hash_map <tree, size_t></b>; >> // OK >> > +hash_map <tree, size_t> *map = new hash_map <tree, size_t>; >> // Avoid</pre></blockquote> >> > + >> > + <p>This rule does not apply to abbreviated type names embedded in >> > + an identifier, such as the result of <code>tree_to_shwi</code>.</p> >> > + </li> >> > + <li> >> > + <p>when the expression simply provides an alternative view of an >> object >> > + and is bound to a read-only temporary. For example:</p> >> > + >> > + <blockquote> >> > +<pre><b>auto</b> wioff = <b>wi::to_wide (off);</b> // OK >> > +wide_int wioff = wi::to_wide (off); // Avoid if wioff is read-only >> > +<b>auto</b> minus1 = <b>std::shwi (-1, prec);</b> // OK >> > +wide_int minus1 = std::shwi (-1, prec); // Avoid if minus1 is >> read-only</pre></blockquote> >> > + >> > + <p>In principle this rule applies to other views of an object too, >> > + such as a reversed view of a list, or a sequential view of a >> > + <code>hash_set</code>. It does not apply to general >> temporaries.</p> >> > + </li> >> > + <li> >> > + <p>the type of an iterator. For example:</p> >> > + >> > + <blockquote> >> > +<pre><b>auto</b> it = <b>std::find (names.begin (), names.end (), >> needle)</b>; // OK >> > +vector <name_map>::iterator it = std::find (names.begin (), >> > + names.end (), needle); // >> Avoid</pre></blockquote> >> > + </li> >> > + <li> >> > + <p>the type of a lambda expression. For example:</p> >> > + >> > + <blockquote> >> > +<pre><b>auto</b> f = <b>[] (int x) { return x + 1; }</b>; // >> OK</pre></blockquote> >> > + </li> >> > +</ul></p> >> > + >> > +<p><code>auto</code> should <b>not</b> be used in other contexts.</p> >> >> This seems like a severe (and unnecessary) restriction... >> >> > + >> > +<p> >> > +<a href="codingrationale.html#auto">Rationale and Discussion</a> >> > +</p> >> > >> > <h4 id="Struct_Use">Struct Definitions</h4> >> > >> > diff --git a/htdocs/codingrationale.html b/htdocs/codingrationale.html >> > index 0b44f1da..a919023c 100644 >> > --- a/htdocs/codingrationale.html >> > +++ b/htdocs/codingrationale.html >> > @@ -50,6 +50,23 @@ if (info *q = get_any_available_info ()) { >> > } >> > </code></pre></blockquote> >> > >> > +<h4 id="auto">Use of <code>auto</code></h4> >> > + >> > +<p>The reason for preferring <code>auto</code> in expressions like: >> > +<blockquote><pre>auto wioff = wi::to_wide (off);</pre></blockquote> >> > +is that using the natural type of the expression is more efficient than >> > +converting it to types like <code>wide_int</code>.</p> >> > + >> > +<p>The reason for excluding other uses of <code>auto</code> is that >> > +in most other cases the type carries useful information. For example: >> > +<blockquote><pre>for (const std::pair <const char *, tree> >> &elt : indirect_pool) >> > + ...</pre></blockquote> >> > +makes it obvious that <code>elt</code> is a pair and gives the types of >> > +<code>elt.first</code> and <code>elt.second</code>. In contrast: >> > +<blockquote><pre>for (const auto &elt : indirect_pool) >> > + ...</pre></blockquote> >> > +gives no immediate indication what <code>elt</code> is or what can >> > +be done with it.</p> >> >> ...there are countless constructs in C++ 98 as well in C where there >> is no such indication yet we don't (and very well can't) try to avoid >> using them. Examples include macros, members of structures defined >> far away from the point of their use, results of ordinary function >> calls, results of overloaded functions or templates, default function >> arguments, default template parameters, etc. >> >> By way of a random example from genrecog.c: >> >> int_set::iterator end >> = std::set_union (trans1->labels.begin (), trans1->labels.end (), >> combined->begin (), combined->end (), >> next->begin ()); >> >> There is no immediate indication precisely what type int_set::iterator >> is. All we can tell is that that it's some sort of an iterator, and >> that should be good enough. It lets us (even forces us to) write code >> that satisfies the requirements of the abstraction (whatever it happens >> to be), and avoid tying it closely to the implementation. That's >> a good thing. Do you mean that this example should or shouldn't use "auto"? Iterators are included in the list above, so the idea was that using "auto" would be the recommended style here. >> Unless there is a sound technical reason for avoiding it (e.g., >> unacceptable inefficiency or known safety problems) I'd say leave >> it to everyone's judgment what convenience features to use. If >> something turns out to be a problem we'll deal with it then. But using "auto" is never going to be an efficiency concern, and probably not a safety concern. So in the case of "auto", using that principle would basically come down to "when to use auto is purely a judgement call". I don't see how we can get consistency with that kind of approach. Or is the argument that we're (or I'm :-)) worrying too much about consistency and we should just go with the flow? If we do treat it as a pure judgement call, the problem then is: who's judgement matters most here? The author's or the reviewer's? Should the reviewer respect the choice of the author even if they don't personally agree with it, given that there are no technical issues at stake? > I agree with this. If using 'auto' makes the code harder to read, that's a > good comment for code review, but it's hard to write a general rule for > this sort of thing. I think the downsides of a pure "it's up to the reviewer" approach are: - Every contributor and reviewer has their own opinions. The point of coding standards is to aim for consistency in a large project despite these various and often conflicting opinions. - If it is (or gives the impression of being) purely down to the individual opinions of the reviewer, things can get awkward. E.g. -- and maybe I shouldn't use a personal example like this -- I remember Martin S has complained a few times when, in code review, Jeff has asked for changes to match existing GCC style (e.g. to use upper case instead of CamelCase for enum values). In all the examples I saw, Jeff was asking for what I understood the GCC style to be. But Martin gave the impression of being quite annoyed at having to make these changes, talking in the "enum case" about having to learn individual reviewers' preferences. I think that kind of reaction is inevitable if we don't try to agree common standards. If things aren't written down, requests from reviewers not to use a feature can seem arbitrary or whimsical even when they're not. The same goes for requests to follow conventions that have built up over time without being written down. The temptation can be to push back against code review comments that aren't purely technical in nature. If we take this approach, then over time (because of the different opinions of different contributors) there is likely to be code in the codebase that uses "auto" in the way that any given person wants to use it. It will seem even more arbitrary to reject the use of "auto" in one context if it has already been used elsewhere in another similar context. So over time, we'll either get more review friction or come to an understanding that the use of "auto" isn't a suitable comment for code review after all. I think the latter is more likely. It can even be framed positively: reviewers should respect the choice of author to use "auto" whenever they like, and not impose their own opinions. But while individual patches are one source of hard-to-read code, another is when different styles build up over time. And that's what I'd really like to avoid. Having a consistent style in itself makes code easier to read. It also makes it easier to modify, because there's less guesswork involved. Like I say, this list isn't supposed to be fixed for all time. We can add to it whenever a good missing case crops up. And the template one that you (Jason) mentioned in the earlier message is definitely a good one :-) And to be clear, this is in no way an "anti-auto" drive. It's purely about taking one feature that is (rightly) going to be used often and trying to add some consistency and predictability around it. Thanks, Richard ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Describe coding conventions surrounding "auto" 2020-05-16 10:43 ` [PATCH] Describe coding conventions surrounding "auto" Richard Sandiford @ 2020-05-18 16:37 ` Martin Sebor 2020-05-18 18:02 ` Richard Sandiford 0 siblings, 1 reply; 29+ messages in thread From: Martin Sebor @ 2020-05-18 16:37 UTC (permalink / raw) To: Jason Merrill, Richard Biener, Richard Biener via Gcc-patches, richard.sandiford On 5/16/20 4:43 AM, Richard Sandiford wrote: > Sorry for the empty subject line earlier... > > Jason Merrill <jason@redhat.com> writes: >> On Fri, May 15, 2020 at 9:47 PM Martin Sebor <msebor@gmail.com> wrote: >> >>> On 5/15/20 8:08 AM, Richard Sandiford wrote: >>>>> Those are all good examples. Mind putting that into a patch >>>>> for the coding conventions? >>>> How's this? I added "new" expressions as another example of the >>>> first category. >>>> >>>> I'm sure I've missed other good uses, but we can always add to the >>>> list later if necessary. >>>> >>>> Thanks, >>>> Richard >>>> >>>> >>>> 0001-Describe-coding-conventions-surrounding-auto.patch >>>> >>>> From 10b27e367de0fa9d5bf91544385401cdcbdb8c00 Mon Sep 17 00:00:00 2001 >>>> From: Richard Sandiford<richard.sandiford@arm.com> >>>> Date: Fri, 15 May 2020 14:58:46 +0100 >>>> Subject: [PATCH] Describe coding conventions surrounding "auto" >>>> >>>> --- >>>> htdocs/codingconventions.html | 53 +++++++++++++++++++++++++++++++++++ >>>> htdocs/codingrationale.html | 17 +++++++++++ >>>> 2 files changed, 70 insertions(+) >>>> >>>> diff --git a/htdocs/codingconventions.html >>> b/htdocs/codingconventions.html >>>> index f4732ef6..ae49fb91 100644 >>>> --- a/htdocs/codingconventions.html >>>> +++ b/htdocs/codingconventions.html >>>> @@ -51,6 +51,7 @@ the conventions separately from any other changes to >>> the code.</p> >>>> <li><a href="#Cxx_Language">Language Use</a> >>>> <ul> >>>> <li><a href="#Variable">Variable Definitions</a></li> >>>> + <li><a href="#Auto">Use of <code>auto</code></a></li> >>>> <li><a href="#Struct_Use">Struct Definitions</a></li> >>>> <li><a href="#Class_Use">Class Definitions</a></li> >>>> <li><a href="#Constructors">Constructors and >>> Destructors</a></li> >>>> @@ -884,6 +885,58 @@ Variables may be simultaneously defined and tested >>> in control expressions. >>>> <a href="codingrationale.html#variables">Rationale and Discussion</a> >>>> </p> >>>> >>>> +<h4 id="Auto">Use of <code>auto</code></h4> >>>> + >>>> +<p><code>auto</code> should be used in the following circumstances: >>>> +<ul> >>>> + <li><p>when the expression gives the C++ type explicitly. For >>> example</p> >>>> + >>>> + <blockquote> >>>> +<pre>if (<b>auto *</b>table = dyn_cast <<b>rtx_jump_table_data >>> *</b>> (insn)) // OK >>>> + ... >>>> +if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> >>> (insn)) // Avoid >>>> + ... >>>> +<b>auto *</b>map = new <b>hash_map <tree, size_t></b>; >>> // OK >>>> +hash_map <tree, size_t> *map = new hash_map <tree, size_t>; >>> // Avoid</pre></blockquote> >>>> + >>>> + <p>This rule does not apply to abbreviated type names embedded in >>>> + an identifier, such as the result of <code>tree_to_shwi</code>.</p> >>>> + </li> >>>> + <li> >>>> + <p>when the expression simply provides an alternative view of an >>> object >>>> + and is bound to a read-only temporary. For example:</p> >>>> + >>>> + <blockquote> >>>> +<pre><b>auto</b> wioff = <b>wi::to_wide (off);</b> // OK >>>> +wide_int wioff = wi::to_wide (off); // Avoid if wioff is read-only >>>> +<b>auto</b> minus1 = <b>std::shwi (-1, prec);</b> // OK >>>> +wide_int minus1 = std::shwi (-1, prec); // Avoid if minus1 is >>> read-only</pre></blockquote> >>>> + >>>> + <p>In principle this rule applies to other views of an object too, >>>> + such as a reversed view of a list, or a sequential view of a >>>> + <code>hash_set</code>. It does not apply to general >>> temporaries.</p> >>>> + </li> >>>> + <li> >>>> + <p>the type of an iterator. For example:</p> >>>> + >>>> + <blockquote> >>>> +<pre><b>auto</b> it = <b>std::find (names.begin (), names.end (), >>> needle)</b>; // OK >>>> +vector <name_map>::iterator it = std::find (names.begin (), >>>> + names.end (), needle); // >>> Avoid</pre></blockquote> >>>> + </li> >>>> + <li> >>>> + <p>the type of a lambda expression. For example:</p> >>>> + >>>> + <blockquote> >>>> +<pre><b>auto</b> f = <b>[] (int x) { return x + 1; }</b>; // >>> OK</pre></blockquote> >>>> + </li> >>>> +</ul></p> >>>> + >>>> +<p><code>auto</code> should <b>not</b> be used in other contexts.</p> >>> >>> This seems like a severe (and unnecessary) restriction... >>> >>>> + >>>> +<p> >>>> +<a href="codingrationale.html#auto">Rationale and Discussion</a> >>>> +</p> >>>> >>>> <h4 id="Struct_Use">Struct Definitions</h4> >>>> >>>> diff --git a/htdocs/codingrationale.html b/htdocs/codingrationale.html >>>> index 0b44f1da..a919023c 100644 >>>> --- a/htdocs/codingrationale.html >>>> +++ b/htdocs/codingrationale.html >>>> @@ -50,6 +50,23 @@ if (info *q = get_any_available_info ()) { >>>> } >>>> </code></pre></blockquote> >>>> >>>> +<h4 id="auto">Use of <code>auto</code></h4> >>>> + >>>> +<p>The reason for preferring <code>auto</code> in expressions like: >>>> +<blockquote><pre>auto wioff = wi::to_wide (off);</pre></blockquote> >>>> +is that using the natural type of the expression is more efficient than >>>> +converting it to types like <code>wide_int</code>.</p> >>>> + >>>> +<p>The reason for excluding other uses of <code>auto</code> is that >>>> +in most other cases the type carries useful information. For example: >>>> +<blockquote><pre>for (const std::pair <const char *, tree> >>> &elt : indirect_pool) >>>> + ...</pre></blockquote> >>>> +makes it obvious that <code>elt</code> is a pair and gives the types of >>>> +<code>elt.first</code> and <code>elt.second</code>. In contrast: >>>> +<blockquote><pre>for (const auto &elt : indirect_pool) >>>> + ...</pre></blockquote> >>>> +gives no immediate indication what <code>elt</code> is or what can >>>> +be done with it.</p> >>> >>> ...there are countless constructs in C++ 98 as well in C where there >>> is no such indication yet we don't (and very well can't) try to avoid >>> using them. Examples include macros, members of structures defined >>> far away from the point of their use, results of ordinary function >>> calls, results of overloaded functions or templates, default function >>> arguments, default template parameters, etc. >>> >>> By way of a random example from genrecog.c: >>> >>> int_set::iterator end >>> = std::set_union (trans1->labels.begin (), trans1->labels.end (), >>> combined->begin (), combined->end (), >>> next->begin ()); >>> >>> There is no immediate indication precisely what type int_set::iterator >>> is. All we can tell is that that it's some sort of an iterator, and >>> that should be good enough. It lets us (even forces us to) write code >>> that satisfies the requirements of the abstraction (whatever it happens >>> to be), and avoid tying it closely to the implementation. That's >>> a good thing. > > Do you mean that this example should or shouldn't use "auto"? > Iterators are included in the list above, so the idea was that using > "auto" would be the recommended style here. I meant it as a general example where the exact type isn't (and isn't supposed to be) apparent to the caller because it's an implementation detail. Similarly, if an API defines a typedef string_tree_pair for std::pair<const char*, tree>, it's the typedef that's meant to be used in preference to what it expands to. >>> Unless there is a sound technical reason for avoiding it (e.g., >>> unacceptable inefficiency or known safety problems) I'd say leave >>> it to everyone's judgment what convenience features to use. If >>> something turns out to be a problem we'll deal with it then. > > But using "auto" is never going to be an efficiency concern, > and probably not a safety concern. So in the case of "auto", > using that principle would basically come down to "when to use > auto is purely a judgement call". > > I don't see how we can get consistency with that kind of approach. > Or is the argument that we're (or I'm :-)) worrying too much about > consistency and we should just go with the flow? > > If we do treat it as a pure judgement call, the problem then is: > who's judgement matters most here? The author's or the reviewer's? > Should the reviewer respect the choice of the author even if they > don't personally agree with it, given that there are no technical > issues at stake? When no technical concerns are at stake contributors should be free to use the language as they feel is appropriate. The fewer hurdles we put in place the more time we will be able to focus on getting the many technical details right, and the more fun it will be to contribute. If a consensus emerges that some uses are generally best avoided then it might be appropriate to reflect it in the coding conventions. But I'd hope that wouldn't happen before we've had time to gain experience with it. Martin > >> I agree with this. If using 'auto' makes the code harder to read, that's a >> good comment for code review, but it's hard to write a general rule for >> this sort of thing. > > I think the downsides of a pure "it's up to the reviewer" approach are: > > - Every contributor and reviewer has their own opinions. The point of > coding standards is to aim for consistency in a large project despite > these various and often conflicting opinions. > > - If it is (or gives the impression of being) purely down to the > individual opinions of the reviewer, things can get awkward. > E.g. -- and maybe I shouldn't use a personal example like this -- > I remember Martin S has complained a few times when, in code review, > Jeff has asked for changes to match existing GCC style (e.g. to use > upper case instead of CamelCase for enum values). In all the examples > I saw, Jeff was asking for what I understood the GCC style to be. > But Martin gave the impression of being quite annoyed at having to > make these changes, talking in the "enum case" about having to learn > individual reviewers' preferences. > > I think that kind of reaction is inevitable if we don't try to agree > common standards. If things aren't written down, requests from reviewers > not to use a feature can seem arbitrary or whimsical even when they're not. > The same goes for requests to follow conventions that have built up > over time without being written down. The temptation can be to push > back against code review comments that aren't purely technical in nature. > > If we take this approach, then over time (because of the different > opinions of different contributors) there is likely to be code in the > codebase that uses "auto" in the way that any given person wants to > use it. It will seem even more arbitrary to reject the use of "auto" > in one context if it has already been used elsewhere in another > similar context. So over time, we'll either get more review friction > or come to an understanding that the use of "auto" isn't a suitable > comment for code review after all. > > I think the latter is more likely. It can even be framed positively: > reviewers should respect the choice of author to use "auto" whenever > they like, and not impose their own opinions. > > But while individual patches are one source of hard-to-read code, > another is when different styles build up over time. And that's what > I'd really like to avoid. > > Having a consistent style in itself makes code easier to read. > It also makes it easier to modify, because there's less guesswork > involved. > > Like I say, this list isn't supposed to be fixed for all time. > We can add to it whenever a good missing case crops up. And the > template one that you (Jason) mentioned in the earlier message is > definitely a good one :-) > > And to be clear, this is in no way an "anti-auto" drive. It's purely > about taking one feature that is (rightly) going to be used often > and trying to add some consistency and predictability around it. > > Thanks, > Richard > ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Describe coding conventions surrounding "auto" 2020-05-18 16:37 ` Martin Sebor @ 2020-05-18 18:02 ` Richard Sandiford 2020-05-18 18:42 ` Jason Merrill 2020-05-18 22:51 ` Martin Sebor 0 siblings, 2 replies; 29+ messages in thread From: Richard Sandiford @ 2020-05-18 18:02 UTC (permalink / raw) To: Martin Sebor Cc: Jason Merrill, Richard Biener, Richard Biener via Gcc-patches Martin Sebor <msebor@gmail.com> writes: > On 5/16/20 4:43 AM, Richard Sandiford wrote: >> Sorry for the empty subject line earlier... >> >> Jason Merrill <jason@redhat.com> writes: >>> On Fri, May 15, 2020 at 9:47 PM Martin Sebor <msebor@gmail.com> wrote: >>> >>>> On 5/15/20 8:08 AM, Richard Sandiford wrote: >>>>>> Those are all good examples. Mind putting that into a patch >>>>>> for the coding conventions? >>>>> How's this? I added "new" expressions as another example of the >>>>> first category. >>>>> >>>>> I'm sure I've missed other good uses, but we can always add to the >>>>> list later if necessary. >>>>> >>>>> Thanks, >>>>> Richard >>>>> >>>>> >>>>> 0001-Describe-coding-conventions-surrounding-auto.patch >>>>> >>>>> From 10b27e367de0fa9d5bf91544385401cdcbdb8c00 Mon Sep 17 00:00:00 2001 >>>>> From: Richard Sandiford<richard.sandiford@arm.com> >>>>> Date: Fri, 15 May 2020 14:58:46 +0100 >>>>> Subject: [PATCH] Describe coding conventions surrounding "auto" >>>>> >>>>> --- >>>>> htdocs/codingconventions.html | 53 +++++++++++++++++++++++++++++++++++ >>>>> htdocs/codingrationale.html | 17 +++++++++++ >>>>> 2 files changed, 70 insertions(+) >>>>> >>>>> diff --git a/htdocs/codingconventions.html >>>> b/htdocs/codingconventions.html >>>>> index f4732ef6..ae49fb91 100644 >>>>> --- a/htdocs/codingconventions.html >>>>> +++ b/htdocs/codingconventions.html >>>>> @@ -51,6 +51,7 @@ the conventions separately from any other changes to >>>> the code.</p> >>>>> <li><a href="#Cxx_Language">Language Use</a> >>>>> <ul> >>>>> <li><a href="#Variable">Variable Definitions</a></li> >>>>> + <li><a href="#Auto">Use of <code>auto</code></a></li> >>>>> <li><a href="#Struct_Use">Struct Definitions</a></li> >>>>> <li><a href="#Class_Use">Class Definitions</a></li> >>>>> <li><a href="#Constructors">Constructors and >>>> Destructors</a></li> >>>>> @@ -884,6 +885,58 @@ Variables may be simultaneously defined and tested >>>> in control expressions. >>>>> <a href="codingrationale.html#variables">Rationale and Discussion</a> >>>>> </p> >>>>> >>>>> +<h4 id="Auto">Use of <code>auto</code></h4> >>>>> + >>>>> +<p><code>auto</code> should be used in the following circumstances: >>>>> +<ul> >>>>> + <li><p>when the expression gives the C++ type explicitly. For >>>> example</p> >>>>> + >>>>> + <blockquote> >>>>> +<pre>if (<b>auto *</b>table = dyn_cast <<b>rtx_jump_table_data >>>> *</b>> (insn)) // OK >>>>> + ... >>>>> +if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> >>>> (insn)) // Avoid >>>>> + ... >>>>> +<b>auto *</b>map = new <b>hash_map <tree, size_t></b>; >>>> // OK >>>>> +hash_map <tree, size_t> *map = new hash_map <tree, size_t>; >>>> // Avoid</pre></blockquote> >>>>> + >>>>> + <p>This rule does not apply to abbreviated type names embedded in >>>>> + an identifier, such as the result of <code>tree_to_shwi</code>.</p> >>>>> + </li> >>>>> + <li> >>>>> + <p>when the expression simply provides an alternative view of an >>>> object >>>>> + and is bound to a read-only temporary. For example:</p> >>>>> + >>>>> + <blockquote> >>>>> +<pre><b>auto</b> wioff = <b>wi::to_wide (off);</b> // OK >>>>> +wide_int wioff = wi::to_wide (off); // Avoid if wioff is read-only >>>>> +<b>auto</b> minus1 = <b>std::shwi (-1, prec);</b> // OK >>>>> +wide_int minus1 = std::shwi (-1, prec); // Avoid if minus1 is >>>> read-only</pre></blockquote> >>>>> + >>>>> + <p>In principle this rule applies to other views of an object too, >>>>> + such as a reversed view of a list, or a sequential view of a >>>>> + <code>hash_set</code>. It does not apply to general >>>> temporaries.</p> >>>>> + </li> >>>>> + <li> >>>>> + <p>the type of an iterator. For example:</p> >>>>> + >>>>> + <blockquote> >>>>> +<pre><b>auto</b> it = <b>std::find (names.begin (), names.end (), >>>> needle)</b>; // OK >>>>> +vector <name_map>::iterator it = std::find (names.begin (), >>>>> + names.end (), needle); // >>>> Avoid</pre></blockquote> >>>>> + </li> >>>>> + <li> >>>>> + <p>the type of a lambda expression. For example:</p> >>>>> + >>>>> + <blockquote> >>>>> +<pre><b>auto</b> f = <b>[] (int x) { return x + 1; }</b>; // >>>> OK</pre></blockquote> >>>>> + </li> >>>>> +</ul></p> >>>>> + >>>>> +<p><code>auto</code> should <b>not</b> be used in other contexts.</p> >>>> >>>> This seems like a severe (and unnecessary) restriction... >>>> >>>>> + >>>>> +<p> >>>>> +<a href="codingrationale.html#auto">Rationale and Discussion</a> >>>>> +</p> >>>>> >>>>> <h4 id="Struct_Use">Struct Definitions</h4> >>>>> >>>>> diff --git a/htdocs/codingrationale.html b/htdocs/codingrationale.html >>>>> index 0b44f1da..a919023c 100644 >>>>> --- a/htdocs/codingrationale.html >>>>> +++ b/htdocs/codingrationale.html >>>>> @@ -50,6 +50,23 @@ if (info *q = get_any_available_info ()) { >>>>> } >>>>> </code></pre></blockquote> >>>>> >>>>> +<h4 id="auto">Use of <code>auto</code></h4> >>>>> + >>>>> +<p>The reason for preferring <code>auto</code> in expressions like: >>>>> +<blockquote><pre>auto wioff = wi::to_wide (off);</pre></blockquote> >>>>> +is that using the natural type of the expression is more efficient than >>>>> +converting it to types like <code>wide_int</code>.</p> >>>>> + >>>>> +<p>The reason for excluding other uses of <code>auto</code> is that >>>>> +in most other cases the type carries useful information. For example: >>>>> +<blockquote><pre>for (const std::pair <const char *, tree> >>>> &elt : indirect_pool) >>>>> + ...</pre></blockquote> >>>>> +makes it obvious that <code>elt</code> is a pair and gives the types of >>>>> +<code>elt.first</code> and <code>elt.second</code>. In contrast: >>>>> +<blockquote><pre>for (const auto &elt : indirect_pool) >>>>> + ...</pre></blockquote> >>>>> +gives no immediate indication what <code>elt</code> is or what can >>>>> +be done with it.</p> >>>> >>>> ...there are countless constructs in C++ 98 as well in C where there >>>> is no such indication yet we don't (and very well can't) try to avoid >>>> using them. Examples include macros, members of structures defined >>>> far away from the point of their use, results of ordinary function >>>> calls, results of overloaded functions or templates, default function >>>> arguments, default template parameters, etc. >>>> >>>> By way of a random example from genrecog.c: >>>> >>>> int_set::iterator end >>>> = std::set_union (trans1->labels.begin (), trans1->labels.end (), >>>> combined->begin (), combined->end (), >>>> next->begin ()); >>>> >>>> There is no immediate indication precisely what type int_set::iterator >>>> is. All we can tell is that that it's some sort of an iterator, and >>>> that should be good enough. It lets us (even forces us to) write code >>>> that satisfies the requirements of the abstraction (whatever it happens >>>> to be), and avoid tying it closely to the implementation. That's >>>> a good thing. >> >> Do you mean that this example should or shouldn't use "auto"? >> Iterators are included in the list above, so the idea was that using >> "auto" would be the recommended style here. > > I meant it as a general example where the exact type isn't (and isn't > supposed to be) apparent to the caller because it's an implementation > detail. But like I say, the proposal was that this example should use "auto", and it sounds like you might agree. In that case I don't think the example really helps make the decision about whether the coding standards are useful or not. Do you have other examples that you think would be better written using "auto" that aren't covered by the list, and aren't covered by Jason's point about template-dependent types? > Similarly, if an API defines a typedef string_tree_pair for > std::pair<const char*, tree>, it's the typedef that's meant to > be used in preference to what it expands to. Using the typedef would be fine. string_tree_pair describes the type pretty well: it's still obvious that "elt" is a pair, and what "elt.first" and "elt.second" are. Typedefs that don't describe the type well are bad typedefs. :-) The distinction is more between whether "auto" should be used or whether an explicit type should be used, rather than between different ways of writing the explicit type. I agree it'd be worth adding "string_tree_pair" to the rationale too, to make it clearer that this isn't about expanding the typedefs as far they'll go. >>>> Unless there is a sound technical reason for avoiding it (e.g., >>>> unacceptable inefficiency or known safety problems) I'd say leave >>>> it to everyone's judgment what convenience features to use. If >>>> something turns out to be a problem we'll deal with it then. >> >> But using "auto" is never going to be an efficiency concern, >> and probably not a safety concern. So in the case of "auto", >> using that principle would basically come down to "when to use >> auto is purely a judgement call". >> >> I don't see how we can get consistency with that kind of approach. >> Or is the argument that we're (or I'm :-)) worrying too much about >> consistency and we should just go with the flow? >> >> If we do treat it as a pure judgement call, the problem then is: >> who's judgement matters most here? The author's or the reviewer's? >> Should the reviewer respect the choice of the author even if they >> don't personally agree with it, given that there are no technical >> issues at stake? > > When no technical concerns are at stake contributors should be free > to use the language as they feel is appropriate. The fewer hurdles > we put in place the more time we will be able to focus on getting > the many technical details right, and the more fun it will be to > contribute. I agree that's a self-consistent approach. So I think at this point three options have been suggested: (1) Try to add coding conventions around when "auto" should and shouldn't be used. (2) Be broadly accepting of "auto", but reject cases that seem hard to read during code review. (3) Allow "auto" to be used anywhere that a contributor thinks is appropriate. Since the decision isn't usually a technical one, reviewers would be encouraged to respect the author's choice and be discouraged from asking for a different choice. Personally my preference order is (1), (3) and (2). I think (2) is the worst of both worlds: it wouldn't give a consistent codebase, because whether something is seen as hard to read would vary based on the people involved. And it wouldn't give predictability because contributors would only know whether a use of "auto" is acceptable by submitting a patch and seeing what the reaction is. (3) also wouldn't give a consistent codebase, but it would give more predictable reviews. > If a consensus emerges that some uses are generally > best avoided then it might be appropriate to reflect it in > the coding conventions. But I'd hope that wouldn't happen before > we've had time to gain experience with it. I think the difference here is between whether we start with a list of acceptable uses and expand it with experience, or whether we start by assuming all uses are acceptable and restrict it with experience. The reason I think the former is better is that we're starting with a codebase that doesn't use "auto" at all. So when the switch is flipped and the code is C++11, we'll have a C++11 codebase that never uses "auto". Given that starting point, it seems more natural to list cases in which "auto" should be used (as a change to the status quo) rather than those in which it shouldn't. But besides Jason's point about template-dependent types, I think the objections have been to the idea of having coding conventions around this in principle, rather than to the actual list. So at this point I'm not sure whether the proposed list would actually stop someone from using "auto" in the way they'd typically want to use it, and if so, what those use cases are. Like I say, the list was only supposed to be a starting point, based on my guess at what would be broadly acceptable. So if the chosen cases are themselves a sticking point, suggestions for additions or modifications are definitely welcome. And the list can be expanded later if new uses crop up. That's still an improvement on how things were until now, where "auto" couldn't be used at all. Thanks, Richard ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Describe coding conventions surrounding "auto" 2020-05-18 18:02 ` Richard Sandiford @ 2020-05-18 18:42 ` Jason Merrill 2020-05-18 22:51 ` Martin Sebor 1 sibling, 0 replies; 29+ messages in thread From: Jason Merrill @ 2020-05-18 18:42 UTC (permalink / raw) To: Martin Sebor, Richard Biener, Richard Biener via Gcc-patches, richard.sandiford On 5/18/20 2:02 PM, Richard Sandiford wrote: > Martin Sebor <msebor@gmail.com> writes: >> On 5/16/20 4:43 AM, Richard Sandiford wrote: >>> Sorry for the empty subject line earlier... >>> >>> Jason Merrill <jason@redhat.com> writes: >>>> On Fri, May 15, 2020 at 9:47 PM Martin Sebor <msebor@gmail.com> wrote: >>>> >>>>> On 5/15/20 8:08 AM, Richard Sandiford wrote: >>>>>>> Those are all good examples. Mind putting that into a patch >>>>>>> for the coding conventions? >>>>>> How's this? I added "new" expressions as another example of the >>>>>> first category. >>>>>> >>>>>> I'm sure I've missed other good uses, but we can always add to the >>>>>> list later if necessary. >>>>>> >>>>>> Thanks, >>>>>> Richard >>>>>> >>>>>> >>>>>> 0001-Describe-coding-conventions-surrounding-auto.patch >>>>>> >>>>>> From 10b27e367de0fa9d5bf91544385401cdcbdb8c00 Mon Sep 17 00:00:00 2001 >>>>>> From: Richard Sandiford<richard.sandiford@arm.com> >>>>>> Date: Fri, 15 May 2020 14:58:46 +0100 >>>>>> Subject: [PATCH] Describe coding conventions surrounding "auto" >>>>>> >>>>>> --- >>>>>> htdocs/codingconventions.html | 53 +++++++++++++++++++++++++++++++++++ >>>>>> htdocs/codingrationale.html | 17 +++++++++++ >>>>>> 2 files changed, 70 insertions(+) >>>>>> >>>>>> diff --git a/htdocs/codingconventions.html >>>>> b/htdocs/codingconventions.html >>>>>> index f4732ef6..ae49fb91 100644 >>>>>> --- a/htdocs/codingconventions.html >>>>>> +++ b/htdocs/codingconventions.html >>>>>> @@ -51,6 +51,7 @@ the conventions separately from any other changes to >>>>> the code.</p> >>>>>> <li><a href="#Cxx_Language">Language Use</a> >>>>>> <ul> >>>>>> <li><a href="#Variable">Variable Definitions</a></li> >>>>>> + <li><a href="#Auto">Use of <code>auto</code></a></li> >>>>>> <li><a href="#Struct_Use">Struct Definitions</a></li> >>>>>> <li><a href="#Class_Use">Class Definitions</a></li> >>>>>> <li><a href="#Constructors">Constructors and >>>>> Destructors</a></li> >>>>>> @@ -884,6 +885,58 @@ Variables may be simultaneously defined and tested >>>>> in control expressions. >>>>>> <a href="codingrationale.html#variables">Rationale and Discussion</a> >>>>>> </p> >>>>>> >>>>>> +<h4 id="Auto">Use of <code>auto</code></h4> >>>>>> + >>>>>> +<p><code>auto</code> should be used in the following circumstances: >>>>>> +<ul> >>>>>> + <li><p>when the expression gives the C++ type explicitly. For >>>>> example</p> >>>>>> + >>>>>> + <blockquote> >>>>>> +<pre>if (<b>auto *</b>table = dyn_cast <<b>rtx_jump_table_data >>>>> *</b>> (insn)) // OK >>>>>> + ... >>>>>> +if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> >>>>> (insn)) // Avoid >>>>>> + ... >>>>>> +<b>auto *</b>map = new <b>hash_map <tree, size_t></b>; >>>>> // OK >>>>>> +hash_map <tree, size_t> *map = new hash_map <tree, size_t>; >>>>> // Avoid</pre></blockquote> >>>>>> + >>>>>> + <p>This rule does not apply to abbreviated type names embedded in >>>>>> + an identifier, such as the result of <code>tree_to_shwi</code>.</p> >>>>>> + </li> >>>>>> + <li> >>>>>> + <p>when the expression simply provides an alternative view of an >>>>> object >>>>>> + and is bound to a read-only temporary. For example:</p> >>>>>> + >>>>>> + <blockquote> >>>>>> +<pre><b>auto</b> wioff = <b>wi::to_wide (off);</b> // OK >>>>>> +wide_int wioff = wi::to_wide (off); // Avoid if wioff is read-only >>>>>> +<b>auto</b> minus1 = <b>std::shwi (-1, prec);</b> // OK >>>>>> +wide_int minus1 = std::shwi (-1, prec); // Avoid if minus1 is >>>>> read-only</pre></blockquote> >>>>>> + >>>>>> + <p>In principle this rule applies to other views of an object too, >>>>>> + such as a reversed view of a list, or a sequential view of a >>>>>> + <code>hash_set</code>. It does not apply to general >>>>> temporaries.</p> >>>>>> + </li> >>>>>> + <li> >>>>>> + <p>the type of an iterator. For example:</p> >>>>>> + >>>>>> + <blockquote> >>>>>> +<pre><b>auto</b> it = <b>std::find (names.begin (), names.end (), >>>>> needle)</b>; // OK >>>>>> +vector <name_map>::iterator it = std::find (names.begin (), >>>>>> + names.end (), needle); // >>>>> Avoid</pre></blockquote> >>>>>> + </li> >>>>>> + <li> >>>>>> + <p>the type of a lambda expression. For example:</p> >>>>>> + >>>>>> + <blockquote> >>>>>> +<pre><b>auto</b> f = <b>[] (int x) { return x + 1; }</b>; // >>>>> OK</pre></blockquote> >>>>>> + </li> >>>>>> +</ul></p> >>>>>> + >>>>>> +<p><code>auto</code> should <b>not</b> be used in other contexts.</p> >>>>> >>>>> This seems like a severe (and unnecessary) restriction... >>>>> >>>>>> + >>>>>> +<p> >>>>>> +<a href="codingrationale.html#auto">Rationale and Discussion</a> >>>>>> +</p> >>>>>> >>>>>> <h4 id="Struct_Use">Struct Definitions</h4> >>>>>> >>>>>> diff --git a/htdocs/codingrationale.html b/htdocs/codingrationale.html >>>>>> index 0b44f1da..a919023c 100644 >>>>>> --- a/htdocs/codingrationale.html >>>>>> +++ b/htdocs/codingrationale.html >>>>>> @@ -50,6 +50,23 @@ if (info *q = get_any_available_info ()) { >>>>>> } >>>>>> </code></pre></blockquote> >>>>>> >>>>>> +<h4 id="auto">Use of <code>auto</code></h4> >>>>>> + >>>>>> +<p>The reason for preferring <code>auto</code> in expressions like: >>>>>> +<blockquote><pre>auto wioff = wi::to_wide (off);</pre></blockquote> >>>>>> +is that using the natural type of the expression is more efficient than >>>>>> +converting it to types like <code>wide_int</code>.</p> >>>>>> + >>>>>> +<p>The reason for excluding other uses of <code>auto</code> is that >>>>>> +in most other cases the type carries useful information. For example: >>>>>> +<blockquote><pre>for (const std::pair <const char *, tree> >>>>> &elt : indirect_pool) >>>>>> + ...</pre></blockquote> >>>>>> +makes it obvious that <code>elt</code> is a pair and gives the types of >>>>>> +<code>elt.first</code> and <code>elt.second</code>. In contrast: >>>>>> +<blockquote><pre>for (const auto &elt : indirect_pool) >>>>>> + ...</pre></blockquote> >>>>>> +gives no immediate indication what <code>elt</code> is or what can >>>>>> +be done with it.</p> >>>>> >>>>> ...there are countless constructs in C++ 98 as well in C where there >>>>> is no such indication yet we don't (and very well can't) try to avoid >>>>> using them. Examples include macros, members of structures defined >>>>> far away from the point of their use, results of ordinary function >>>>> calls, results of overloaded functions or templates, default function >>>>> arguments, default template parameters, etc. >>>>> >>>>> By way of a random example from genrecog.c: >>>>> >>>>> int_set::iterator end >>>>> = std::set_union (trans1->labels.begin (), trans1->labels.end (), >>>>> combined->begin (), combined->end (), >>>>> next->begin ()); >>>>> >>>>> There is no immediate indication precisely what type int_set::iterator >>>>> is. All we can tell is that that it's some sort of an iterator, and >>>>> that should be good enough. It lets us (even forces us to) write code >>>>> that satisfies the requirements of the abstraction (whatever it happens >>>>> to be), and avoid tying it closely to the implementation. That's >>>>> a good thing. >>> >>> Do you mean that this example should or shouldn't use "auto"? >>> Iterators are included in the list above, so the idea was that using >>> "auto" would be the recommended style here. >> >> I meant it as a general example where the exact type isn't (and isn't >> supposed to be) apparent to the caller because it's an implementation >> detail. > > But like I say, the proposal was that this example should use "auto", > and it sounds like you might agree. In that case I don't think the > example really helps make the decision about whether the coding > standards are useful or not. > > Do you have other examples that you think would be better written > using "auto" that aren't covered by the list, and aren't covered > by Jason's point about template-dependent types? > >> Similarly, if an API defines a typedef string_tree_pair for >> std::pair<const char*, tree>, it's the typedef that's meant to >> be used in preference to what it expands to. > > Using the typedef would be fine. string_tree_pair describes > the type pretty well: it's still obvious that "elt" is a pair, > and what "elt.first" and "elt.second" are. Typedefs that don't > describe the type well are bad typedefs. :-) > > The distinction is more between whether "auto" should be used or whether > an explicit type should be used, rather than between different ways of > writing the explicit type. I agree it'd be worth adding "string_tree_pair" > to the rationale too, to make it clearer that this isn't about expanding > the typedefs as far they'll go. > >>>>> Unless there is a sound technical reason for avoiding it (e.g., >>>>> unacceptable inefficiency or known safety problems) I'd say leave >>>>> it to everyone's judgment what convenience features to use. If >>>>> something turns out to be a problem we'll deal with it then. >>> >>> But using "auto" is never going to be an efficiency concern, >>> and probably not a safety concern. So in the case of "auto", >>> using that principle would basically come down to "when to use >>> auto is purely a judgement call". >>> >>> I don't see how we can get consistency with that kind of approach. >>> Or is the argument that we're (or I'm :-)) worrying too much about >>> consistency and we should just go with the flow? >>> >>> If we do treat it as a pure judgement call, the problem then is: >>> who's judgement matters most here? The author's or the reviewer's? >>> Should the reviewer respect the choice of the author even if they >>> don't personally agree with it, given that there are no technical >>> issues at stake? >> >> When no technical concerns are at stake contributors should be free >> to use the language as they feel is appropriate. The fewer hurdles >> we put in place the more time we will be able to focus on getting >> the many technical details right, and the more fun it will be to >> contribute. > > I agree that's a self-consistent approach. So I think at this point > three options have been suggested: > > (1) Try to add coding conventions around when "auto" should and > shouldn't be used. > > (2) Be broadly accepting of "auto", but reject cases that seem > hard to read during code review. > > (3) Allow "auto" to be used anywhere that a contributor thinks is > appropriate. Since the decision isn't usually a technical one, > reviewers would be encouraged to respect the author's choice and > be discouraged from asking for a different choice. > > Personally my preference order is (1), (3) and (2). I think (2) > is the worst of both worlds: it wouldn't give a consistent codebase, > because whether something is seen as hard to read would vary based > on the people involved. And it wouldn't give predictability because > contributors would only know whether a use of "auto" is acceptable > by submitting a patch and seeing what the reaction is. > > (3) also wouldn't give a consistent codebase, but it would give more > predictable reviews. (2) is already the case for code review in general, isn't it? If a reviewer finds code hard to read, they can ask for improvements. I'm be in favor of conventions for when using 'auto' is recommended, and when it would be discouraged, but I don't think strict rules are necessary. Jason >> If a consensus emerges that some uses are generally >> best avoided then it might be appropriate to reflect it in >> the coding conventions. But I'd hope that wouldn't happen before >> we've had time to gain experience with it. > > I think the difference here is between whether we start with a list > of acceptable uses and expand it with experience, or whether we start > by assuming all uses are acceptable and restrict it with experience. > > The reason I think the former is better is that we're starting with > a codebase that doesn't use "auto" at all. So when the switch is > flipped and the code is C++11, we'll have a C++11 codebase that never > uses "auto". Given that starting point, it seems more natural to list > cases in which "auto" should be used (as a change to the status quo) > rather than those in which it shouldn't. > > But besides Jason's point about template-dependent types, I think the > objections have been to the idea of having coding conventions around > this in principle, rather than to the actual list. So at this point > I'm not sure whether the proposed list would actually stop someone > from using "auto" in the way they'd typically want to use it, > and if so, what those use cases are. > > Like I say, the list was only supposed to be a starting point, based on > my guess at what would be broadly acceptable. So if the chosen cases > are themselves a sticking point, suggestions for additions or modifications > are definitely welcome. > > And the list can be expanded later if new uses crop up. That's still > an improvement on how things were until now, where "auto" couldn't be > used at all. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Describe coding conventions surrounding "auto" 2020-05-18 18:02 ` Richard Sandiford 2020-05-18 18:42 ` Jason Merrill @ 2020-05-18 22:51 ` Martin Sebor 2020-05-19 9:26 ` Richard Sandiford 2020-05-19 9:36 ` Nicholas Krause 1 sibling, 2 replies; 29+ messages in thread From: Martin Sebor @ 2020-05-18 22:51 UTC (permalink / raw) To: Jason Merrill, Richard Biener, Richard Biener via Gcc-patches, richard.sandiford On 5/18/20 12:02 PM, Richard Sandiford wrote: > Martin Sebor <msebor@gmail.com> writes: >> On 5/16/20 4:43 AM, Richard Sandiford wrote: >>> Sorry for the empty subject line earlier... >>> >>> Jason Merrill <jason@redhat.com> writes: >>>> On Fri, May 15, 2020 at 9:47 PM Martin Sebor <msebor@gmail.com> wrote: >>>> >>>>> On 5/15/20 8:08 AM, Richard Sandiford wrote: >>>>>>> Those are all good examples. Mind putting that into a patch >>>>>>> for the coding conventions? >>>>>> How's this? I added "new" expressions as another example of the >>>>>> first category. >>>>>> >>>>>> I'm sure I've missed other good uses, but we can always add to the >>>>>> list later if necessary. >>>>>> >>>>>> Thanks, >>>>>> Richard >>>>>> >>>>>> >>>>>> 0001-Describe-coding-conventions-surrounding-auto.patch >>>>>> >>>>>> From 10b27e367de0fa9d5bf91544385401cdcbdb8c00 Mon Sep 17 00:00:00 2001 >>>>>> From: Richard Sandiford<richard.sandiford@arm.com> >>>>>> Date: Fri, 15 May 2020 14:58:46 +0100 >>>>>> Subject: [PATCH] Describe coding conventions surrounding "auto" >>>>>> >>>>>> --- >>>>>> htdocs/codingconventions.html | 53 +++++++++++++++++++++++++++++++++++ >>>>>> htdocs/codingrationale.html | 17 +++++++++++ >>>>>> 2 files changed, 70 insertions(+) >>>>>> >>>>>> diff --git a/htdocs/codingconventions.html >>>>> b/htdocs/codingconventions.html >>>>>> index f4732ef6..ae49fb91 100644 >>>>>> --- a/htdocs/codingconventions.html >>>>>> +++ b/htdocs/codingconventions.html >>>>>> @@ -51,6 +51,7 @@ the conventions separately from any other changes to >>>>> the code.</p> >>>>>> <li><a href="#Cxx_Language">Language Use</a> >>>>>> <ul> >>>>>> <li><a href="#Variable">Variable Definitions</a></li> >>>>>> + <li><a href="#Auto">Use of <code>auto</code></a></li> >>>>>> <li><a href="#Struct_Use">Struct Definitions</a></li> >>>>>> <li><a href="#Class_Use">Class Definitions</a></li> >>>>>> <li><a href="#Constructors">Constructors and >>>>> Destructors</a></li> >>>>>> @@ -884,6 +885,58 @@ Variables may be simultaneously defined and tested >>>>> in control expressions. >>>>>> <a href="codingrationale.html#variables">Rationale and Discussion</a> >>>>>> </p> >>>>>> >>>>>> +<h4 id="Auto">Use of <code>auto</code></h4> >>>>>> + >>>>>> +<p><code>auto</code> should be used in the following circumstances: >>>>>> +<ul> >>>>>> + <li><p>when the expression gives the C++ type explicitly. For >>>>> example</p> >>>>>> + >>>>>> + <blockquote> >>>>>> +<pre>if (<b>auto *</b>table = dyn_cast <<b>rtx_jump_table_data >>>>> *</b>> (insn)) // OK >>>>>> + ... >>>>>> +if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> >>>>> (insn)) // Avoid >>>>>> + ... >>>>>> +<b>auto *</b>map = new <b>hash_map <tree, size_t></b>; >>>>> // OK >>>>>> +hash_map <tree, size_t> *map = new hash_map <tree, size_t>; >>>>> // Avoid</pre></blockquote> >>>>>> + >>>>>> + <p>This rule does not apply to abbreviated type names embedded in >>>>>> + an identifier, such as the result of <code>tree_to_shwi</code>.</p> >>>>>> + </li> >>>>>> + <li> >>>>>> + <p>when the expression simply provides an alternative view of an >>>>> object >>>>>> + and is bound to a read-only temporary. For example:</p> >>>>>> + >>>>>> + <blockquote> >>>>>> +<pre><b>auto</b> wioff = <b>wi::to_wide (off);</b> // OK >>>>>> +wide_int wioff = wi::to_wide (off); // Avoid if wioff is read-only >>>>>> +<b>auto</b> minus1 = <b>std::shwi (-1, prec);</b> // OK >>>>>> +wide_int minus1 = std::shwi (-1, prec); // Avoid if minus1 is >>>>> read-only</pre></blockquote> >>>>>> + >>>>>> + <p>In principle this rule applies to other views of an object too, >>>>>> + such as a reversed view of a list, or a sequential view of a >>>>>> + <code>hash_set</code>. It does not apply to general >>>>> temporaries.</p> >>>>>> + </li> >>>>>> + <li> >>>>>> + <p>the type of an iterator. For example:</p> >>>>>> + >>>>>> + <blockquote> >>>>>> +<pre><b>auto</b> it = <b>std::find (names.begin (), names.end (), >>>>> needle)</b>; // OK >>>>>> +vector <name_map>::iterator it = std::find (names.begin (), >>>>>> + names.end (), needle); // >>>>> Avoid</pre></blockquote> >>>>>> + </li> >>>>>> + <li> >>>>>> + <p>the type of a lambda expression. For example:</p> >>>>>> + >>>>>> + <blockquote> >>>>>> +<pre><b>auto</b> f = <b>[] (int x) { return x + 1; }</b>; // >>>>> OK</pre></blockquote> >>>>>> + </li> >>>>>> +</ul></p> >>>>>> + >>>>>> +<p><code>auto</code> should <b>not</b> be used in other contexts.</p> >>>>> >>>>> This seems like a severe (and unnecessary) restriction... >>>>> >>>>>> + >>>>>> +<p> >>>>>> +<a href="codingrationale.html#auto">Rationale and Discussion</a> >>>>>> +</p> >>>>>> >>>>>> <h4 id="Struct_Use">Struct Definitions</h4> >>>>>> >>>>>> diff --git a/htdocs/codingrationale.html b/htdocs/codingrationale.html >>>>>> index 0b44f1da..a919023c 100644 >>>>>> --- a/htdocs/codingrationale.html >>>>>> +++ b/htdocs/codingrationale.html >>>>>> @@ -50,6 +50,23 @@ if (info *q = get_any_available_info ()) { >>>>>> } >>>>>> </code></pre></blockquote> >>>>>> >>>>>> +<h4 id="auto">Use of <code>auto</code></h4> >>>>>> + >>>>>> +<p>The reason for preferring <code>auto</code> in expressions like: >>>>>> +<blockquote><pre>auto wioff = wi::to_wide (off);</pre></blockquote> >>>>>> +is that using the natural type of the expression is more efficient than >>>>>> +converting it to types like <code>wide_int</code>.</p> >>>>>> + >>>>>> +<p>The reason for excluding other uses of <code>auto</code> is that >>>>>> +in most other cases the type carries useful information. For example: >>>>>> +<blockquote><pre>for (const std::pair <const char *, tree> >>>>> &elt : indirect_pool) >>>>>> + ...</pre></blockquote> >>>>>> +makes it obvious that <code>elt</code> is a pair and gives the types of >>>>>> +<code>elt.first</code> and <code>elt.second</code>. In contrast: >>>>>> +<blockquote><pre>for (const auto &elt : indirect_pool) >>>>>> + ...</pre></blockquote> >>>>>> +gives no immediate indication what <code>elt</code> is or what can >>>>>> +be done with it.</p> >>>>> >>>>> ...there are countless constructs in C++ 98 as well in C where there >>>>> is no such indication yet we don't (and very well can't) try to avoid >>>>> using them. Examples include macros, members of structures defined >>>>> far away from the point of their use, results of ordinary function >>>>> calls, results of overloaded functions or templates, default function >>>>> arguments, default template parameters, etc. >>>>> >>>>> By way of a random example from genrecog.c: >>>>> >>>>> int_set::iterator end >>>>> = std::set_union (trans1->labels.begin (), trans1->labels.end (), >>>>> combined->begin (), combined->end (), >>>>> next->begin ()); >>>>> >>>>> There is no immediate indication precisely what type int_set::iterator >>>>> is. All we can tell is that that it's some sort of an iterator, and >>>>> that should be good enough. It lets us (even forces us to) write code >>>>> that satisfies the requirements of the abstraction (whatever it happens >>>>> to be), and avoid tying it closely to the implementation. That's >>>>> a good thing. >>> >>> Do you mean that this example should or shouldn't use "auto"? >>> Iterators are included in the list above, so the idea was that using >>> "auto" would be the recommended style here. >> >> I meant it as a general example where the exact type isn't (and isn't >> supposed to be) apparent to the caller because it's an implementation >> detail. > > But like I say, the proposal was that this example should use "auto", > and it sounds like you might agree. In that case I don't think the > example really helps make the decision about whether the coding > standards are useful or not. > > Do you have other examples that you think would be better written > using "auto" that aren't covered by the list, and aren't covered > by Jason's point about template-dependent types? I think it applies any time mentioning the exact type isn't necessary, not just because it might introduce a dependency on details that the code doesn't need, but also because it's more verbose than the alternative. The for range loop mentioned upthread is an example. But auto is just one of a number of new core language features new in C++. Unlike some other C++ features(*), I don't think it's easily misused, at least not to such an extent to justify adding a guideline for us to use safely, consistently, or simply in good taste. Martin [*] I could see value in guidelines around rvalue references or deleted and defaulted functions, for instance, since those are easily used in dangerous ways. PS Herb Sutter has a nice article (as usual) where he summarizes commonly raised concerns with auto and his thoughts on them: https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ >> Similarly, if an API defines a typedef string_tree_pair for >> std::pair<const char*, tree>, it's the typedef that's meant to >> be used in preference to what it expands to. > > Using the typedef would be fine. string_tree_pair describes > the type pretty well: it's still obvious that "elt" is a pair, > and what "elt.first" and "elt.second" are. Typedefs that don't > describe the type well are bad typedefs. :-) > > The distinction is more between whether "auto" should be used or whether > an explicit type should be used, rather than between different ways of > writing the explicit type. I agree it'd be worth adding "string_tree_pair" > to the rationale too, to make it clearer that this isn't about expanding > the typedefs as far they'll go. > >>>>> Unless there is a sound technical reason for avoiding it (e.g., >>>>> unacceptable inefficiency or known safety problems) I'd say leave >>>>> it to everyone's judgment what convenience features to use. If >>>>> something turns out to be a problem we'll deal with it then. >>> >>> But using "auto" is never going to be an efficiency concern, >>> and probably not a safety concern. So in the case of "auto", >>> using that principle would basically come down to "when to use >>> auto is purely a judgement call". >>> >>> I don't see how we can get consistency with that kind of approach. >>> Or is the argument that we're (or I'm :-)) worrying too much about >>> consistency and we should just go with the flow? >>> >>> If we do treat it as a pure judgement call, the problem then is: >>> who's judgement matters most here? The author's or the reviewer's? >>> Should the reviewer respect the choice of the author even if they >>> don't personally agree with it, given that there are no technical >>> issues at stake? >> >> When no technical concerns are at stake contributors should be free >> to use the language as they feel is appropriate. The fewer hurdles >> we put in place the more time we will be able to focus on getting >> the many technical details right, and the more fun it will be to >> contribute. > > I agree that's a self-consistent approach. So I think at this point > three options have been suggested: > > (1) Try to add coding conventions around when "auto" should and > shouldn't be used. > > (2) Be broadly accepting of "auto", but reject cases that seem > hard to read during code review. > > (3) Allow "auto" to be used anywhere that a contributor thinks is > appropriate. Since the decision isn't usually a technical one, > reviewers would be encouraged to respect the author's choice and > be discouraged from asking for a different choice. > > Personally my preference order is (1), (3) and (2). I think (2) > is the worst of both worlds: it wouldn't give a consistent codebase, > because whether something is seen as hard to read would vary based > on the people involved. And it wouldn't give predictability because > contributors would only know whether a use of "auto" is acceptable > by submitting a patch and seeing what the reaction is. > > (3) also wouldn't give a consistent codebase, but it would give more > predictable reviews. > >> If a consensus emerges that some uses are generally >> best avoided then it might be appropriate to reflect it in >> the coding conventions. But I'd hope that wouldn't happen before >> we've had time to gain experience with it. > > I think the difference here is between whether we start with a list > of acceptable uses and expand it with experience, or whether we start > by assuming all uses are acceptable and restrict it with experience. > > The reason I think the former is better is that we're starting with > a codebase that doesn't use "auto" at all. So when the switch is > flipped and the code is C++11, we'll have a C++11 codebase that never > uses "auto". Given that starting point, it seems more natural to list > cases in which "auto" should be used (as a change to the status quo) > rather than those in which it shouldn't. > > But besides Jason's point about template-dependent types, I think the > objections have been to the idea of having coding conventions around > this in principle, rather than to the actual list. So at this point > I'm not sure whether the proposed list would actually stop someone > from using "auto" in the way they'd typically want to use it, > and if so, what those use cases are. > > Like I say, the list was only supposed to be a starting point, based on > my guess at what would be broadly acceptable. So if the chosen cases > are themselves a sticking point, suggestions for additions or modifications > are definitely welcome. > > And the list can be expanded later if new uses crop up. That's still > an improvement on how things were until now, where "auto" couldn't be > used at all. > > Thanks, > Richard > ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Describe coding conventions surrounding "auto" 2020-05-18 22:51 ` Martin Sebor @ 2020-05-19 9:26 ` Richard Sandiford 2020-05-19 9:36 ` Nicholas Krause 1 sibling, 0 replies; 29+ messages in thread From: Richard Sandiford @ 2020-05-19 9:26 UTC (permalink / raw) To: Martin Sebor Cc: Jason Merrill, Richard Biener, Richard Biener via Gcc-patches Martin Sebor <msebor@gmail.com> writes: >>>>>> By way of a random example from genrecog.c: >>>>>> >>>>>> int_set::iterator end >>>>>> = std::set_union (trans1->labels.begin (), trans1->labels.end (), >>>>>> combined->begin (), combined->end (), >>>>>> next->begin ()); >>>>>> >>>>>> There is no immediate indication precisely what type int_set::iterator >>>>>> is. All we can tell is that that it's some sort of an iterator, and >>>>>> that should be good enough. It lets us (even forces us to) write code >>>>>> that satisfies the requirements of the abstraction (whatever it happens >>>>>> to be), and avoid tying it closely to the implementation. That's >>>>>> a good thing. >>>> >>>> Do you mean that this example should or shouldn't use "auto"? >>>> Iterators are included in the list above, so the idea was that using >>>> "auto" would be the recommended style here. >>> >>> I meant it as a general example where the exact type isn't (and isn't >>> supposed to be) apparent to the caller because it's an implementation >>> detail. >> >> But like I say, the proposal was that this example should use "auto", >> and it sounds like you might agree. In that case I don't think the >> example really helps make the decision about whether the coding >> standards are useful or not. >> >> Do you have other examples that you think would be better written >> using "auto" that aren't covered by the list, and aren't covered >> by Jason's point about template-dependent types? > > I think it applies any time mentioning the exact type isn't > necessary, not just because it might introduce a dependency on > details that the code doesn't need, but also because it's more > verbose than the alternative. The for range loop mentioned > upthread is an example. > > But auto is just one of a number of new core language features > new in C++. Unlike some other C++ features(*), I don't think > it's easily misused, at least not to such an extent to justify > adding a guideline for us to use safely, consistently, or simply > in good taste. I agree a guideline like that would be pointless. It'd be like saying "be good". :-) But the idea with the patch was instead to have conventions that use objective conditions. (The rationale was more subjective of course.) > Martin > > [*] I could see value in guidelines around rvalue references > or deleted and defaulted functions, for instance, since those > are easily used in dangerous ways. > > PS Herb Sutter has a nice article (as usual) where he summarizes > commonly raised concerns with auto and his thoughts on them: > https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ Almost always using "auto" seems a bit drastic when we're starting with a codebase that doesn't use "auto" at all. TBH I don't find the argument in that article convincing, especially the part about types often being implicit within expressions. E.g. it's true that: if( find(begin(c), end(c), v) == end(c) ) c.emplace_back(v); assert( !c.empty() ); is readable without having any explicit types. But it doesn't follow that larger blocks of code are just readable without having explicit types. That would be like saying that GCC's 1000-line functions are just as readable as small functions, since each statement is readable in isolation. The article seems to be concentrating on examples that are likely to crop up in templatised library code rather than in (say) IL processing. E.g.: take: auto size = compute_objsize (ref, ostype, pdecl, poff); Is that size a tree, some form of wide_int, or a plain HWI? The answer decides what you can do with the size. Using auto here forces you to look at the prototype of compute_objsize (which eventually might itself return "auto" on the AAA principle), or look around to see how "size" is used in practice. That's not likely to confuse the person writing the code. But: tree size = compute_objsize (ref, ostype, pdecl, poff); either makes life easier for whoever comes next, or doesn't make any difference to them either way. And that's true for longer type names too. Like Jason says, the default position if we don't add any guidelines is that whether "auto" is appropriate is a question for code review. Maybe some reviewers would accept patches that follow the "almost always auto" principle. Others probably would probably reject the patches and ask for more explicit types to be added. Others might accept something in between. If we don't add any guidelines, that would be the review process operating correctly. Thanks, Richard ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH] Describe coding conventions surrounding "auto" 2020-05-18 22:51 ` Martin Sebor 2020-05-19 9:26 ` Richard Sandiford @ 2020-05-19 9:36 ` Nicholas Krause 1 sibling, 0 replies; 29+ messages in thread From: Nicholas Krause @ 2020-05-19 9:36 UTC (permalink / raw) To: Martin Sebor, Jason Merrill, Richard Biener, Richard Biener via Gcc-patches, richard.sandiford On 5/18/20 6:51 PM, Martin Sebor via Gcc-patches wrote: > On 5/18/20 12:02 PM, Richard Sandiford wrote: >> Martin Sebor <msebor@gmail.com> writes: >>> On 5/16/20 4:43 AM, Richard Sandiford wrote: >>>> Sorry for the empty subject line earlier... >>>> >>>> Jason Merrill <jason@redhat.com> writes: >>>>> On Fri, May 15, 2020 at 9:47 PM Martin Sebor <msebor@gmail.com> wrote: >>>>> >>>>>> On 5/15/20 8:08 AM, Richard Sandiford wrote: >>>>>>>> Those are all good examples. Mind putting that into a patch >>>>>>>> for the coding conventions? >>>>>>> How's this? I added "new" expressions as another example of the >>>>>>> first category. >>>>>>> >>>>>>> I'm sure I've missed other good uses, but we can always add to the >>>>>>> list later if necessary. >>>>>>> >>>>>>> Thanks, >>>>>>> Richard >>>>>>> >>>>>>> >>>>>>> 0001-Describe-coding-conventions-surrounding-auto.patch >>>>>>> >>>>>>> From 10b27e367de0fa9d5bf91544385401cdcbdb8c00 Mon Sep 17 >>>>>>> 00:00:00 2001 >>>>>>> From: Richard Sandiford<richard.sandiford@arm.com> >>>>>>> Date: Fri, 15 May 2020 14:58:46 +0100 >>>>>>> Subject: [PATCH] Describe coding conventions surrounding "auto" >>>>>>> >>>>>>> --- >>>>>>> htdocs/codingconventions.html | 53 >>>>>>> +++++++++++++++++++++++++++++++++++ >>>>>>> htdocs/codingrationale.html | 17 +++++++++++ >>>>>>> 2 files changed, 70 insertions(+) >>>>>>> >>>>>>> diff --git a/htdocs/codingconventions.html >>>>>> b/htdocs/codingconventions.html >>>>>>> index f4732ef6..ae49fb91 100644 >>>>>>> --- a/htdocs/codingconventions.html >>>>>>> +++ b/htdocs/codingconventions.html >>>>>>> @@ -51,6 +51,7 @@ the conventions separately from any other >>>>>>> changes to >>>>>> the code.</p> >>>>>>> <li><a href="#Cxx_Language">Language Use</a> >>>>>>> <ul> >>>>>>> <li><a href="#Variable">Variable Definitions</a></li> >>>>>>> + <li><a href="#Auto">Use of <code>auto</code></a></li> >>>>>>> <li><a href="#Struct_Use">Struct Definitions</a></li> >>>>>>> <li><a href="#Class_Use">Class Definitions</a></li> >>>>>>> <li><a href="#Constructors">Constructors and >>>>>> Destructors</a></li> >>>>>>> @@ -884,6 +885,58 @@ Variables may be simultaneously defined and >>>>>>> tested >>>>>> in control expressions. >>>>>>> <a href="codingrationale.html#variables">Rationale and >>>>>>> Discussion</a> >>>>>>> </p> >>>>>>> >>>>>>> +<h4 id="Auto">Use of <code>auto</code></h4> >>>>>>> + >>>>>>> +<p><code>auto</code> should be used in the following circumstances: >>>>>>> +<ul> >>>>>>> + <li><p>when the expression gives the C++ type explicitly. For >>>>>> example</p> >>>>>>> + >>>>>>> + <blockquote> >>>>>>> +<pre>if (<b>auto *</b>table = dyn_cast <<b>rtx_jump_table_data >>>>>> *</b>> (insn)) // OK >>>>>>> + ... >>>>>>> +if (rtx_jump_table_data *table = dyn_cast >>>>>>> <rtx_jump_table_data *> >>>>>> (insn)) // Avoid >>>>>>> + ... >>>>>>> +<b>auto *</b>map = new <b>hash_map <tree, size_t></b>; >>>>>> // OK >>>>>>> +hash_map <tree, size_t> *map = new hash_map <tree, >>>>>>> size_t>; >>>>>> // Avoid</pre></blockquote> >>>>>>> + >>>>>>> + <p>This rule does not apply to abbreviated type names >>>>>>> embedded in >>>>>>> + an identifier, such as the result of >>>>>>> <code>tree_to_shwi</code>.</p> >>>>>>> + </li> >>>>>>> + <li> >>>>>>> + <p>when the expression simply provides an alternative view >>>>>>> of an >>>>>> object >>>>>>> + and is bound to a read-only temporary. For example:</p> >>>>>>> + >>>>>>> + <blockquote> >>>>>>> +<pre><b>auto</b> wioff = <b>wi::to_wide (off);</b> // OK >>>>>>> +wide_int wioff = wi::to_wide (off); // Avoid if wioff is >>>>>>> read-only >>>>>>> +<b>auto</b> minus1 = <b>std::shwi (-1, prec);</b> // OK >>>>>>> +wide_int minus1 = std::shwi (-1, prec); // Avoid if minus1 is >>>>>> read-only</pre></blockquote> >>>>>>> + >>>>>>> + <p>In principle this rule applies to other views of an >>>>>>> object too, >>>>>>> + such as a reversed view of a list, or a sequential view of a >>>>>>> + <code>hash_set</code>. It does not apply to general >>>>>> temporaries.</p> >>>>>>> + </li> >>>>>>> + <li> >>>>>>> + <p>the type of an iterator. For example:</p> >>>>>>> + >>>>>>> + <blockquote> >>>>>>> +<pre><b>auto</b> it = <b>std::find (names.begin (), names.end (), >>>>>> needle)</b>; // OK >>>>>>> +vector <name_map>::iterator it = std::find (names.begin (), >>>>>>> + names.end (), >>>>>>> needle); // >>>>>> Avoid</pre></blockquote> >>>>>>> + </li> >>>>>>> + <li> >>>>>>> + <p>the type of a lambda expression. For example:</p> >>>>>>> + >>>>>>> + <blockquote> >>>>>>> +<pre><b>auto</b> f = <b>[] (int x) { return x + 1; }</b>; // >>>>>> OK</pre></blockquote> >>>>>>> + </li> >>>>>>> +</ul></p> >>>>>>> + >>>>>>> +<p><code>auto</code> should <b>not</b> be used in other >>>>>>> contexts.</p> >>>>>> >>>>>> This seems like a severe (and unnecessary) restriction... >>>>>> >>>>>>> + >>>>>>> +<p> >>>>>>> +<a href="codingrationale.html#auto">Rationale and Discussion</a> >>>>>>> +</p> >>>>>>> >>>>>>> <h4 id="Struct_Use">Struct Definitions</h4> >>>>>>> >>>>>>> diff --git a/htdocs/codingrationale.html >>>>>>> b/htdocs/codingrationale.html >>>>>>> index 0b44f1da..a919023c 100644 >>>>>>> --- a/htdocs/codingrationale.html >>>>>>> +++ b/htdocs/codingrationale.html >>>>>>> @@ -50,6 +50,23 @@ if (info *q = get_any_available_info ()) { >>>>>>> } >>>>>>> </code></pre></blockquote> >>>>>>> >>>>>>> +<h4 id="auto">Use of <code>auto</code></h4> >>>>>>> + >>>>>>> +<p>The reason for preferring <code>auto</code> in expressions like: >>>>>>> +<blockquote><pre>auto wioff = wi::to_wide (off);</pre></blockquote> >>>>>>> +is that using the natural type of the expression is more >>>>>>> efficient than >>>>>>> +converting it to types like <code>wide_int</code>.</p> >>>>>>> + >>>>>>> +<p>The reason for excluding other uses of <code>auto</code> is that >>>>>>> +in most other cases the type carries useful information. For >>>>>>> example: >>>>>>> +<blockquote><pre>for (const std::pair <const char *, tree> >>>>>> &elt : indirect_pool) >>>>>>> + ...</pre></blockquote> >>>>>>> +makes it obvious that <code>elt</code> is a pair and gives the >>>>>>> types of >>>>>>> +<code>elt.first</code> and <code>elt.second</code>. In contrast: >>>>>>> +<blockquote><pre>for (const auto &elt : indirect_pool) >>>>>>> + ...</pre></blockquote> >>>>>>> +gives no immediate indication what <code>elt</code> is or what can >>>>>>> +be done with it.</p> >>>>>> >>>>>> ...there are countless constructs in C++ 98 as well in C where there >>>>>> is no such indication yet we don't (and very well can't) try to avoid >>>>>> using them. Examples include macros, members of structures defined >>>>>> far away from the point of their use, results of ordinary function >>>>>> calls, results of overloaded functions or templates, default function >>>>>> arguments, default template parameters, etc. >>>>>> >>>>>> By way of a random example from genrecog.c: >>>>>> >>>>>> int_set::iterator end >>>>>> = std::set_union (trans1->labels.begin (), >>>>>> trans1->labels.end (), >>>>>> combined->begin (), combined->end (), >>>>>> next->begin ()); >>>>>> >>>>>> There is no immediate indication precisely what type >>>>>> int_set::iterator >>>>>> is. All we can tell is that that it's some sort of an iterator, and >>>>>> that should be good enough. It lets us (even forces us to) write >>>>>> code >>>>>> that satisfies the requirements of the abstraction (whatever it >>>>>> happens >>>>>> to be), and avoid tying it closely to the implementation. That's >>>>>> a good thing. >>>> >>>> Do you mean that this example should or shouldn't use "auto"? >>>> Iterators are included in the list above, so the idea was that using >>>> "auto" would be the recommended style here. >>> >>> I meant it as a general example where the exact type isn't (and isn't >>> supposed to be) apparent to the caller because it's an implementation >>> detail. >> >> But like I say, the proposal was that this example should use "auto", >> and it sounds like you might agree. In that case I don't think the >> example really helps make the decision about whether the coding >> standards are useful or not. >> >> Do you have other examples that you think would be better written >> using "auto" that aren't covered by the list, and aren't covered >> by Jason's point about template-dependent types? > > I think it applies any time mentioning the exact type isn't > necessary, not just because it might introduce a dependency on > details that the code doesn't need, but also because it's more > verbose than the alternative. The for range loop mentioned > upthread is an example. > > But auto is just one of a number of new core language features > new in C++. Unlike some other C++ features(*), I don't think > it's easily misused, at least not to such an extent to justify > adding a guideline for us to use safely, consistently, or simply > in good taste. > > Martin > > [*] I could see value in guidelines around rvalue references > or deleted and defaulted functions, for instance, since those > are easily used in dangerous ways. > > PS Herb Sutter has a nice article (as usual) where he summarizes > commonly raised concerns with auto and his thoughts on them: > https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ > > >>> Similarly, if an API defines a typedef string_tree_pair for >>> std::pair<const char*, tree>, it's the typedef that's meant to >>> be used in preference to what it expands to. >> >> Using the typedef would be fine. string_tree_pair describes >> the type pretty well: it's still obvious that "elt" is a pair, >> and what "elt.first" and "elt.second" are. Typedefs that don't >> describe the type well are bad typedefs. :-) >> >> The distinction is more between whether "auto" should be used or whether >> an explicit type should be used, rather than between different ways of >> writing the explicit type. I agree it'd be worth adding >> "string_tree_pair" >> to the rationale too, to make it clearer that this isn't about expanding >> the typedefs as far they'll go. >> >>>>>> Unless there is a sound technical reason for avoiding it (e.g., >>>>>> unacceptable inefficiency or known safety problems) I'd say leave >>>>>> it to everyone's judgment what convenience features to use. If >>>>>> something turns out to be a problem we'll deal with it then. >>>> >>>> But using "auto" is never going to be an efficiency concern, >>>> and probably not a safety concern. So in the case of "auto", >>>> using that principle would basically come down to "when to use >>>> auto is purely a judgement call". >>>> >>>> I don't see how we can get consistency with that kind of approach. >>>> Or is the argument that we're (or I'm :-)) worrying too much about >>>> consistency and we should just go with the flow? >>>> >>>> If we do treat it as a pure judgement call, the problem then is: >>>> who's judgement matters most here? The author's or the reviewer's? >>>> Should the reviewer respect the choice of the author even if they >>>> don't personally agree with it, given that there are no technical >>>> issues at stake? >>> >>> When no technical concerns are at stake contributors should be free >>> to use the language as they feel is appropriate. The fewer hurdles >>> we put in place the more time we will be able to focus on getting >>> the many technical details right, and the more fun it will be to >>> contribute. >> >> I agree that's a self-consistent approach. So I think at this point >> three options have been suggested: >> >> (1) Try to add coding conventions around when "auto" should and >> shouldn't be used. >> >> (2) Be broadly accepting of "auto", but reject cases that seem >> hard to read during code review. >> >> (3) Allow "auto" to be used anywhere that a contributor thinks is >> appropriate. Since the decision isn't usually a technical one, >> reviewers would be encouraged to respect the author's choice and >> be discouraged from asking for a different choice. >> >> Personally my preference order is (1), (3) and (2). I think (2) >> is the worst of both worlds: it wouldn't give a consistent codebase, >> because whether something is seen as hard to read would vary based >> on the people involved. And it wouldn't give predictability because >> contributors would only know whether a use of "auto" is acceptable >> by submitting a patch and seeing what the reaction is. >> >> (3) also wouldn't give a consistent codebase, but it would give more >> predictable reviews. >> >>> If a consensus emerges that some uses are generally >>> best avoided then it might be appropriate to reflect it in >>> the coding conventions. But I'd hope that wouldn't happen before >>> we've had time to gain experience with it. >> >> I think the difference here is between whether we start with a list >> of acceptable uses and expand it with experience, or whether we start >> by assuming all uses are acceptable and restrict it with experience. >> >> The reason I think the former is better is that we're starting with >> a codebase that doesn't use "auto" at all. So when the switch is >> flipped and the code is C++11, we'll have a C++11 codebase that never >> uses "auto". Given that starting point, it seems more natural to list >> cases in which "auto" should be used (as a change to the status quo) >> rather than those in which it shouldn't. >> >> But besides Jason's point about template-dependent types, I think the >> objections have been to the idea of having coding conventions around >> this in principle, rather than to the actual list. So at this point >> I'm not sure whether the proposed list would actually stop someone >> from using "auto" in the way they'd typically want to use it, >> and if so, what those use cases are. >> >> Like I say, the list was only supposed to be a starting point, based on >> my guess at what would be broadly acceptable. So if the chosen cases >> are themselves a sticking point, suggestions for additions or >> modifications >> are definitely welcome. >> >> And the list can be expanded later if new uses crop up. That's still >> an improvement on how things were until now, where "auto" couldn't be >> used at all. >> >> Thanks, >> Richard >> > Richard, There is one use case that may be of issue but its up to other people to decide in that of auto&& and the issues around perfect forwarding. I'm aware of anything in the code base requiring perfect forwarding, and not in the near future. Would it to be nice to avoid that and the same for T& for templates? Or is there something I'm not aware of that requires it. I'm assuming people know about the dangers of perfect forwarding with either of these four things T&,T&&,auto&&,auto&. Sorry if I'm injecting my thoughts late into the discussion about auto, Nick -- Fundamentally an organism has conscious mental states if and only if there is something that it is like to be that organism--something it is like for the organism. - Thomas Nagel ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 9:58 ` Richard Sandiford 2020-05-15 10:15 ` Richard Biener @ 2020-05-15 17:36 ` Jason Merrill 1 sibling, 0 replies; 29+ messages in thread From: Jason Merrill @ 2020-05-15 17:36 UTC (permalink / raw) To: Richard Biener, Richard Biener via Gcc-patches, Jason Merrill, Richard Sandiford On Fri, May 15, 2020 at 5:58 AM Richard Sandiford <richard.sandiford@arm.com> wrote: > Richard Biener <richard.guenther@gmail.com> writes: > > On Fri, May 15, 2020 at 10:30 AM Richard Sandiford > > <richard.sandiford@arm.com> wrote: > >> > >> Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes: > >> > Note I think what's missing is some general blurb in our coding > conventions > >> > as to how much of C++11 we are supposed to use in non-infrastructure > parts > >> > of GCC (I expect things like hash-table.h to use more C++ features > than, > >> > say, tree-ssa-alias.c). > >> > >> I guess there are two aspects to that: > >> > >> - Are there any specific features we should avoid using at all? > >> TBH I hope not. Trying to police this based on C++ feature sounds > >> difficulty and might be counterproductive. > >> > >> IMO it should just (continue to) be based on principles like avoiding > >> abstraction for abstraction's sake, and keeping compiler performance > >> and code size in mind. Even tree-ssa-alias.c should be able to use > >> any C++ feature if there's a justification. > >> > >> - Coding conventions for when features should be used. "auto" is an > >> obvious one. Maybe also lambdas (which should help avoid the horrible > >> "void *" callback parameters we have all over the place now). > >> > >> Maybe also guidelines to actively use certain features, e.g. > >> > >> - use "= default" where possible > >> > >> - prefer range-based for loops to macros > >> > >> - mark "operator bool()" conversions as explicit > >> > >> - use "override" where applicable > >> > >> (all obvious I guess), etc. > > > > I think the most important thing is that refactoring for the sake > > of refactoring is bad iff it does not improve on consistency > > throughout the code base. We should really try hard to use > > C++ features consistently - this makes the code base easier > > to understand. > > Agreed. One of the reasons I'm keen to have something in the > coding standards is that things became less consistent after > the C->C++ switch. > > Maybe we should reconsider some of the existing coding standards too. > E.g.: > > Define all members outside the class definition. > That is, there are no function bodies or member initializers > inside the class definition. > > isn't widely followed. That's a bit of a tangent though. > (FTR, I've no attachment to the current conventions and didn't > contribute anything to them. More consistency would be good though.) > > > We've moved more and more to stronly-typed data structures > > so I'd not like to see 'auto' everywhere - it should be still > > obvious what kind of objects we're working with where they > > matter. IMHO they do not matter for example for iterators. > > I don't care about the iterator type but about the type of > > the object and the container. > > Also agreed. :-) How about this as a starting point: > > --------------------------------------------------------------- > Use auto for: > > - the result of casts or other expressions that give the type > explicitly. E.g.: > > if (auto *table = dyn_cast <rtx_jump_table_data *> (insn)) > > instead of: > > if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> > (insn)) > > - iterator types. E.g.: > > auto it = foo.begin (); > > instead of: > > foo_type::iterator it = foo.begin (); > > - expressions that provide an alternative view of something, > when the expression is bound to a read-only temporary. E.g.: > > auto val1 = wi::to_wide (...); > auto val2 = wi::uhwi (12, 16); > > instead of: > > wide_int val1 = wi::to_wide (...); > wide_int val2 = wi::uhwi (12, 16); > > (Using "wide_int" is less efficient than using the natural type of > the expression.) > > - the type of a lambda expression. E.g.: > > auto f = [] (int x) { return x + 1; }; > > Do not use auto otherwise. > We probably also want to use auto for local variables in templates where the initializer is type-dependent. Jason ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 7:14 ` Richard Biener 2020-05-15 8:30 ` Richard Sandiford @ 2020-05-15 17:30 ` Jason Merrill 2020-05-15 18:21 ` Richard Biener 1 sibling, 1 reply; 29+ messages in thread From: Jason Merrill @ 2020-05-15 17:30 UTC (permalink / raw) To: Richard Biener; +Cc: GCC Patches On Fri, May 15, 2020 at 3:15 AM Richard Biener <richard.guenther@gmail.com> wrote: > > +# When bootstrapping with GCC, build stage 1 in C++11 mode to ensure > that a > > +# C++11 compiler can still start the bootstrap. > > if test "$enable_bootstrap:$GXX" = "yes:yes"; then > > + CXX="$CXX -std=gnu++11" > > So I just spotted this - since we're requiring a ISO C++11 compiler > shouldn't > we build stage1 with -std=c++11 rather than gnu++11 (whatever the detailed > differences are here)? Also not sure what level of -pedantic we'd need to > avoid GNU extensions even with -std=c++11. Of course there are (I hope) > a lot less GNU extensions for C++ than there were for C and hopefully > no extra in gnu++11 compared to gnu++98 which we checked previously. > When we first moved to C++ I tried using -std=c++98, but there were too many places where we were assuming that if we're building with GCC, we can use GNU C extensions. I'll see if that's still a problem for -std=c++11. Note I think what's missing is some general blurb in our coding conventions > as to how much of C++11 we are supposed to use in non-infrastructure parts > of GCC (I expect things like hash-table.h to use more C++ features than, > say, tree-ssa-alias.c). > > There also does not seem to be a configure check which may present > users with a more useful error message than later cryptic fail of build? > I suppose we cannot simply check __cplusplus for this, can we? Do > other common host compilers need additional options to enable C++11? > Good point, I'll add that. > Should we try to second guess such flags via configury? For example > GCC 4.8 defaults to -std=gnu++98 and the above only seems to apply > to the bootstrap case so GCC 4.8 cannot be used to build cross compilers > without adjusting CC and CXX? > Older GCC is still GCC and will get the flag automatically. Jason ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 17:30 ` Jason Merrill @ 2020-05-15 18:21 ` Richard Biener 2020-05-15 21:53 ` Jason Merrill 0 siblings, 1 reply; 29+ messages in thread From: Richard Biener @ 2020-05-15 18:21 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches On May 15, 2020 7:30:38 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote: >On Fri, May 15, 2020 at 3:15 AM Richard Biener ><richard.guenther@gmail.com> >wrote: > >> > +# When bootstrapping with GCC, build stage 1 in C++11 mode to >ensure >> that a >> > +# C++11 compiler can still start the bootstrap. >> > if test "$enable_bootstrap:$GXX" = "yes:yes"; then >> > + CXX="$CXX -std=gnu++11" >> >> So I just spotted this - since we're requiring a ISO C++11 compiler >> shouldn't >> we build stage1 with -std=c++11 rather than gnu++11 (whatever the >detailed >> differences are here)? Also not sure what level of -pedantic we'd >need to >> avoid GNU extensions even with -std=c++11. Of course there are (I >hope) >> a lot less GNU extensions for C++ than there were for C and hopefully >> no extra in gnu++11 compared to gnu++98 which we checked previously. >> > >When we first moved to C++ I tried using -std=c++98, but there were too >many places where we were assuming that if we're building with GCC, we >can >use GNU C extensions. > >I'll see if that's still a problem for -std=c++11. > >Note I think what's missing is some general blurb in our coding >conventions >> as to how much of C++11 we are supposed to use in non-infrastructure >parts >> of GCC (I expect things like hash-table.h to use more C++ features >than, >> say, tree-ssa-alias.c). >> >> There also does not seem to be a configure check which may present >> users with a more useful error message than later cryptic fail of >build? >> I suppose we cannot simply check __cplusplus for this, can we? Do >> other common host compilers need additional options to enable C++11? >> > >Good point, I'll add that. > > >> Should we try to second guess such flags via configury? For example >> GCC 4.8 defaults to -std=gnu++98 and the above only seems to apply >> to the bootstrap case so GCC 4.8 cannot be used to build cross >compilers >> without adjusting CC and CXX? >> > >Older GCC is still GCC and will get the flag automatically. But yes:yes suggests that when building a cross compiler this doesn't apply? Richard. >Jason ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 18:21 ` Richard Biener @ 2020-05-15 21:53 ` Jason Merrill 2020-05-16 6:50 ` Richard Biener ` (2 more replies) 0 siblings, 3 replies; 29+ messages in thread From: Jason Merrill @ 2020-05-15 21:53 UTC (permalink / raw) To: Richard Biener; +Cc: GCC Patches [-- Attachment #1: Type: text/plain, Size: 2267 bytes --] On 5/15/20 2:21 PM, Richard Biener wrote: > On May 15, 2020 7:30:38 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote: >> On Fri, May 15, 2020 at 3:15 AM Richard Biener >> <richard.guenther@gmail.com> >> wrote: >> >>>> +# When bootstrapping with GCC, build stage 1 in C++11 mode to >> ensure >>> that a >>>> +# C++11 compiler can still start the bootstrap. >>>> if test "$enable_bootstrap:$GXX" = "yes:yes"; then >>>> + CXX="$CXX -std=gnu++11" >>> >>> So I just spotted this - since we're requiring a ISO C++11 compiler shouldn't >>> we build stage1 with -std=c++11 rather than gnu++11 (whatever the detailed >>> differences are here)? Also not sure what level of -pedantic we'd need to >>> avoid GNU extensions even with -std=c++11. Of course there are (I hope) >>> a lot less GNU extensions for C++ than there were for C and hopefully >>> no extra in gnu++11 compared to gnu++98 which we checked previously. Building stage 1 with -std=c++11 -pedantic-errors works with 8.3.1, but fails pretty badly with 4.8.5, >> When we first moved to C++ I tried using -std=c++98, but there were too >> many places where we were assuming that if we're building with GCC, we can >> use GNU C extensions. >> >> I'll see if that's still a problem for -std=c++11. It doesn't seem to be, so I've made that change. >>> There also does not seem to be a configure check which may present >>> users with a more useful error message than later cryptic fail of build? >>> I suppose we cannot simply check __cplusplus for this, can we? Do >>> other common host compilers need additional options to enable C++11? >> >> Good point, I'll add that. This patch uses a test from the autoconf archive to add any needed flags. Tested with GCC 4.8.5 and clang 3.4.2 (with the above stage 1 -std=c++11 disabled). >>> Should we try to second guess such flags via configury? For example >>> GCC 4.8 defaults to -std=gnu++98 and the above only seems to apply >>> to the bootstrap case so GCC 4.8 cannot be used to build cross >> compilers >>> without adjusting CC and CXX? >> >> Older GCC is still GCC and will get the flag automatically. > > But yes:yes suggests that when building a cross compiler this doesn't apply? True, but the new test should cover that case. OK for trunk? [-- Attachment #2: cxx11-boot.diff --] [-- Type: text/x-patch, Size: 50545 bytes --] commit f466a9f3f121f16b97071162806255fb464718f2 Author: Jason Merrill <jason@redhat.com> Date: Fri May 15 17:15:38 2020 -0400 bootstrap: Update requirement to C++11. There was general agreement last November that we would move to allowing C++11 features to be used in GCC 11; this patch implements that direction. ChangeLog 2020-05-15 Jason Merrill <jason@redhat.com> * configure.ac: Update bootstrap dialect to -std=c++11. config/ChangeLog 2020-05-15 Jason Merrill <jason@redhat.com> * ax_cxx_compile_stdcxx.m4: Import from autoconf archive with an adjustment to try the default mode. gcc/ChangeLog 2020-05-15 Jason Merrill <jason@redhat.com> * aclocal.m4: Add ax_cxx_compile_stdcxx.m4. * configure.ac: Use AX_CXX_COMPILE_STDCXX(11). diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 876b04f9c45..c367f4f66e3 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -238,18 +238,20 @@ described below. @heading Tools/packages necessary for building GCC @table @asis -@item ISO C++98 compiler -Necessary to bootstrap GCC, although versions of GCC prior -to 4.8 also allow bootstrapping with a ISO C89 compiler and versions -of GCC prior to 3.4 also allow bootstrapping with a traditional -(K&R) C compiler. +@item ISO C++11 compiler +Necessary to bootstrap GCC. + +Versions of GCC prior to 11 also allow bootstrapping with an ISO C++98 +compiler, versions of GCC prior to 4.8 also allow bootstrapping with a +ISO C89 compiler, and versions of GCC prior to 3.4 also allow +bootstrapping with a traditional (K&R) C compiler. To build all languages in a cross-compiler or other configuration where 3-stage bootstrap is not performed, you need to start with an existing -GCC binary (version 3.4 or later) because source code for language +GCC binary (version 4.8 or later) because source code for language frontends other than C might use GCC extensions. -Note that to bootstrap GCC with versions of GCC earlier than 3.4, you +Note that to bootstrap GCC with versions of GCC earlier than 4.8, you may need to use @option{--disable-stage1-checking}, though bootstrapping the compiler with such earlier compilers is strongly discouraged. diff --git a/config/ax_cxx_compile_stdcxx.m4 b/config/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 00000000000..9413da624d2 --- /dev/null +++ b/config/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,962 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for no added switch, and then for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> +# Copyright (c) 2012 Zack Weinberg <zackw@panix.com> +# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> +# Copyright (c) 2015 Paul Norman <penorman@mac.com> +# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu> +# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com> +# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com> +# Copyright (c) 2020 Jason Merrill <jason@redhat.com> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 12 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$2], [], [dnl + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi]) + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same<int, decltype(f(x))>::value, ""); + static_assert(is_same<int&, decltype(g(x))>::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include <initializer_list> +#include <utility> +#include <type_traits> + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template<typename... Args> + int multiply(Args... args) + { + return (args * ... * 1); + } + + template<typename... Args> + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value); + static_assert(std::is_same<int, decltype(bar)>::value); + } + + namespace test_typename_in_template_template_parameter + { + + template<template<typename> typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template <bool cond> + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template <typename T1, typename T2> + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template <auto n> + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair<int, int> pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair<int, int>& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template<typename T> + Bad + f(T*, T*); + + template<typename T1, typename T2> + Good + f(T1*, T2*); + + static_assert (std::is_same_v<Good, decltype(f(g1, g2))>); + + } + + namespace test_inline_variables + { + + template<class T> void f(T) + {} + + template<class T> inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + +]]) diff --git a/configure.ac b/configure.ac index c78d9cbea62..a67801371a4 100644 --- a/configure.ac +++ b/configure.ac @@ -1462,10 +1462,10 @@ case "$have_compiler:$host:$target:$enable_bootstrap" in ;; esac -# When bootstrapping with GCC, build stage 1 in C++98 mode to ensure that a -# C++98 compiler can still start the bootstrap. +# When bootstrapping with GCC, build stage 1 in C++11 mode to ensure that a +# C++11 compiler can still start the bootstrap. if test "$enable_bootstrap:$GXX" = "yes:yes"; then - CXX="$CXX -std=gnu++98" + CXX="$CXX -std=c++11" fi # Used for setting $lt_cv_objdir diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4 index 1737d59d1cb..e93c1535063 100644 --- a/gcc/aclocal.m4 +++ b/gcc/aclocal.m4 @@ -18,6 +18,7 @@ m4_include([../ltsugar.m4]) m4_include([../ltversion.m4]) m4_include([../lt~obsolete.m4]) m4_include([../config/acx.m4]) +m4_include([../config/ax_cxx_compile_stdcxx.m4]) m4_include([../config/cet.m4]) m4_include([../config/codeset.m4]) m4_include([../config/depstand.m4]) diff --git a/gcc/configure.ac b/gcc/configure.ac index 953b464cedf..60d83c30771 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -385,6 +385,9 @@ AC_SUBST(PICFLAG_FOR_TARGET) # ------------------------- AC_USE_SYSTEM_EXTENSIONS + +AX_CXX_COMPILE_STDCXX(11) + AC_PROG_CPP AC_C_INLINE diff --git a/ChangeLog b/ChangeLog index a7fcf77b9b2..53d13eb6182 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2020-05-15 Jason Merrill <jason@redhat.com> + + * configure.ac: Update bootstrap dialect to -std=c++11. + 2020-04-29 Thomas Schwinge <thomas@codesourcery.com> PR target/92713 diff --git a/config/ChangeLog b/config/ChangeLog index a4d54749669..ec09e85a84b 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,8 @@ +2020-05-15 Jason Merrill <jason@redhat.com> + + * ax_cxx_compile_stdcxx.m4: Import from autoconf archive with + an adjustment to try the default mode. + 2020-05-15 H.J. Lu <hongjiu.lu@intel.com> PR bootstrap/95147 diff --git a/configure b/configure index 4cc938ebb7d..3af6a530b9a 100755 --- a/configure +++ b/configure @@ -5523,10 +5523,10 @@ $as_echo "$as_me: WARNING: trying to bootstrap a cross compiler" >&2;} ;; esac -# When bootstrapping with GCC, build stage 1 in C++98 mode to ensure that a -# C++98 compiler can still start the bootstrap. +# When bootstrapping with GCC, build stage 1 in C++11 mode to ensure that a +# C++11 compiler can still start the bootstrap. if test "$enable_bootstrap:$GXX" = "yes:yes"; then - CXX="$CXX -std=gnu++98" + CXX="$CXX -std=c++11" fi # Used for setting $lt_cv_objdir diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ae73f21560..9743ff65add 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2020-05-15 Jason Merrill <jason@redhat.com> + + * aclocal.m4: Add ax_cxx_compile_stdcxx.m4. + * configure.ac: Use AX_CXX_COMPILE_STDCXX(11). + +2020-05-14 Jason Merrill <jason@redhat.com> + + * doc/install.texi (Prerequisites): Update boostrap compiler + requirement to C++11/GCC 4.8. + 2020-05-15 Segher Boessenkool <segher@kernel.crashing.org> * config/rs6000/rs6000-builtin.def (BU_FUTURE_MISC_2): Also require diff --git a/gcc/configure b/gcc/configure index 8f0f67494fe..4531d50eb0f 100755 --- a/gcc/configure +++ b/gcc/configure @@ -847,6 +847,7 @@ c_loose_warn loose_warn aliasing_flags CPP +HAVE_CXX11 EGREP GREP CXXCPP @@ -5708,6 +5709,999 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 +$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } +if ${ax_cv_cxx_compile_cxx11+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ax_cv_cxx_compile_cxx11=yes +else + ax_cv_cxx_compile_cxx11=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 +$as_echo "$ax_cv_cxx_compile_cxx11" >&6; } + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX11=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +$as_echo "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +$as_echo "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -19018,7 +20012,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19021 "configure" +#line 20015 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -19124,7 +20118,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19127 "configure" +#line 20121 "configure" #include "confdefs.h" #if HAVE_DLFCN_H ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 21:53 ` Jason Merrill @ 2020-05-16 6:50 ` Richard Biener 2020-06-05 16:00 ` Christophe Lyon 2020-06-08 10:34 ` Martin Jambor 2 siblings, 0 replies; 29+ messages in thread From: Richard Biener @ 2020-05-16 6:50 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches On May 15, 2020 11:53:42 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote: >On 5/15/20 2:21 PM, Richard Biener wrote: >> On May 15, 2020 7:30:38 PM GMT+02:00, Jason Merrill ><jason@redhat.com> wrote: >>> On Fri, May 15, 2020 at 3:15 AM Richard Biener >>> <richard.guenther@gmail.com> >>> wrote: >>> >>>>> +# When bootstrapping with GCC, build stage 1 in C++11 mode to >>> ensure >>>> that a >>>>> +# C++11 compiler can still start the bootstrap. >>>>> if test "$enable_bootstrap:$GXX" = "yes:yes"; then >>>>> + CXX="$CXX -std=gnu++11" >>>> >>>> So I just spotted this - since we're requiring a ISO C++11 compiler >shouldn't >>>> we build stage1 with -std=c++11 rather than gnu++11 (whatever the >detailed >>>> differences are here)? Also not sure what level of -pedantic we'd >need to >>>> avoid GNU extensions even with -std=c++11. Of course there are (I >hope) >>>> a lot less GNU extensions for C++ than there were for C and >hopefully >>>> no extra in gnu++11 compared to gnu++98 which we checked >previously. > >Building stage 1 with -std=c++11 -pedantic-errors works with 8.3.1, but > >fails pretty badly with 4.8.5, > >>> When we first moved to C++ I tried using -std=c++98, but there were >too >>> many places where we were assuming that if we're building with GCC, >we can >>> use GNU C extensions. >>> >>> I'll see if that's still a problem for -std=c++11. > >It doesn't seem to be, so I've made that change. > >>>> There also does not seem to be a configure check which may present >>>> users with a more useful error message than later cryptic fail of >build? >>>> I suppose we cannot simply check __cplusplus for this, can we? Do >>>> other common host compilers need additional options to enable >C++11? >>> >>> Good point, I'll add that. > >This patch uses a test from the autoconf archive to add any needed >flags. Tested with GCC 4.8.5 and clang 3.4.2 (with the above stage 1 >-std=c++11 disabled). > >>>> Should we try to second guess such flags via configury? For >example >>>> GCC 4.8 defaults to -std=gnu++98 and the above only seems to apply >>>> to the bootstrap case so GCC 4.8 cannot be used to build cross >>> compilers >>>> without adjusting CC and CXX? >>> >>> Older GCC is still GCC and will get the flag automatically. >> >> But yes:yes suggests that when building a cross compiler this doesn't >apply? > >True, but the new test should cover that case. > >OK for trunk? OK if there are no further comments over the weekend. Thanks, Richard. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 21:53 ` Jason Merrill 2020-05-16 6:50 ` Richard Biener @ 2020-06-05 16:00 ` Christophe Lyon 2020-06-05 16:39 ` Jason Merrill 2020-06-08 10:34 ` Martin Jambor 2 siblings, 1 reply; 29+ messages in thread From: Christophe Lyon @ 2020-06-05 16:00 UTC (permalink / raw) To: Jason Merrill; +Cc: Richard Biener, GCC Patches On Fri, 15 May 2020 at 23:54, Jason Merrill via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > On 5/15/20 2:21 PM, Richard Biener wrote: > > On May 15, 2020 7:30:38 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote: > >> On Fri, May 15, 2020 at 3:15 AM Richard Biener > >> <richard.guenther@gmail.com> > >> wrote: > >> > >>>> +# When bootstrapping with GCC, build stage 1 in C++11 mode to > >> ensure > >>> that a > >>>> +# C++11 compiler can still start the bootstrap. > >>>> if test "$enable_bootstrap:$GXX" = "yes:yes"; then > >>>> + CXX="$CXX -std=gnu++11" > >>> > >>> So I just spotted this - since we're requiring a ISO C++11 compiler shouldn't > >>> we build stage1 with -std=c++11 rather than gnu++11 (whatever the detailed > >>> differences are here)? Also not sure what level of -pedantic we'd need to > >>> avoid GNU extensions even with -std=c++11. Of course there are (I hope) > >>> a lot less GNU extensions for C++ than there were for C and hopefully > >>> no extra in gnu++11 compared to gnu++98 which we checked previously. > > Building stage 1 with -std=c++11 -pedantic-errors works with 8.3.1, but > fails pretty badly with 4.8.5, > > >> When we first moved to C++ I tried using -std=c++98, but there were too > >> many places where we were assuming that if we're building with GCC, we can > >> use GNU C extensions. > >> > >> I'll see if that's still a problem for -std=c++11. > > It doesn't seem to be, so I've made that change. > > >>> There also does not seem to be a configure check which may present > >>> users with a more useful error message than later cryptic fail of build? > >>> I suppose we cannot simply check __cplusplus for this, can we? Do > >>> other common host compilers need additional options to enable C++11? > >> > >> Good point, I'll add that. > > This patch uses a test from the autoconf archive to add any needed > flags. Tested with GCC 4.8.5 and clang 3.4.2 (with the above stage 1 > -std=c++11 disabled). > > >>> Should we try to second guess such flags via configury? For example > >>> GCC 4.8 defaults to -std=gnu++98 and the above only seems to apply > >>> to the bootstrap case so GCC 4.8 cannot be used to build cross > >> compilers > >>> without adjusting CC and CXX? > >> > >> Older GCC is still GCC and will get the flag automatically. > > > > But yes:yes suggests that when building a cross compiler this doesn't apply? > > True, but the new test should cover that case. > > OK for trunk? Hi, After recent commits on trunk that make use of c++11 features, I'm now unable to build cross-compilers (x86_64 host, arm/aarch64 targets) /gcc/tree-ssa-math-opts.c:124:32: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 basic_block bb = basic_block(); I am using gcc-5.4.0, and this happens because although gcc/configure correctly: checking whether g++ supports C++11 features by default... no checking whether g++ supports C++11 features with -std=gnu++11... yes the actual CXXFLAGS used during the build are set by the toplevel Makefile, which does not include -std=c++11 or -std=gnu++11 IIUC this patch forces c++11 when during bootstrap to make sure that even with a compiler with more recent defaults, we can still build with as low as c++11 requirements. It is not meant to raise the default level of the build compiler. So we probably want a proper fix to force/upgrade the minimal CXXFLAGS required in gcc/configure (to c++11) and have the top-level configure set it down to the minimal CXXFLAGS we want to guarantee? Do we really want to make this distinction? Or is it OK to always force c++11 ? The immediate problem for me is that all my validations for trunk fail during the build stage. FWIW, I removed the check on enable_bootstrap so that -std=c++11 is used for my non-bootstrap cross-compiler, and the build goes further, but still fails when compiling arm-common.c: from /home/christophe.lyon/src/GCC/sources/gcc-fsf-git/trunk/gcc/common/config/arm/arm-common.c:34: /usr/lib/gcc/x86_64-linux-gnu/5/include/mm_malloc.h:42:12: error: attempt to use poisoned "malloc" return malloc (size); Christophe ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-06-05 16:00 ` Christophe Lyon @ 2020-06-05 16:39 ` Jason Merrill 2020-06-05 17:58 ` Jason Merrill 0 siblings, 1 reply; 29+ messages in thread From: Jason Merrill @ 2020-06-05 16:39 UTC (permalink / raw) To: Christophe Lyon; +Cc: Richard Biener, GCC Patches On Fri, Jun 5, 2020 at 12:01 PM Christophe Lyon <christophe.lyon@linaro.org> wrote: > On Fri, 15 May 2020 at 23:54, Jason Merrill via Gcc-patches > <gcc-patches@gcc.gnu.org> wrote: > > > > On 5/15/20 2:21 PM, Richard Biener wrote: > > > On May 15, 2020 7:30:38 PM GMT+02:00, Jason Merrill <jason@redhat.com> > wrote: > > >> On Fri, May 15, 2020 at 3:15 AM Richard Biener > > >> <richard.guenther@gmail.com> > > >> wrote: > > >> > > >>>> +# When bootstrapping with GCC, build stage 1 in C++11 mode to > > >> ensure > > >>> that a > > >>>> +# C++11 compiler can still start the bootstrap. > > >>>> if test "$enable_bootstrap:$GXX" = "yes:yes"; then > > >>>> + CXX="$CXX -std=gnu++11" > > >>> > > >>> So I just spotted this - since we're requiring a ISO C++11 compiler > shouldn't > > >>> we build stage1 with -std=c++11 rather than gnu++11 (whatever the > detailed > > >>> differences are here)? Also not sure what level of -pedantic we'd > need to > > >>> avoid GNU extensions even with -std=c++11. Of course there are (I > hope) > > >>> a lot less GNU extensions for C++ than there were for C and hopefully > > >>> no extra in gnu++11 compared to gnu++98 which we checked previously. > > > > Building stage 1 with -std=c++11 -pedantic-errors works with 8.3.1, but > > fails pretty badly with 4.8.5, > > > > >> When we first moved to C++ I tried using -std=c++98, but there were > too > > >> many places where we were assuming that if we're building with GCC, > we can > > >> use GNU C extensions. > > >> > > >> I'll see if that's still a problem for -std=c++11. > > > > It doesn't seem to be, so I've made that change. > > > > >>> There also does not seem to be a configure check which may present > > >>> users with a more useful error message than later cryptic fail of > build? > > >>> I suppose we cannot simply check __cplusplus for this, can we? Do > > >>> other common host compilers need additional options to enable C++11? > > >> > > >> Good point, I'll add that. > > > > This patch uses a test from the autoconf archive to add any needed > > flags. Tested with GCC 4.8.5 and clang 3.4.2 (with the above stage 1 > > -std=c++11 disabled). > > > > >>> Should we try to second guess such flags via configury? For example > > >>> GCC 4.8 defaults to -std=gnu++98 and the above only seems to apply > > >>> to the bootstrap case so GCC 4.8 cannot be used to build cross > > >> compilers > > >>> without adjusting CC and CXX? > > >> > > >> Older GCC is still GCC and will get the flag automatically. > > > > > > But yes:yes suggests that when building a cross compiler this doesn't > apply? > > > > True, but the new test should cover that case. > > > > OK for trunk? > > Hi, > > After recent commits on trunk that make use of c++11 features, I'm now > unable to build cross-compilers (x86_64 host, arm/aarch64 targets) > /gcc/tree-ssa-math-opts.c:124:32: warning: non-static data member > initializers only available with -std=c++11 or -std=gnu++11 > basic_block bb = basic_block(); > > I am using gcc-5.4.0, and this happens because although gcc/configure > correctly: > checking whether g++ supports C++11 features by default... no > checking whether g++ supports C++11 features with -std=gnu++11... yes > the actual CXXFLAGS used during the build are set by the toplevel Makefile, > which does not include -std=c++11 or -std=gnu++11 > Configure adds the -std=gnu++11 to CXX, not CXXFLAGS, but the problem is the same; we only actually get the flag if you run 'make' in the gcc subdirectory. I guess I need to move that test to toplevel. Jason ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-06-05 16:39 ` Jason Merrill @ 2020-06-05 17:58 ` Jason Merrill 2020-06-07 16:56 ` Christophe Lyon 0 siblings, 1 reply; 29+ messages in thread From: Jason Merrill @ 2020-06-05 17:58 UTC (permalink / raw) To: Christophe Lyon; +Cc: Richard Biener, GCC Patches [-- Attachment #1: Type: text/plain, Size: 4214 bytes --] On 6/5/20 12:39 PM, Jason Merrill wrote: > On Fri, Jun 5, 2020 at 12:01 PM Christophe Lyon > <christophe.lyon@linaro.org <mailto:christophe.lyon@linaro.org>> wrote: > > On Fri, 15 May 2020 at 23:54, Jason Merrill via Gcc-patches > <gcc-patches@gcc.gnu.org <mailto:gcc-patches@gcc.gnu.org>> wrote: > > > > On 5/15/20 2:21 PM, Richard Biener wrote: > > > On May 15, 2020 7:30:38 PM GMT+02:00, Jason Merrill > <jason@redhat.com <mailto:jason@redhat.com>> wrote: > > >> On Fri, May 15, 2020 at 3:15 AM Richard Biener > > >> <richard.guenther@gmail.com <mailto:richard.guenther@gmail.com>> > > >> wrote: > > >> > > >>>> +# When bootstrapping with GCC, build stage 1 in C++11 mode to > > >> ensure > > >>> that a > > >>>> +# C++11 compiler can still start the bootstrap. > > >>>> if test "$enable_bootstrap:$GXX" = "yes:yes"; then > > >>>> + CXX="$CXX -std=gnu++11" > > >>> > > >>> So I just spotted this - since we're requiring a ISO C++11 > compiler shouldn't > > >>> we build stage1 with -std=c++11 rather than gnu++11 (whatever > the detailed > > >>> differences are here)? Also not sure what level of -pedantic > we'd need to > > >>> avoid GNU extensions even with -std=c++11. Of course there > are (I hope) > > >>> a lot less GNU extensions for C++ than there were for C and > hopefully > > >>> no extra in gnu++11 compared to gnu++98 which we checked > previously. > > > > Building stage 1 with -std=c++11 -pedantic-errors works with > 8.3.1, but > > fails pretty badly with 4.8.5, > > > > >> When we first moved to C++ I tried using -std=c++98, but there > were too > > >> many places where we were assuming that if we're building with > GCC, we can > > >> use GNU C extensions. > > >> > > >> I'll see if that's still a problem for -std=c++11. > > > > It doesn't seem to be, so I've made that change. > > > > >>> There also does not seem to be a configure check which may > present > > >>> users with a more useful error message than later cryptic > fail of build? > > >>> I suppose we cannot simply check __cplusplus for this, can > we? Do > > >>> other common host compilers need additional options to enable > C++11? > > >> > > >> Good point, I'll add that. > > > > This patch uses a test from the autoconf archive to add any needed > > flags. Tested with GCC 4.8.5 and clang 3.4.2 (with the above stage 1 > > -std=c++11 disabled). > > > > >>> Should we try to second guess such flags via configury? For > example > > >>> GCC 4.8 defaults to -std=gnu++98 and the above only seems to > apply > > >>> to the bootstrap case so GCC 4.8 cannot be used to build cross > > >> compilers > > >>> without adjusting CC and CXX? > > >> > > >> Older GCC is still GCC and will get the flag automatically. > > > > > > But yes:yes suggests that when building a cross compiler this > doesn't apply? > > > > True, but the new test should cover that case. > > > > OK for trunk? > > Hi, > > After recent commits on trunk that make use of c++11 features, I'm now > unable to build cross-compilers (x86_64 host, arm/aarch64 targets) > /gcc/tree-ssa-math-opts.c:124:32: warning: non-static data member > initializers only available with -std=c++11 or -std=gnu++11 > basic_block bb = basic_block(); > > I am using gcc-5.4.0, and this happens because although > gcc/configure correctly: > checking whether g++ supports C++11 features by default... no > checking whether g++ supports C++11 features with -std=gnu++11... yes > the actual CXXFLAGS used during the build are set by the toplevel > Makefile, > which does not include -std=c++11 or -std=gnu++11 > > > Configure adds the -std=gnu++11 to CXX, not CXXFLAGS, but the problem is > the same; we only actually get the flag if you run 'make' in the gcc > subdirectory. I guess I need to move that test to toplevel. Like so. OK for trunk? [-- Attachment #2: disable-boot.diff --] [-- Type: text/x-patch, Size: 50813 bytes --] commit e9a1dcaf78f7316a771cc6c3a4800784bb18d8e2 Author: Jason Merrill <jason@redhat.com> Date: Fri Jun 5 12:45:11 2020 -0400 c++: Fix --disable-bootstrap with older g++. Previously I had AX_CXX_COMPILE_STDCXX in the gcc directory configure, which added -std=c++11 to CXX if needed, but then CXX is overridden from the toplevel directory, so it didn't have the desired effect. Fixed by moving the check to the toplevel. Currently it is only used when building GCC without bootstrapping; other packages that share the toplevel directory can adjust the condition if they also want to require C++11 support. ChangeLog: * configure.ac: Check AX_CXX_COMPILE_STDCXX if not bootstrapping. * configure: Regenerate. gcc/ChangeLog: * aclocal.m4: Remove ax_cxx_compile_stdcxx.m4. * configure.ac: Remove AX_CXX_COMPILE_STDCXX. * configure: Regenerate. diff --git a/configure.ac b/configure.ac index 59bd92a3e53..1a53ed418e4 100644 --- a/configure.ac +++ b/configure.ac @@ -23,6 +23,7 @@ m4_include(config/acx.m4) m4_include(config/override.m4) m4_include(config/proginstall.m4) m4_include(config/elf.m4) +m4_include(config/ax_cxx_compile_stdcxx.m4) m4_include([libtool.m4]) m4_include([ltoptions.m4]) m4_include([ltsugar.m4]) @@ -1463,9 +1464,12 @@ case "$have_compiler:$host:$target:$enable_bootstrap" in esac # When bootstrapping with GCC, build stage 1 in C++11 mode to ensure that a -# C++11 compiler can still start the bootstrap. +# C++11 compiler can still start the bootstrap. Otherwise, if building GCC, +# require C++11 (or higher). if test "$enable_bootstrap:$GXX" = "yes:yes"; then CXX="$CXX -std=c++11" +elif test "$have_compiler" = yes; then + AX_CXX_COMPILE_STDCXX(11) fi # Used for setting $lt_cv_objdir diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4 index e93c1535063..1737d59d1cb 100644 --- a/gcc/aclocal.m4 +++ b/gcc/aclocal.m4 @@ -18,7 +18,6 @@ m4_include([../ltsugar.m4]) m4_include([../ltversion.m4]) m4_include([../lt~obsolete.m4]) m4_include([../config/acx.m4]) -m4_include([../config/ax_cxx_compile_stdcxx.m4]) m4_include([../config/cet.m4]) m4_include([../config/codeset.m4]) m4_include([../config/depstand.m4]) diff --git a/gcc/configure.ac b/gcc/configure.ac index 60d83c30771..9e7efd13ecc 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -386,8 +386,6 @@ AC_SUBST(PICFLAG_FOR_TARGET) AC_USE_SYSTEM_EXTENSIONS -AX_CXX_COMPILE_STDCXX(11) - AC_PROG_CPP AC_C_INLINE diff --git a/configure b/configure index b7897446c70..a0c5aca9e8d 100755 --- a/configure +++ b/configure @@ -694,6 +694,7 @@ extra_mpc_gmp_configure_flags extra_mpfr_configure_flags gmpinc gmplibs +HAVE_CXX11 do_compare GNATMAKE GNATBIND @@ -5524,9 +5525,1002 @@ $as_echo "$as_me: WARNING: trying to bootstrap a cross compiler" >&2;} esac # When bootstrapping with GCC, build stage 1 in C++11 mode to ensure that a -# C++11 compiler can still start the bootstrap. +# C++11 compiler can still start the bootstrap. Otherwise, if building GCC, +# require C++11 (or higher). if test "$enable_bootstrap:$GXX" = "yes:yes"; then CXX="$CXX -std=c++11" +elif test "$have_compiler" = yes; then + ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 +$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } +if ${ax_cv_cxx_compile_cxx11+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ax_cv_cxx_compile_cxx11=yes +else + ax_cv_cxx_compile_cxx11=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 +$as_echo "$ax_cv_cxx_compile_cxx11" >&6; } + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX11=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +$as_echo "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +$as_echo "#define HAVE_CXX11 1" >>confdefs.h + + fi + + fi # Used for setting $lt_cv_objdir @@ -6489,7 +7483,8 @@ $as_echo "$as_me: WARNING: GNAT is required to build $language" >&2;} esac # Disable jit if -enable-host-shared not specified - # but not if building for Mingw + # but not if building for Mingw. All code in Windows + # is position independent code (PIC). case $target in *mingw*) ;; *) diff --git a/gcc/configure b/gcc/configure index 46850710424..629c7c7e153 100755 --- a/gcc/configure +++ b/gcc/configure @@ -847,7 +847,6 @@ c_loose_warn loose_warn aliasing_flags CPP -HAVE_CXX11 EGREP GREP CXXCPP @@ -5710,998 +5709,6 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } - ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - ac_success=no - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 -$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } -if ${ax_cv_cxx_compile_cxx11+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -// If the compiler admits that it is not ready for C++11, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201103L - -#error "This is not a C++11 compiler" - -#else - -namespace cxx11 -{ - - namespace test_static_assert - { - - template <typename T> - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - } - - namespace test_final_override - { - - struct Base - { - virtual ~Base() {} - virtual void f() {} - }; - - struct Derived : public Base - { - virtual ~Derived() override {} - virtual void f() override {} - }; - - } - - namespace test_double_right_angle_brackets - { - - template < typename T > - struct check {}; - - typedef check<void> single_type; - typedef check<check<void>> double_type; - typedef check<check<check<void>>> triple_type; - typedef check<check<check<check<void>>>> quadruple_type; - - } - - namespace test_decltype - { - - int - f() - { - int a = 1; - decltype(a) b = 2; - return a + b; - } - - } - - namespace test_type_deduction - { - - template < typename T1, typename T2 > - struct is_same - { - static const bool value = false; - }; - - template < typename T > - struct is_same<T, T> - { - static const bool value = true; - }; - - template < typename T1, typename T2 > - auto - add(T1 a1, T2 a2) -> decltype(a1 + a2) - { - return a1 + a2; - } - - int - test(const int c, volatile int v) - { - static_assert(is_same<int, decltype(0)>::value == true, ""); - static_assert(is_same<int, decltype(c)>::value == false, ""); - static_assert(is_same<int, decltype(v)>::value == false, ""); - auto ac = c; - auto av = v; - auto sumi = ac + av + 'x'; - auto sumf = ac + av + 1.0; - static_assert(is_same<int, decltype(ac)>::value == true, ""); - static_assert(is_same<int, decltype(av)>::value == true, ""); - static_assert(is_same<int, decltype(sumi)>::value == true, ""); - static_assert(is_same<int, decltype(sumf)>::value == false, ""); - static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); - return (sumf > 0.0) ? sumi : add(c, v); - } - - } - - namespace test_noexcept - { - - int f() { return 0; } - int g() noexcept { return 0; } - - static_assert(noexcept(f()) == false, ""); - static_assert(noexcept(g()) == true, ""); - - } - - namespace test_constexpr - { - - template < typename CharT > - unsigned long constexpr - strlen_c_r(const CharT *const s, const unsigned long acc) noexcept - { - return *s ? strlen_c_r(s + 1, acc + 1) : acc; - } - - template < typename CharT > - unsigned long constexpr - strlen_c(const CharT *const s) noexcept - { - return strlen_c_r(s, 0UL); - } - - static_assert(strlen_c("") == 0UL, ""); - static_assert(strlen_c("1") == 1UL, ""); - static_assert(strlen_c("example") == 7UL, ""); - static_assert(strlen_c("another\0example") == 7UL, ""); - - } - - namespace test_rvalue_references - { - - template < int N > - struct answer - { - static constexpr int value = N; - }; - - answer<1> f(int&) { return answer<1>(); } - answer<2> f(const int&) { return answer<2>(); } - answer<3> f(int&&) { return answer<3>(); } - - void - test() - { - int i = 0; - const int c = 0; - static_assert(decltype(f(i))::value == 1, ""); - static_assert(decltype(f(c))::value == 2, ""); - static_assert(decltype(f(0))::value == 3, ""); - } - - } - - namespace test_uniform_initialization - { - - struct test - { - static const int zero {}; - static const int one {1}; - }; - - static_assert(test::zero == 0, ""); - static_assert(test::one == 1, ""); - - } - - namespace test_lambdas - { - - void - test1() - { - auto lambda1 = [](){}; - auto lambda2 = lambda1; - lambda1(); - lambda2(); - } - - int - test2() - { - auto a = [](int i, int j){ return i + j; }(1, 2); - auto b = []() -> int { return '0'; }(); - auto c = [=](){ return a + b; }(); - auto d = [&](){ return c; }(); - auto e = [a, &b](int x) mutable { - const auto identity = [](int y){ return y; }; - for (auto i = 0; i < a; ++i) - a += b--; - return x + identity(a + b); - }(0); - return a + b + c + d + e; - } - - int - test3() - { - const auto nullary = [](){ return 0; }; - const auto unary = [](int x){ return x; }; - using nullary_t = decltype(nullary); - using unary_t = decltype(unary); - const auto higher1st = [](nullary_t f){ return f(); }; - const auto higher2nd = [unary](nullary_t f1){ - return [unary, f1](unary_t f2){ return f2(unary(f1())); }; - }; - return higher1st(nullary) + higher2nd(nullary)(unary); - } - - } - - namespace test_variadic_templates - { - - template <int...> - struct sum; - - template <int N0, int... N1toN> - struct sum<N0, N1toN...> - { - static constexpr auto value = N0 + sum<N1toN...>::value; - }; - - template <> - struct sum<> - { - static constexpr auto value = 0; - }; - - static_assert(sum<>::value == 0, ""); - static_assert(sum<1>::value == 1, ""); - static_assert(sum<23>::value == 23, ""); - static_assert(sum<1, 2>::value == 3, ""); - static_assert(sum<5, 5, 11>::value == 21, ""); - static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); - - } - - // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae - // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function - // because of this. - namespace test_template_alias_sfinae - { - - struct foo {}; - - template<typename T> - using member = typename T::member_type; - - template<typename T> - void func(...) {} - - template<typename T> - void func(member<T>*) {} - - void test(); - - void test() { func<foo>(0); } - - } - -} // namespace cxx11 - -#endif // __cplusplus >= 201103L - - - -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ax_cv_cxx_compile_cxx11=yes -else - ax_cv_cxx_compile_cxx11=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 -$as_echo "$ax_cv_cxx_compile_cxx11" >&6; } - if test x$ax_cv_cxx_compile_cxx11 = xyes; then - ac_success=yes - fi - - if test x$ac_success = xno; then - for alternative in ${ax_cxx_compile_alternatives}; do - switch="-std=gnu++${alternative}" - cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 -$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } -if eval \${$cachevar+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_CXX="$CXX" - CXX="$CXX $switch" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -// If the compiler admits that it is not ready for C++11, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201103L - -#error "This is not a C++11 compiler" - -#else - -namespace cxx11 -{ - - namespace test_static_assert - { - - template <typename T> - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - } - - namespace test_final_override - { - - struct Base - { - virtual ~Base() {} - virtual void f() {} - }; - - struct Derived : public Base - { - virtual ~Derived() override {} - virtual void f() override {} - }; - - } - - namespace test_double_right_angle_brackets - { - - template < typename T > - struct check {}; - - typedef check<void> single_type; - typedef check<check<void>> double_type; - typedef check<check<check<void>>> triple_type; - typedef check<check<check<check<void>>>> quadruple_type; - - } - - namespace test_decltype - { - - int - f() - { - int a = 1; - decltype(a) b = 2; - return a + b; - } - - } - - namespace test_type_deduction - { - - template < typename T1, typename T2 > - struct is_same - { - static const bool value = false; - }; - - template < typename T > - struct is_same<T, T> - { - static const bool value = true; - }; - - template < typename T1, typename T2 > - auto - add(T1 a1, T2 a2) -> decltype(a1 + a2) - { - return a1 + a2; - } - - int - test(const int c, volatile int v) - { - static_assert(is_same<int, decltype(0)>::value == true, ""); - static_assert(is_same<int, decltype(c)>::value == false, ""); - static_assert(is_same<int, decltype(v)>::value == false, ""); - auto ac = c; - auto av = v; - auto sumi = ac + av + 'x'; - auto sumf = ac + av + 1.0; - static_assert(is_same<int, decltype(ac)>::value == true, ""); - static_assert(is_same<int, decltype(av)>::value == true, ""); - static_assert(is_same<int, decltype(sumi)>::value == true, ""); - static_assert(is_same<int, decltype(sumf)>::value == false, ""); - static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); - return (sumf > 0.0) ? sumi : add(c, v); - } - - } - - namespace test_noexcept - { - - int f() { return 0; } - int g() noexcept { return 0; } - - static_assert(noexcept(f()) == false, ""); - static_assert(noexcept(g()) == true, ""); - - } - - namespace test_constexpr - { - - template < typename CharT > - unsigned long constexpr - strlen_c_r(const CharT *const s, const unsigned long acc) noexcept - { - return *s ? strlen_c_r(s + 1, acc + 1) : acc; - } - - template < typename CharT > - unsigned long constexpr - strlen_c(const CharT *const s) noexcept - { - return strlen_c_r(s, 0UL); - } - - static_assert(strlen_c("") == 0UL, ""); - static_assert(strlen_c("1") == 1UL, ""); - static_assert(strlen_c("example") == 7UL, ""); - static_assert(strlen_c("another\0example") == 7UL, ""); - - } - - namespace test_rvalue_references - { - - template < int N > - struct answer - { - static constexpr int value = N; - }; - - answer<1> f(int&) { return answer<1>(); } - answer<2> f(const int&) { return answer<2>(); } - answer<3> f(int&&) { return answer<3>(); } - - void - test() - { - int i = 0; - const int c = 0; - static_assert(decltype(f(i))::value == 1, ""); - static_assert(decltype(f(c))::value == 2, ""); - static_assert(decltype(f(0))::value == 3, ""); - } - - } - - namespace test_uniform_initialization - { - - struct test - { - static const int zero {}; - static const int one {1}; - }; - - static_assert(test::zero == 0, ""); - static_assert(test::one == 1, ""); - - } - - namespace test_lambdas - { - - void - test1() - { - auto lambda1 = [](){}; - auto lambda2 = lambda1; - lambda1(); - lambda2(); - } - - int - test2() - { - auto a = [](int i, int j){ return i + j; }(1, 2); - auto b = []() -> int { return '0'; }(); - auto c = [=](){ return a + b; }(); - auto d = [&](){ return c; }(); - auto e = [a, &b](int x) mutable { - const auto identity = [](int y){ return y; }; - for (auto i = 0; i < a; ++i) - a += b--; - return x + identity(a + b); - }(0); - return a + b + c + d + e; - } - - int - test3() - { - const auto nullary = [](){ return 0; }; - const auto unary = [](int x){ return x; }; - using nullary_t = decltype(nullary); - using unary_t = decltype(unary); - const auto higher1st = [](nullary_t f){ return f(); }; - const auto higher2nd = [unary](nullary_t f1){ - return [unary, f1](unary_t f2){ return f2(unary(f1())); }; - }; - return higher1st(nullary) + higher2nd(nullary)(unary); - } - - } - - namespace test_variadic_templates - { - - template <int...> - struct sum; - - template <int N0, int... N1toN> - struct sum<N0, N1toN...> - { - static constexpr auto value = N0 + sum<N1toN...>::value; - }; - - template <> - struct sum<> - { - static constexpr auto value = 0; - }; - - static_assert(sum<>::value == 0, ""); - static_assert(sum<1>::value == 1, ""); - static_assert(sum<23>::value == 23, ""); - static_assert(sum<1, 2>::value == 3, ""); - static_assert(sum<5, 5, 11>::value == 21, ""); - static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); - - } - - // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae - // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function - // because of this. - namespace test_template_alias_sfinae - { - - struct foo {}; - - template<typename T> - using member = typename T::member_type; - - template<typename T> - void func(...) {} - - template<typename T> - void func(member<T>*) {} - - void test(); - - void test() { func<foo>(0); } - - } - -} // namespace cxx11 - -#endif // __cplusplus >= 201103L - - - -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - eval $cachevar=yes -else - eval $cachevar=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CXX="$ac_save_CXX" -fi -eval ac_res=\$$cachevar - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi - ac_success=yes - break - fi - done - fi - - if test x$ac_success = xno; then - for alternative in ${ax_cxx_compile_alternatives}; do - for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do - cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 -$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } -if eval \${$cachevar+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_CXX="$CXX" - CXX="$CXX $switch" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -// If the compiler admits that it is not ready for C++11, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201103L - -#error "This is not a C++11 compiler" - -#else - -namespace cxx11 -{ - - namespace test_static_assert - { - - template <typename T> - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - } - - namespace test_final_override - { - - struct Base - { - virtual ~Base() {} - virtual void f() {} - }; - - struct Derived : public Base - { - virtual ~Derived() override {} - virtual void f() override {} - }; - - } - - namespace test_double_right_angle_brackets - { - - template < typename T > - struct check {}; - - typedef check<void> single_type; - typedef check<check<void>> double_type; - typedef check<check<check<void>>> triple_type; - typedef check<check<check<check<void>>>> quadruple_type; - - } - - namespace test_decltype - { - - int - f() - { - int a = 1; - decltype(a) b = 2; - return a + b; - } - - } - - namespace test_type_deduction - { - - template < typename T1, typename T2 > - struct is_same - { - static const bool value = false; - }; - - template < typename T > - struct is_same<T, T> - { - static const bool value = true; - }; - - template < typename T1, typename T2 > - auto - add(T1 a1, T2 a2) -> decltype(a1 + a2) - { - return a1 + a2; - } - - int - test(const int c, volatile int v) - { - static_assert(is_same<int, decltype(0)>::value == true, ""); - static_assert(is_same<int, decltype(c)>::value == false, ""); - static_assert(is_same<int, decltype(v)>::value == false, ""); - auto ac = c; - auto av = v; - auto sumi = ac + av + 'x'; - auto sumf = ac + av + 1.0; - static_assert(is_same<int, decltype(ac)>::value == true, ""); - static_assert(is_same<int, decltype(av)>::value == true, ""); - static_assert(is_same<int, decltype(sumi)>::value == true, ""); - static_assert(is_same<int, decltype(sumf)>::value == false, ""); - static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); - return (sumf > 0.0) ? sumi : add(c, v); - } - - } - - namespace test_noexcept - { - - int f() { return 0; } - int g() noexcept { return 0; } - - static_assert(noexcept(f()) == false, ""); - static_assert(noexcept(g()) == true, ""); - - } - - namespace test_constexpr - { - - template < typename CharT > - unsigned long constexpr - strlen_c_r(const CharT *const s, const unsigned long acc) noexcept - { - return *s ? strlen_c_r(s + 1, acc + 1) : acc; - } - - template < typename CharT > - unsigned long constexpr - strlen_c(const CharT *const s) noexcept - { - return strlen_c_r(s, 0UL); - } - - static_assert(strlen_c("") == 0UL, ""); - static_assert(strlen_c("1") == 1UL, ""); - static_assert(strlen_c("example") == 7UL, ""); - static_assert(strlen_c("another\0example") == 7UL, ""); - - } - - namespace test_rvalue_references - { - - template < int N > - struct answer - { - static constexpr int value = N; - }; - - answer<1> f(int&) { return answer<1>(); } - answer<2> f(const int&) { return answer<2>(); } - answer<3> f(int&&) { return answer<3>(); } - - void - test() - { - int i = 0; - const int c = 0; - static_assert(decltype(f(i))::value == 1, ""); - static_assert(decltype(f(c))::value == 2, ""); - static_assert(decltype(f(0))::value == 3, ""); - } - - } - - namespace test_uniform_initialization - { - - struct test - { - static const int zero {}; - static const int one {1}; - }; - - static_assert(test::zero == 0, ""); - static_assert(test::one == 1, ""); - - } - - namespace test_lambdas - { - - void - test1() - { - auto lambda1 = [](){}; - auto lambda2 = lambda1; - lambda1(); - lambda2(); - } - - int - test2() - { - auto a = [](int i, int j){ return i + j; }(1, 2); - auto b = []() -> int { return '0'; }(); - auto c = [=](){ return a + b; }(); - auto d = [&](){ return c; }(); - auto e = [a, &b](int x) mutable { - const auto identity = [](int y){ return y; }; - for (auto i = 0; i < a; ++i) - a += b--; - return x + identity(a + b); - }(0); - return a + b + c + d + e; - } - - int - test3() - { - const auto nullary = [](){ return 0; }; - const auto unary = [](int x){ return x; }; - using nullary_t = decltype(nullary); - using unary_t = decltype(unary); - const auto higher1st = [](nullary_t f){ return f(); }; - const auto higher2nd = [unary](nullary_t f1){ - return [unary, f1](unary_t f2){ return f2(unary(f1())); }; - }; - return higher1st(nullary) + higher2nd(nullary)(unary); - } - - } - - namespace test_variadic_templates - { - - template <int...> - struct sum; - - template <int N0, int... N1toN> - struct sum<N0, N1toN...> - { - static constexpr auto value = N0 + sum<N1toN...>::value; - }; - - template <> - struct sum<> - { - static constexpr auto value = 0; - }; - - static_assert(sum<>::value == 0, ""); - static_assert(sum<1>::value == 1, ""); - static_assert(sum<23>::value == 23, ""); - static_assert(sum<1, 2>::value == 3, ""); - static_assert(sum<5, 5, 11>::value == 21, ""); - static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); - - } - - // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae - // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function - // because of this. - namespace test_template_alias_sfinae - { - - struct foo {}; - - template<typename T> - using member = typename T::member_type; - - template<typename T> - void func(...) {} - - template<typename T> - void func(member<T>*) {} - - void test(); - - void test() { func<foo>(0); } - - } - -} // namespace cxx11 - -#endif // __cplusplus >= 201103L - - - -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - eval $cachevar=yes -else - eval $cachevar=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CXX="$ac_save_CXX" -fi -eval ac_res=\$$cachevar - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi - ac_success=yes - break - fi - done - if test x$ac_success = xyes; then - break - fi - done - fi - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - if test x$ax_cxx_compile_cxx11_required = xtrue; then - if test x$ac_success = xno; then - as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 - fi - fi - if test x$ac_success = xno; then - HAVE_CXX11=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 -$as_echo "$as_me: No compiler with C++11 support was found" >&6;} - else - HAVE_CXX11=1 - -$as_echo "#define HAVE_CXX11 1" >>confdefs.h - - fi - - - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -20012,7 +19019,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 20015 "configure" +#line 19022 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -20118,7 +19125,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 20121 "configure" +#line 19128 "configure" #include "confdefs.h" #if HAVE_DLFCN_H ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-06-05 17:58 ` Jason Merrill @ 2020-06-07 16:56 ` Christophe Lyon 2020-06-08 2:10 ` Jason Merrill 0 siblings, 1 reply; 29+ messages in thread From: Christophe Lyon @ 2020-06-07 16:56 UTC (permalink / raw) To: Jason Merrill; +Cc: Richard Biener, GCC Patches [-- Attachment #1: Type: text/plain, Size: 4710 bytes --] On Fri, 5 Jun 2020 at 19:58, Jason Merrill <jason@redhat.com> wrote: > > On 6/5/20 12:39 PM, Jason Merrill wrote: > > On Fri, Jun 5, 2020 at 12:01 PM Christophe Lyon > > <christophe.lyon@linaro.org <mailto:christophe.lyon@linaro.org>> wrote: > > > > On Fri, 15 May 2020 at 23:54, Jason Merrill via Gcc-patches > > <gcc-patches@gcc.gnu.org <mailto:gcc-patches@gcc.gnu.org>> wrote: > > > > > > On 5/15/20 2:21 PM, Richard Biener wrote: > > > > On May 15, 2020 7:30:38 PM GMT+02:00, Jason Merrill > > <jason@redhat.com <mailto:jason@redhat.com>> wrote: > > > >> On Fri, May 15, 2020 at 3:15 AM Richard Biener > > > >> <richard.guenther@gmail.com <mailto:richard.guenther@gmail.com>> > > > >> wrote: > > > >> > > > >>>> +# When bootstrapping with GCC, build stage 1 in C++11 mode to > > > >> ensure > > > >>> that a > > > >>>> +# C++11 compiler can still start the bootstrap. > > > >>>> if test "$enable_bootstrap:$GXX" = "yes:yes"; then > > > >>>> + CXX="$CXX -std=gnu++11" > > > >>> > > > >>> So I just spotted this - since we're requiring a ISO C++11 > > compiler shouldn't > > > >>> we build stage1 with -std=c++11 rather than gnu++11 (whatever > > the detailed > > > >>> differences are here)? Also not sure what level of -pedantic > > we'd need to > > > >>> avoid GNU extensions even with -std=c++11. Of course there > > are (I hope) > > > >>> a lot less GNU extensions for C++ than there were for C and > > hopefully > > > >>> no extra in gnu++11 compared to gnu++98 which we checked > > previously. > > > > > > Building stage 1 with -std=c++11 -pedantic-errors works with > > 8.3.1, but > > > fails pretty badly with 4.8.5, > > > > > > >> When we first moved to C++ I tried using -std=c++98, but there > > were too > > > >> many places where we were assuming that if we're building with > > GCC, we can > > > >> use GNU C extensions. > > > >> > > > >> I'll see if that's still a problem for -std=c++11. > > > > > > It doesn't seem to be, so I've made that change. > > > > > > >>> There also does not seem to be a configure check which may > > present > > > >>> users with a more useful error message than later cryptic > > fail of build? > > > >>> I suppose we cannot simply check __cplusplus for this, can > > we? Do > > > >>> other common host compilers need additional options to enable > > C++11? > > > >> > > > >> Good point, I'll add that. > > > > > > This patch uses a test from the autoconf archive to add any needed > > > flags. Tested with GCC 4.8.5 and clang 3.4.2 (with the above stage 1 > > > -std=c++11 disabled). > > > > > > >>> Should we try to second guess such flags via configury? For > > example > > > >>> GCC 4.8 defaults to -std=gnu++98 and the above only seems to > > apply > > > >>> to the bootstrap case so GCC 4.8 cannot be used to build cross > > > >> compilers > > > >>> without adjusting CC and CXX? > > > >> > > > >> Older GCC is still GCC and will get the flag automatically. > > > > > > > > But yes:yes suggests that when building a cross compiler this > > doesn't apply? > > > > > > True, but the new test should cover that case. > > > > > > OK for trunk? > > > > Hi, > > > > After recent commits on trunk that make use of c++11 features, I'm now > > unable to build cross-compilers (x86_64 host, arm/aarch64 targets) > > /gcc/tree-ssa-math-opts.c:124:32: warning: non-static data member > > initializers only available with -std=c++11 or -std=gnu++11 > > basic_block bb = basic_block(); > > > > I am using gcc-5.4.0, and this happens because although > > gcc/configure correctly: > > checking whether g++ supports C++11 features by default... no > > checking whether g++ supports C++11 features with -std=gnu++11... yes > > the actual CXXFLAGS used during the build are set by the toplevel > > Makefile, > > which does not include -std=c++11 or -std=gnu++11 > > > > > > Configure adds the -std=gnu++11 to CXX, not CXXFLAGS, but the problem is > > the same; we only actually get the flag if you run 'make' in the gcc > > subdirectory. I guess I need to move that test to toplevel. > > Like so. OK for trunk? > Yes it works for me (I thought we needed more subtle logic for configurations I couldn't think of). As I mentioned earlier, the build of the arm port is broken after this upgrade, and the attached patch fixes it. OK? Thanks, Christophe [-- Attachment #2: arm-common-algorithm.patch --] [-- Type: text/x-patch, Size: 1125 bytes --] [arm] (header usage fix) include c++ algorithm header via system.h After the recent commit that forces uses of c++11, the arm part failed to build because it does not include <algorithm> via system.h as should be done. This results in: from /gcc/common/config/arm/arm-common.c:34: /usr/lib/gcc/x86_64-linux-gnu/5/include/mm_malloc.h:42:12: error: attempt to use poisoned "malloc" return malloc (size); This patch fixes the problem by defining INCLUDE_ALGORITHM before including system.h and no longer includes <algorithm> directly. diff --git a/gcc/common/config/arm/arm-common.c b/gcc/common/config/arm/arm-common.c index 78a779c..8e986e4 100644 --- a/gcc/common/config/arm/arm-common.c +++ b/gcc/common/config/arm/arm-common.c @@ -19,6 +19,7 @@ #define INCLUDE_LIST #define INCLUDE_VECTOR +#define INCLUDE_ALGORITHM #include "config.h" #include "system.h" #include "coretypes.h" @@ -31,7 +32,6 @@ #include "flags.h" #include "sbitmap.h" #include "diagnostic.h" -#include <algorithm> /* Set default optimization options. */ static const struct default_options arm_option_optimization_table[] = ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-06-07 16:56 ` Christophe Lyon @ 2020-06-08 2:10 ` Jason Merrill 0 siblings, 0 replies; 29+ messages in thread From: Jason Merrill @ 2020-06-08 2:10 UTC (permalink / raw) To: Christophe Lyon; +Cc: Richard Biener, GCC Patches On 6/7/20 12:56 PM, Christophe Lyon wrote: > On Fri, 5 Jun 2020 at 19:58, Jason Merrill <jason@redhat.com> wrote: >> >> On 6/5/20 12:39 PM, Jason Merrill wrote: >>> On Fri, Jun 5, 2020 at 12:01 PM Christophe Lyon >>> <christophe.lyon@linaro.org <mailto:christophe.lyon@linaro.org>> wrote: >>> >>> On Fri, 15 May 2020 at 23:54, Jason Merrill via Gcc-patches >>> <gcc-patches@gcc.gnu.org <mailto:gcc-patches@gcc.gnu.org>> wrote: >>> > >>> > On 5/15/20 2:21 PM, Richard Biener wrote: >>> > > On May 15, 2020 7:30:38 PM GMT+02:00, Jason Merrill >>> <jason@redhat.com <mailto:jason@redhat.com>> wrote: >>> > >> On Fri, May 15, 2020 at 3:15 AM Richard Biener >>> > >> <richard.guenther@gmail.com <mailto:richard.guenther@gmail.com>> >>> > >> wrote: >>> > >> >>> > >>>> +# When bootstrapping with GCC, build stage 1 in C++11 mode to >>> > >> ensure >>> > >>> that a >>> > >>>> +# C++11 compiler can still start the bootstrap. >>> > >>>> if test "$enable_bootstrap:$GXX" = "yes:yes"; then >>> > >>>> + CXX="$CXX -std=gnu++11" >>> > >>> >>> > >>> So I just spotted this - since we're requiring a ISO C++11 >>> compiler shouldn't >>> > >>> we build stage1 with -std=c++11 rather than gnu++11 (whatever >>> the detailed >>> > >>> differences are here)? Also not sure what level of -pedantic >>> we'd need to >>> > >>> avoid GNU extensions even with -std=c++11. Of course there >>> are (I hope) >>> > >>> a lot less GNU extensions for C++ than there were for C and >>> hopefully >>> > >>> no extra in gnu++11 compared to gnu++98 which we checked >>> previously. >>> > >>> > Building stage 1 with -std=c++11 -pedantic-errors works with >>> 8.3.1, but >>> > fails pretty badly with 4.8.5, >>> > >>> > >> When we first moved to C++ I tried using -std=c++98, but there >>> were too >>> > >> many places where we were assuming that if we're building with >>> GCC, we can >>> > >> use GNU C extensions. >>> > >> >>> > >> I'll see if that's still a problem for -std=c++11. >>> > >>> > It doesn't seem to be, so I've made that change. >>> > >>> > >>> There also does not seem to be a configure check which may >>> present >>> > >>> users with a more useful error message than later cryptic >>> fail of build? >>> > >>> I suppose we cannot simply check __cplusplus for this, can >>> we? Do >>> > >>> other common host compilers need additional options to enable >>> C++11? >>> > >> >>> > >> Good point, I'll add that. >>> > >>> > This patch uses a test from the autoconf archive to add any needed >>> > flags. Tested with GCC 4.8.5 and clang 3.4.2 (with the above stage 1 >>> > -std=c++11 disabled). >>> > >>> > >>> Should we try to second guess such flags via configury? For >>> example >>> > >>> GCC 4.8 defaults to -std=gnu++98 and the above only seems to >>> apply >>> > >>> to the bootstrap case so GCC 4.8 cannot be used to build cross >>> > >> compilers >>> > >>> without adjusting CC and CXX? >>> > >> >>> > >> Older GCC is still GCC and will get the flag automatically. >>> > > >>> > > But yes:yes suggests that when building a cross compiler this >>> doesn't apply? >>> > >>> > True, but the new test should cover that case. >>> > >>> > OK for trunk? >>> >>> Hi, >>> >>> After recent commits on trunk that make use of c++11 features, I'm now >>> unable to build cross-compilers (x86_64 host, arm/aarch64 targets) >>> /gcc/tree-ssa-math-opts.c:124:32: warning: non-static data member >>> initializers only available with -std=c++11 or -std=gnu++11 >>> basic_block bb = basic_block(); >>> >>> I am using gcc-5.4.0, and this happens because although >>> gcc/configure correctly: >>> checking whether g++ supports C++11 features by default... no >>> checking whether g++ supports C++11 features with -std=gnu++11... yes >>> the actual CXXFLAGS used during the build are set by the toplevel >>> Makefile, >>> which does not include -std=c++11 or -std=gnu++11 >>> >>> >>> Configure adds the -std=gnu++11 to CXX, not CXXFLAGS, but the problem is >>> the same; we only actually get the flag if you run 'make' in the gcc >>> subdirectory. I guess I need to move that test to toplevel. >> >> Like so. OK for trunk? >> > > Yes it works for me (I thought we needed more subtle logic for > configurations I couldn't think of). > > As I mentioned earlier, the build of the arm port is broken after this > upgrade, and the attached patch fixes it. OK? OK. Jason ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-05-15 21:53 ` Jason Merrill 2020-05-16 6:50 ` Richard Biener 2020-06-05 16:00 ` Christophe Lyon @ 2020-06-08 10:34 ` Martin Jambor 2020-06-08 19:03 ` Jason Merrill 2 siblings, 1 reply; 29+ messages in thread From: Martin Jambor @ 2020-06-08 10:34 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches, Richard Biener Hi, On Fri, May 15 2020, Jason Merrill via Gcc-patches wrote: > commit f466a9f3f121f16b97071162806255fb464718f2 > Author: Jason Merrill <jason@redhat.com> > Date: Fri May 15 17:15:38 2020 -0400 > > bootstrap: Update requirement to C++11. > > There was general agreement last November that we would move to allowing > C++11 features to be used in GCC 11; this patch implements that direction. > since this commit (gcc-11-462-g5329b59a2e1) I cannot bootstrap GCC on gcc45.fsffrance.org compile farm machine which is an i586-linux-gnu box where the system compiler is GCC 4.9.2 which I believe should be new enough. Still, stage 1 fails with the errors below. What baffles me is that only bootstrap fails on the old machine. If I configure with --disable-bootstrap, make finishes fine. For the record, I configure gcc there with: /home/jamborm/gcc/trunk/src/configure --prefix=/home/jamborm/gcc/trunk/inst --enable-languages=c,c++ --enable-checking=yes --disable-libsanitizer --disable-multilib --disable-libcilkrts --with-gmp=/opt/cfarm/gmp-latest --with-mpfr=/opt/cfarm/mpfr-latest --with-mpc=/opt/cfarm/mpc-latest In my other i686 testing environment, which is a chroot with gcc 8.3.0 as the system compiler, I can bootstrap without any issues. I can open a PR if you want me to. Thanks, Martin g++ -std=c++11 -fno-PIE -c -g -DIN_GCC -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-format -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common -DHAVE_CONFIG_H -I. -I. -I/home/jamborm/gcc/trunk/src/gcc -I/home/jamborm/gcc/trunk/src/gcc/. -I/home/jamborm/gcc/trunk/src/gcc/../include -I/home/jamborm/gcc/trunk/src/gcc/../libcpp/include -I/opt/cfarm/gmp-latest/include -I/opt/cfarm/mpfr-latest/include -I/opt/cfarm/mpc-latest/include -I/home/jamborm/gcc/trunk/src/gcc/../libdecnumber -I/home/jamborm/gcc/trunk/src/gcc/../libdecnumber/bid -I../libdecnumber -I/home/jamborm/gcc/trunk/src/gcc/../libbacktrace -o i386-options.o -MT i386-options.o -MMD -MP -MF ./.deps/i386-options.TPo /home/jamborm/gcc/trunk/src/gcc/config/i386/i386-options.c In file included from /home/jamborm/gcc/trunk/src/gcc/config/i386/i386-options.c:94:0: /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:35:56: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:137:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:140:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:239:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:242:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:343:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:346:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:547:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:552:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:650:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:653:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:751:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:754:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:858:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:861:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:965:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:970:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:970:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:970:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:970:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:970:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1079:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1084:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1084:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1084:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1084:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1084:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1201:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1206:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1206:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1206:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1206:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1206:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1317:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1322:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1322:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1322:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1322:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1322:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1454:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1459:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1459:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1459:29: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1459:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1459:29: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1593:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1601:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1601:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1601:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1601:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1601:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1706:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1711:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1711:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1711:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1711:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1711:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1810:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1815:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1815:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1815:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1815:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1815:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1912:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ DUMMY_STRINGOP_ALGS}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:1916:22: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {100000, unrolled_loop, false}, {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2016:68: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2122:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2226:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2330:70: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2438:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2443:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2548:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2555:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::max’ {-1, libcall, false}}}}; ^ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2555:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2555:36: error: uninitialized const member ‘stringop_algs::stringop_strategy::alg’ /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2555:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::alg’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:2555:36: warning: missing initializer for member ‘stringop_algs::stringop_strategy::noalign’ [-Wmissing-field-initializers] /home/jamborm/gcc/trunk/src/gcc/config/i386/t-i386:48: recipe for target 'i386-options.o' failed make: *** [i386-options.o] Error 1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH RFC] bootstrap: Update requirement to C++11. 2020-06-08 10:34 ` Martin Jambor @ 2020-06-08 19:03 ` Jason Merrill 0 siblings, 0 replies; 29+ messages in thread From: Jason Merrill @ 2020-06-08 19:03 UTC (permalink / raw) To: Martin Jambor; +Cc: GCC Patches, Richard Biener On Mon, Jun 8, 2020 at 6:54 AM Martin Jambor <mjambor@suse.cz> wrote: > Hi, > > On Fri, May 15 2020, Jason Merrill via Gcc-patches wrote: > > commit f466a9f3f121f16b97071162806255fb464718f2 > > Author: Jason Merrill <jason@redhat.com> > > Date: Fri May 15 17:15:38 2020 -0400 > > > > bootstrap: Update requirement to C++11. > > > > There was general agreement last November that we would move to > allowing > > C++11 features to be used in GCC 11; this patch implements that > direction. > > > > since this commit (gcc-11-462-g5329b59a2e1) I cannot bootstrap GCC on > gcc45.fsffrance.org compile farm machine which is an i586-linux-gnu box > where the system compiler is GCC 4.9.2 which I believe should be new > enough. Still, stage 1 fails with the errors below. > > What baffles me is that only bootstrap fails on the old machine. If I > configure with --disable-bootstrap, make finishes fine. For the record, > I configure gcc there with: > > /home/jamborm/gcc/trunk/src/configure > --prefix=/home/jamborm/gcc/trunk/inst --enable-languages=c,c++ > --enable-checking=yes --disable-libsanitizer --disable-multilib > --disable-libcilkrts --with-gmp=/opt/cfarm/gmp-latest > --with-mpfr=/opt/cfarm/mpfr-latest --with-mpc=/opt/cfarm/mpc-latest > > In my other i686 testing environment, which is a chroot with gcc 8.3.0 > as the system compiler, I can bootstrap without any issues. > > I can open a PR if you want me to. > > Thanks, > > Martin > > > g++ -std=c++11 -fno-PIE -c -g -DIN_GCC -fno-exceptions -fno-rtti > -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings > -Wcast-qual -Wno-format -Wmissing-format-attribute -Woverloaded-virtual > -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings > -fno-common -DHAVE_CONFIG_H -I. -I. -I/home/jamborm/gcc/trunk/src/gcc > -I/home/jamborm/gcc/trunk/src/gcc/. > -I/home/jamborm/gcc/trunk/src/gcc/../include > -I/home/jamborm/gcc/trunk/src/gcc/../libcpp/include > -I/opt/cfarm/gmp-latest/include -I/opt/cfarm/mpfr-latest/include > -I/opt/cfarm/mpc-latest/include > -I/home/jamborm/gcc/trunk/src/gcc/../libdecnumber > -I/home/jamborm/gcc/trunk/src/gcc/../libdecnumber/bid -I../libdecnumber > -I/home/jamborm/gcc/trunk/src/gcc/../libbacktrace -o i386-options.o -MT > i386-options.o -MMD -MP -MF ./.deps/i386-options.TPo > /home/jamborm/gcc/trunk/src/gcc/config/i386/i386-options.c > In file included from > /home/jamborm/gcc/trunk/src/gcc/config/i386/i386-options.c:94:0: > /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: error: > uninitialized const member ‘stringop_algs::stringop_strategy::max’ > {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}}}; > ^ > /home/jamborm/gcc/trunk/src/gcc/config/i386/x86-tune-costs.h:32:56: > warning: missing initializer for member > ‘stringop_algs::stringop_strategy::max’ [-Wmissing-field-initializers] > Hmm, yes, this was PR 49132, fixed in GCC 5. I think we will want to work around it by removing the 'const's from stringop_strategy. Jason ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2020-06-08 19:04 UTC | newest] Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-05-14 21:05 [PATCH RFC] bootstrap: Update requirement to C++11 Jason Merrill 2020-05-14 21:09 ` Jakub Jelinek 2020-05-15 7:14 ` Richard Biener 2020-05-15 8:30 ` Richard Sandiford 2020-05-15 9:26 ` Richard Biener 2020-05-15 9:58 ` Richard Sandiford 2020-05-15 10:15 ` Richard Biener 2020-05-15 14:08 ` Richard Sandiford 2020-05-16 1:47 ` Martin Sebor 2020-05-16 2:45 ` Re: Jason Merrill 2020-05-16 10:43 ` [PATCH] Describe coding conventions surrounding "auto" Richard Sandiford 2020-05-18 16:37 ` Martin Sebor 2020-05-18 18:02 ` Richard Sandiford 2020-05-18 18:42 ` Jason Merrill 2020-05-18 22:51 ` Martin Sebor 2020-05-19 9:26 ` Richard Sandiford 2020-05-19 9:36 ` Nicholas Krause 2020-05-15 17:36 ` [PATCH RFC] bootstrap: Update requirement to C++11 Jason Merrill 2020-05-15 17:30 ` Jason Merrill 2020-05-15 18:21 ` Richard Biener 2020-05-15 21:53 ` Jason Merrill 2020-05-16 6:50 ` Richard Biener 2020-06-05 16:00 ` Christophe Lyon 2020-06-05 16:39 ` Jason Merrill 2020-06-05 17:58 ` Jason Merrill 2020-06-07 16:56 ` Christophe Lyon 2020-06-08 2:10 ` Jason Merrill 2020-06-08 10:34 ` Martin Jambor 2020-06-08 19:03 ` Jason Merrill
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).