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

            Bug ID: 57388
           Summary: [C++11] ICE when function types with ref-qualifiers
                    meet other function types
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: daniel.kruegler at googlemail dot com

While attempting to upgrade std::function for functions with ref-qualifiers I
found that the following code gives an ICE for gcc 4.9.0 20130519
(experimental). The compiler flags are:

-std=c++11 -Wall -pedantic

//------------------------------------------------------
template<class> struct A
{
  static constexpr bool value = false;
};

template<class Res, class... Args>
struct A<Res(Args...)>
{
  static constexpr bool value = true;
};

template<class Res, class... Args>
struct A<Res(Args...) const &>
{
  static constexpr bool value = true;
};

template<class Res, class... Args>
struct A<Res(Args...) const &&>
{
  static constexpr bool value = true;
};

static_assert(A<void()>::value, "Ouch");
static_assert(A<void() const &>::value, ""); // #1
static_assert(A<void() const &&>::value, ""); // #2
//------------------------------------------------------

The error being (at line #1 or if this is commented on line #2):

"main.cpp|25|internal compiler error: canonical types differ for identical
types void() const && and void() const &&"

The conditions seem to depend on type ordering. The ICE doesn't occur, when the
last three lines are inverted to

static_assert(A<void() const &>::value, "");
static_assert(A<void() const &&>::value, "");
static_assert(A<void()>::value, "Ouch");

or if typedefs are introduces for functions with ref-qualifiers up-front such
as in the following replacement of the last three lines:

typedef void FClref() const &;
static_assert(A<void()>::value, "Ouch");
static_assert(A<void() const &>::value, "");
static_assert(A<void() const &&>::value, "");

Interestingly the following variant

typedef void FClref() const &&;
static_assert(A<void()>::value, "Ouch");
static_assert(A<void() const &>::value, ""); // #1
static_assert(A<void() const &&>::value, "");

still ICEs for #1 (but the previous one didn't ICE on the last line)

Reply via email to