[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.