public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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 &lt;<b>rtx_jump_table_data *</b>&gt; (insn))                 // OK
+  ...
+if (rtx_jump_table_data *table = dyn_cast &lt;rtx_jump_table_data *&gt; (insn))  // Avoid
+  ...
+<b>auto *</b>map = new <b>hash_map &lt;tree, size_t&gt;</b>;                    // OK
+hash_map &lt;tree, size_t&gt; *map = new hash_map &lt;tree, size_t&gt;; // 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 &lt;name_map&gt;::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 &lt;const char *, tree&gt; &amp;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 &amp;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: [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  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 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:
  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 &lt;<b>rtx_jump_table_data *</b>&gt; (insn))                 // OK
> +  ...
> +if (rtx_jump_table_data *table = dyn_cast &lt;rtx_jump_table_data *&gt; (insn))  // Avoid
> +  ...
> +<b>auto *</b>map = new <b>hash_map &lt;tree, size_t&gt;</b>;                    // OK
> +hash_map &lt;tree, size_t&gt; *map = new hash_map &lt;tree, size_t&gt;; // 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 &lt;name_map&gt;::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 &lt;const char *, tree&gt; &amp;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 &amp;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 &lt;<b>rtx_jump_table_data
> *</b>&gt; (insn))                 // OK
> > +  ...
> > +if (rtx_jump_table_data *table = dyn_cast &lt;rtx_jump_table_data *&gt;
> (insn))  // Avoid
> > +  ...
> > +<b>auto *</b>map = new <b>hash_map &lt;tree, size_t&gt;</b>;
>         // OK
> > +hash_map &lt;tree, size_t&gt; *map = new hash_map &lt;tree, size_t&gt;;
> // 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 &lt;name_map&gt;::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 &lt;const char *, tree&gt;
> &amp;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 &amp;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 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] 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 &lt;<b>rtx_jump_table_data
>> *</b>&gt; (insn))                 // OK
>> > +  ...
>> > +if (rtx_jump_table_data *table = dyn_cast &lt;rtx_jump_table_data *&gt;
>> (insn))  // Avoid
>> > +  ...
>> > +<b>auto *</b>map = new <b>hash_map &lt;tree, size_t&gt;</b>;
>>         // OK
>> > +hash_map &lt;tree, size_t&gt; *map = new hash_map &lt;tree, size_t&gt;;
>> // 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 &lt;name_map&gt;::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 &lt;const char *, tree&gt;
>> &amp;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 &amp;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 &lt;<b>rtx_jump_table_data
>>> *</b>&gt; (insn))                 // OK
>>>> +  ...
>>>> +if (rtx_jump_table_data *table = dyn_cast &lt;rtx_jump_table_data *&gt;
>>> (insn))  // Avoid
>>>> +  ...
>>>> +<b>auto *</b>map = new <b>hash_map &lt;tree, size_t&gt;</b>;
>>>          // OK
>>>> +hash_map &lt;tree, size_t&gt; *map = new hash_map &lt;tree, size_t&gt;;
>>> // 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 &lt;name_map&gt;::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 &lt;const char *, tree&gt;
>>> &amp;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 &amp;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 &lt;<b>rtx_jump_table_data
>>>> *</b>&gt; (insn))                 // OK
>>>>> +  ...
>>>>> +if (rtx_jump_table_data *table = dyn_cast &lt;rtx_jump_table_data *&gt;
>>>> (insn))  // Avoid
>>>>> +  ...
>>>>> +<b>auto *</b>map = new <b>hash_map &lt;tree, size_t&gt;</b>;
>>>>          // OK
>>>>> +hash_map &lt;tree, size_t&gt; *map = new hash_map &lt;tree, size_t&gt;;
>>>> // 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 &lt;name_map&gt;::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 &lt;const char *, tree&gt;
>>>> &amp;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 &amp;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 &lt;<b>rtx_jump_table_data
>>>>> *</b>&gt; (insn))                 // OK
>>>>>> +  ...
>>>>>> +if (rtx_jump_table_data *table = dyn_cast &lt;rtx_jump_table_data *&gt;
>>>>> (insn))  // Avoid
>>>>>> +  ...
>>>>>> +<b>auto *</b>map = new <b>hash_map &lt;tree, size_t&gt;</b>;
>>>>>           // OK
>>>>>> +hash_map &lt;tree, size_t&gt; *map = new hash_map &lt;tree, size_t&gt;;
>>>>> // 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 &lt;name_map&gt;::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 &lt;const char *, tree&gt;
>>>>> &amp;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 &amp;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 &lt;<b>rtx_jump_table_data
>>>>> *</b>&gt; (insn))                 // OK
>>>>>> +  ...
>>>>>> +if (rtx_jump_table_data *table = dyn_cast &lt;rtx_jump_table_data *&gt;
>>>>> (insn))  // Avoid
>>>>>> +  ...
>>>>>> +<b>auto *</b>map = new <b>hash_map &lt;tree, size_t&gt;</b>;
>>>>>           // OK
>>>>>> +hash_map &lt;tree, size_t&gt; *map = new hash_map &lt;tree, size_t&gt;;
>>>>> // 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 &lt;name_map&gt;::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 &lt;const char *, tree&gt;
>>>>> &amp;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 &amp;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 &lt;<b>rtx_jump_table_data
>>>>>> *</b>&gt; (insn))                 // OK
>>>>>>> +  ...
>>>>>>> +if (rtx_jump_table_data *table = dyn_cast 
>>>>>>> &lt;rtx_jump_table_data *&gt;
>>>>>> (insn))  // Avoid
>>>>>>> +  ...
>>>>>>> +<b>auto *</b>map = new <b>hash_map &lt;tree, size_t&gt;</b>;
>>>>>>           // OK
>>>>>>> +hash_map &lt;tree, size_t&gt; *map = new hash_map &lt;tree, 
>>>>>>> size_t&gt;;
>>>>>> // 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 &lt;name_map&gt;::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 &lt;const char *, tree&gt;
>>>>>> &amp;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 &amp;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 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).