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

            Bug ID: 70380
           Summary: SFINAE error with constexpr expressions referencing a
                    non-const variable
           Product: gcc
           Version: 6.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 following program attempts to use SFINAE to choose between two overloads of
a function template.  Whether one or the other overload is viable depends on
whether or not an expression used in its declaration is a core constant
expression.  I believe the program is valid as is (with the invalid lines
commented out) and should be accepted.  However, GCC 6 and all versions before
it rejects it.  (Clang rejects it as well, due to what I think is also a bug.)

$ cat t.cpp && /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -xc++ t.cpp
int x;

struct A {
  constexpr A (bool b) : m (b ? 42 : x) { }
  constexpr int foo () const { return m; }
  int m;
};

struct B {
  constexpr B (bool b) : m (b ? x : 42) { }
  constexpr int bar () const { return m; }
  int m;
};

// constexpr int a0 = A (false).foo ();       // not constant, rejected
constexpr int a1 = A (true).foo ();        // valid, accepted
constexpr int b0 = B (false).bar ();       // valid, accepted
// constexpr int b1 = B (true).bar ();        // not constant, rejected

template <bool X>
int f (int (*)[A (X).foo ()] = 0) { return !X; }

template <bool X>
int f (int (*)[B (X).bar ()] = 0) { return X; }

constexpr int f0 = f<0>();            // valid, rejected
constexpr int f1 = f<1>();            // valid, rejected
t.cpp:26:24: error: call to non-constexpr function ‘int f(int
(*)[(B)(X).B::bar()]) [with bool X = false]’
 constexpr int f0 = f<0>();            // valid, rejected
                    ~~~~^~
t.cpp:27:24: error: call to non-constexpr function ‘int f(int
(*)[(A)(X).A::foo()]) [with bool X = true]’
 constexpr int f1 = f<1>();            // valid, rejected
                    ~~~~^~

Reply via email to