[PATCH] Teach builtin clz, ctz, and popcount to be const

Richard Smith richard at metafoo.co.uk
Wed Jun 12 23:42:07 PDT 2013

On Wed, Jun 12, 2013 at 11:32 PM,  <mail at justinbogner.com> wrote:
> Richard Smith <richard at metafoo.co.uk> writes:
>>> Don't return false from VisitCallExpr without emitting a diagnostic (see the
>>> comment at the top of the file) -- replace the
>>>   if (!Val)
>>>     return false;
>>> with
>>>   if (!Val)
>>>     return Error(E);
>>> Otherwise LGTM, thanks!
>> Committed with that tweak as r183886.
> Thanks. I don't fully understand the difference between returning false
> and calling Error here, based on the previous expression and the
> comments at the top of the file. Is it simply that the attempt to const
> fold an int here will have already emitted an appropriate diagnostic, so
> we only need to do more when we have local logic?

Per the text after the bullets in the big comment, false with no
diagnostic means that constant-folding failed, but that the expression
is not necessarily always non-constant (and in particular, could
evaluate successfully in a different context). One difference is
whether we can reject

  constexpr int f() { return __builtin_clz(0); }

at definition time (because it can never produce a constant) or
whether we have to wait until it's called. Another is whether we have
a source location more accurate than "somewhere in the expression" for
the "evaluation failed" diagnostic.

> On a related note, what diagnostic does Error without parameters emit
> here?

If no diagnostic is specified, it defaults to
"diag::note_invalid_subexpr_in_const_expr", which is the generic "is
not a constant expression" note.

> Sorry if these questions are obvious.

Far from it, this is rather subtle. I've been meaning to rearrange the
code to prevent this happening by accident, but haven't found time

More information about the cfe-commits mailing list