https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91158

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Cassio Neri from comment #3)
> Forget my use case and comments on dead code elimination. That was a
> digression. (My bad.) In general, I don't expect `if` and `if constexpr` to
> behave the same but I do in this particular case. (I might be wrong.)
> Finally, since `__builtin_constant_p` is not standard this ticket is a
> feature request, not a bug report.
> 
> My reasoning is this: when the compiler sees `static_assert(f1(1));` it
> enters a "constexpr evaluation mode" (not sure this is the right terminology
> but you get the point). At this moment, regardless of optimization level the
> compiler must propagate `1` to `f1` otherwise (generally speaking) it cannot
> evaluate `f1(1)` and decide whether the `static_assert` passes or not.
> Therefore, when it enters `f1` and sees `if constexpr
> (__builtin_constant_p(n))` it is already in "constexpr evaluation mode" (so
> `constexpr` here is redundant) and it knows `n == 1`. Hence, it should
> evaluate `__builtin_constant_p(n)` to `1`.

The problem is that with if constexpr, that if constexpr (__builtin_constant_p
(n)) is seen already before the constexpr evaluation of the f1 function with a
particular argument, during the parsing of that routine.  And if constexpr says
that a constant expression is needed right away at that spot, because whether
the condition is true or false affects the instantiation of templates in the
then or else body etc.  And at that point n is a parameter, not a constant.
__builtin_constant_p is either folded into 1 if the expression is constant, or
deferred till later (if possible), or, if a constant value is required, folded
to 0.  And for if constexpr we can't defer till later and n isn't a constant,
so it gets folded to 0.

Reply via email to