Date
2020-11-10.00:00:00
Message id
11607

Content

The wording in [ptr.launder] paragraph 4:

An invocation of this function may be used in a core constant expression whenever the value of its argument may be used in a core constant expression.

can be taken to mean that the invocation may be used only when the value of its argument can be used in place of the invocation itself.

That interpretation is not particularly obvious, but based on comments on the CWG reflector (see here), that is the interpretation that matches the design intent.

Consider:

#include <new>

struct A { int x; int y; };
struct B { float x; int y; };

union U {
  A a;
  B b;
};

constexpr A foo() {
  U u;
  int* byp = &u.b.y;
  static_assert(&u.b.y == static_cast<void*>(&u.a.y));
  u.a.y = 42;
  *std::launder(byp) = 13;
  return u.a;
}

extern constexpr A globA = foo();

If the static_assert succeeds, then a possible interpretation is that the source file above compiles because the call to std::launder produces a pointer to u.a.y. That interpretation is apparently not desirable.