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

            Bug ID: 79104
           Summary: [7.0 regression] ambiguity calling std::end on a local
                    constexpr array of structs
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The program below reduced from the test case for bug 56973 compiles
successfully with GCC 6 (in addition to Clang and Oracle Solaris Studio) but
fails with the current trunk of GCC 7.0 (and also EDG 4.11).  Making the array
static or moving the declaration to namespace scope resolves the error. 
Changing the array from one of structs to one of characters also works.

$ cat u.C && g++ u.C
template <typename C>
inline auto
begin (C& c) -> decltype (c.begin ());

template <class T, unsigned long N>
inline constexpr T*
begin (T (&a)[N]) { return a; }

void f ()
{
  constexpr struct { const char *s; } a[] = { { "a" } };

  auto i = begin (a);

  auto test=[&]() {
    i = begin (a);
  };
}
u.C: In lambda function:
u.C:16:17: error: no matching function for call to ‘begin(const f()::<unnamed
struct> [1])’
     i = begin (a);
                 ^
u.C:3:1: note: candidate: template<class C> decltype (c.begin()) begin(C&)
 begin (C& c) -> decltype (c.begin ());
 ^~~~~
u.C:3:1: note:   template argument deduction/substitution failed:
u.C: In substitution of ‘template<class C> decltype (c.begin()) begin(C&) [with
C = const f()::<unnamed struct> [1]]’:
u.C:16:17:   required from here
u.C:3:29: error: request for member ‘begin’ in ‘c’, which is of non-class type
const f()::<unnamed struct> [1]’
 begin (C& c) -> decltype (c.begin ());
                           ~~^~~~~
u.C:7:1: note: candidate: constexpr T* begin(T (&)[N]) [with T = const
f()::<unnamed struct>; long unsigned int N = 1]
 begin (T (&a)[N]) { return a; }
 ^~~~~
u.C:7:1: note:   no known conversion for argument 1 from ‘const f()::<unnamed
struct> [1]’ to ‘const f()::<unnamed struct> (&)[1]’

Reply via email to