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 ~~~~^~