[Bug c++/70248] constexpr initialization with unspecified equality expression accepted

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Mar 31 19:50:00 GMT 2016


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


More information about the Gcc-bugs mailing list