https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70167

            Bug ID: 70167
           Summary: Some const array prvalues are incorrectly treated as
                    lvalues
           Product: gcc
           Version: 5.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: inadgob at yahoo dot com
  Target Milestone: ---

The following code is incorrectly rejected: 
(compiled with -Wall -Wextra -std=c++1z -pedantic)


#include <cstddef>

template<class T, std::size_t S> void f(T(&&)[S]) { }

using arr = const int[2];

int main()
{
    f(arr{1, 2});
}


Diagnostics:

prog.cc: In function 'int main()':
prog.cc:9:16: error: cannot bind 'arr {aka const int [2]}' lvalue to 'const int
(&&)[2]'
     f(arr{1, 2});
                ^
prog.cc:3:39: note:   initializing argument 1 of 'void f(T (&&)[S]) [with T =
const int; long unsigned int S = 2ul]'
 template<class T, std::size_t S> void f(T(&&)[S]) { }
                                       ^

Also, decltype(arr{1, 2}) yields const int(&)[2], so it looks like the const
array prvalue is incorrectly treated as an lvalue here. Xvalues of such types
work correctly; non-const array rvalues are fine as well.

This also happens if the array element type is an aggregate. Replacing the
alias declaration with

struct A { int i; };
using arr = const A[2];

causes the same error.

However, it doesn't happen for elements of non-aggregate class type. Replacing
the alias declaration with 

struct A { A(int) { } };
using arr = const A[2];

makes the code compile with no diagnostics.

Reply via email to