https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99859
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org, | |mpolacek at gcc dot gnu.org, | |ppalka at gcc dot gnu.org --- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, on the #c3 testcase, if I put a breakpoint before and after fold_nondependent_expr in finish_static_assert and temporarily in between those two breakpoints put a breakpoint on cxx_eval_call_expression and cxx_eval_increment_expression, it is clear that while cxx_eval_call_expression is called on ... intrusive_ptr<Foo>::~intrusive_ptr (&D.2255); Foo::dec (NON_LVALUE_EXPR <((struct intrusive_ptr *) this)->ptr>); intrusive_ptr<Foo>::~intrusive_ptr (&a); Foo::dec (NON_LVALUE_EXPR <((struct intrusive_ptr *) this)->ptr>); where during the first Foo::dec call evaluation cxx_eval_increment_expression is called on --((struct Foo *) this)->count_ during the second Foo::dec call we use cached result (1) and don't evaluate the body at all. But the body of the constexpr method has side-effects on the class it is called on (and the result is incorrect too), on the testcase when not evaluating at compile time but runtime the first Foo::dec shall predecrement count_ from 2 to 1 (thus return 1) and the second one should predecrement count_ from 1 to 0 (thus return 0). For the constexpr new I had to add the /* If the call allocated some heap object that hasn't been deallocated during the call, or if it deallocated some heap object it has not allocated, the call isn't really stateless for the constexpr evaluation and should not be cached. It is fine if the call allocates something and deallocates it too. */ setting of cacheable to false in some cases, but this PR let's me wonder if it is ever ok to cache constexpr results and what the standard actually says (if constexpr/consteval functions can have side-effects besides computing a return value (I believe they can't just change some unrelated constexpr variable, right?) and ditto for constexpr/consteval methods. So, e.g. shall we remember during the constexpr evaluation if the currently evaluated constexpr function has side-effects to something other than its automatic variables or return value and if so, make it effectively non-cacheable?