[Bug c++/126900] [17 Regression] FAIL: 23_containers/mdspan/layouts/padded_neg.cc -std=gnu++26 (test for errors, line 247) since r17-3305

"ppalka at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126900

--- Comment #5 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Ah, so the trial constant evaluation performed by r17-3305 can cause a function
to be instantiated immediately instead of deferring that instantiation, which
can lead to different diagnostic context lines if that instantiation is
ill-formed.

template<class T>
constexpr int g() {
  static_assert(sizeof(T) == 1);
  return 0;
}

template<class T>
constexpr bool f() {
  auto x = g<T>(); // With -O, g<int> now instantiated during f<int>
instantiation instead of deferred
  return true;
}

static_assert(f<int>());

With -O we'll now diagnose the failed static_assert during instantiation of
f<int>, specifically during cp_fold_function which enters x's initializer,
which constant evaluates it during which we first instantiate g<int>.

Without -O, instantiation of f<int> doesn't do any such folding, and we instead
first instantiate g<int> during manifestly constant evaluation of f<int>().


$ g++ -O 126900.C
126900.C: In instantiation of ‘constexpr int g() [with T = int]’:
126900.C:9:16:   required from ‘constexpr bool f() [with T = int]’
    9 |   auto x = g<T>();
      |            ~~~~^~
126900.C:13:21:   required from here
   13 | static_assert(f<int>());
      |               ~~~~~~^~
126900.C:3:27: error: static assertion failed
    3 |   static_assert(sizeof(T) == 1);
      |                 ~~~~~~~~~~^~~~
  • the comparison reduces to ‘(4 == 1)’

$ g++ 126900.C
126900.C: In instantiation of ‘constexpr int g() [with T = int]’:
126900.C:9:16:   required from here
    9 |   auto x = g<T>();
      |            ~~~~^~
126900.C:13:21:   in ‘constexpr’ expansion of ‘f<int>()’
   13 | static_assert(f<int>());
      |               ~~~~~~^~
126900.C:3:27: error: static assertion failed
    3 |   static_assert(sizeof(T) == 1);
      |                 ~~~~~~~~~~^~~~
  • the comparison reduces to ‘(4 == 1)’

While it's not ideal that the context lines are different with -O vs without,
I'm not sure it's worth fixing this. We can call maybe_constant_init even
without -O (and just discard the result) so that the instantiation order is
independent of -O, but that'd slow down -O0 which we want to be as fast as
possible.  Or we can make maybe_constant_init not instantiate any
uninstantiated functions when mce_false but that'd make the optimization 
dependent on instantiation order which seems brittle, and would severely
restrict when the optimization would trigger.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.