On Thu, 9 Jun 2016, Jakub Jelinek wrote: > On Thu, Jun 09, 2016 at 08:50:15AM +0200, Richard Biener wrote: > > On Wed, 8 Jun 2016, Jason Merrill wrote: > > > > > On Wed, Jun 8, 2016 at 11:16 AM, Marc Glisse <marc.gli...@inria.fr> wrote: > > > > On Wed, 8 Jun 2016, Richard Biener wrote: > > > > > > > >> The following works around PR70992 but the issue came up repeatedly > > > >> that we are not very consistent in preserving the undefined behavior > > > >> of division or modulo by zero. Ok - the only inconsistency is > > > >> that we fold 0 % x to 0 but not 0 % 0 (with literal zero). > > > >> > > > >> After folding is now no longer done early in the C family FEs the > > > >> number of diagnostic regressions with the patch below is two. > > > >> > > > >> FAIL: g++.dg/cpp1y/constexpr-sfinae.C -std=c++14 (test for excess > > > >> errors) > > > > > > Yep. We don't want to fold away undefined behavior in a constexpr > > > function, since constexpr evaluation wants to detect undefined > > > behavior and treat the expression as non-constant in that case. > > > > Hmm. So 0 / x is not constant because x might be zero but 0 * x is > > constant because it can never invoke undefined behavior? Does this mean > > that 0 << n is not const because n might be too large (I suppose > > 0 << 12000 is not const already)? Is 0 * (-x) const? x might be INT_MIN. > > E.g. for the shifts the C++ FE has cxx_eval_check_shift_p which should > optionally warn and/or set *non_constant_p. 0 * (-INT_MIN) would be > non-constant too, etc. > constexpr int foo (int x) { return -x; } > constexpr int bar (int x) { return 0 * (-x); } > constexpr int a = foo (-__INT_MAX__ - 1); > constexpr int b = bar (-__INT_MAX__ - 1); > shows that we don't diagnose the latter though, most likely because > constexpr evaluation is done on the folded tree. > So, either whatever cp_fold does (which uses fold* underneath) should avoid > folding such cases, or the constexpr evaluation should be done on a copy > made before folding. Then cp_fold doesn't have to prohibit optimizations > and it is a matter of constexpr.c routines to detect all the undefined > behavior. After all, I think doing constexpr evaluation on unfolded trees > will have also the advantage of better diagnostic locations.
Yes, I think constexpr diagnostic / detection should be done on unfolded trees (not sure why we'd need to a copy here, just do folding later?). If cp_fold already avoids folding 0 * (-x) then it should simply avoid folding 0 / x or 0 % x as well (for the particular issue this thread started on). Richard.