https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70248
--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- Below is a test case (derived from a test discussed in the context of another bug: https://gcc.gnu.org/ml/gcc-patches/2016-03/msg01644.html) for another example of a constexpr function whose use in a constexpr context is invalid due to its return value relying on unspecified effects, this time the result of the relational expression involving null pointers. The test case shows two problems: first, that the invalid initialization of the constexpr variables a0 and b1 is accepted, and second, an error on the use of SFINAE to select one of the two overloads of the function template f (see also bug 70380 for a similar SFINAE example that's not handled correctly, though for a different reason). The main point of the example is to demonstrate the first problem, but fixing it should take into consideration the SFINAE case. $ cat v.c && /build/gcc-trunk-bootstrap/gcc/xgcc -B /build/gcc-trunk-bootstrap/gcc -S -Wall -Wextra -Wpedantic -xc++ v.c constexpr int *p = 0; constexpr int *q = 0; struct A { constexpr A (bool b) : m (b ? 1 : p < q) { } constexpr int foo () const { return m; } int m; }; struct B { constexpr B (bool b) : m (b ? p < q : 1) { } constexpr int bar () const { return m; } int m; }; constexpr int a0 = A (false).foo (); // invalid, accepted constexpr int a1 = A (true).foo (); // valid, accepted constexpr int b0 = B (false).bar (); // valid, accepted constexpr int b1 = B (true).bar (); // invalid, accepted 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 v.c:27: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 ~~~~^~ v.c:28: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 ~~~~^~