On Tue, Jul 15, 2025 at 08:30:33AM -0400, Jason Merrill wrote: > > The diagnostic only changed for C++26, and I'm not sure why (the _S_at > > function isn't constexpr, so why wasn't it failing there before?) > > In C++23, we could see that the outermost thing in the expression is a call > to _M_error, and it's non-constexpr, so we give up at that point and never > look at the call to _S_at.
Yeah. Though, even in GNU++23 we could have foo (({ if (x == 42) return 14; 23; }), 12); with non-constexpr foo, so maybe we could do that regardless of the C++ level. We've never handled that before during constant evaluation though and now handle it at least in some (for C++26 hopefully most or all) cases, say ({ if (x == 42) return 14; 23 }) + x etc. > In C++26, evaluating the arguments to a function (including the object > argument) might throw before we get to calling the non-constexpr function, > so we need to evaluate them before giving up. There can be other reasons for different diagnostics between C++23 and C++26 related to the constexpr exceptions patch, e.g. potential_constant_expression for C++26 can let some expressions through as potentially constant because it has to assume some call could throw, while in C++23 and earlier that would be impossible, and so something can be diagnosed only later for C++26. Jakub