[build2] GCC 10: error: invalid initialization of reference from expression of type '<brace-enclosed initializer list>'

Matthew Krupcale mkrupcale at matthewkrupcale.com
Sun Feb 9 18:36:36 UTC 2020


On Fri, Feb 7, 2020 at 9:11 AM Boris Kolpackov <boris at codesynthesis.com> wrote:
>
> I am pretty sure this is a GCC bug. It is initializing a const reference
> from a reference_wrapper<> expression.

Yes, I believe it is a GCC bug as well. After some more investigation,
I came up with a simple way to reproduce it[1]:

#include <functional>
struct S {};
using S_refwrap = std::reference_wrapper<S>;
S s;
S_refwrap s_rw(s);
S& s_r(s_rw);

This compiles fine with GCC 9.2 and clang trunk in c++2a mode as well
as in c++17 mode on GCC and clang trunk. GCC trunk in c++2a mode,
however, gives the error:

error: invalid initialization of non-const reference of type 'S&' from
an rvalue of type '<brace-enclosed initializer list>'
    6 | S& s_r(s_rw);
      |            ^

When using a constant reference, it similarly yields:

error: invalid initialization of reference of type 'const S&' from
expression of type '<brace-enclosed initializer list>'

Searching GCC BZ I found a much older bug[2] with a similar error
message although not using std::reference_wrapper. I didn't see
anything recent involving std::reference_wrapper, though. I may then
report this on GCC BZ.

> Thanks, will look into this. At some point we will add a GCC 10 build
> machine to our CI and clean all this up. But I don't think things are
> stable enough just yet.

Yeah, just figured I'd give a heads up since Fedora is starting the process now.

> Unfortunately this doesn't work as one may expect. The dynamic
> creation of targets like obj{} happens during a rule matching for
> targets like exe{} or lib{}. But if you are not building one of
> those exe{} or lib{}, then those rules are not matched and obj{}
> are not created.

Makes sense.

> I am not yet sure what, if anything, we can do about this.

Yeah, nothing obvious comes to mind. You would have to know which
targets might create new rules (i.e. exe{} or lib{}) and act as if you
were going to build all such targets until you've found the actually
desired target (i.e. obj{}) and all its associated rules. I guess in
some sense this would still be the minimum amount of work required to
build (only) these dynamic targets, but it's definitely more work than
if you were just trying to build obj{} targets which are explicitly
defined in the buildfile.

Best,
Matthew

[1] https://godbolt.org/z/7_Phyt
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67259



More information about the users mailing list