Open Quuxplusone opened 4 years ago
Bugzilla Link | PR45020 |
Status | NEW |
Importance | P normal |
Reported by | Sylvain Defresne (sdefresne@google.com) |
Reported on | 2020-02-25 02:37:23 -0800 |
Last modified on | 2020-02-26 19:19:58 -0800 |
Version | trunk |
Hardware | PC MacOS X |
CC | htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, nicolasweber@gmx.de, richard-llvm@metafoo.co.uk, rjmccall@apple.com |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
rjmccall, this is a belated follow-up to bug 27887.
Do you have an opinion on what clang's behavior should be here?
(In reply to Nico Weber from comment #1)
> rjmccall, this is a belated follow-up to bug 27887.
>
> Do you have an opinion on what clang's behavior should be here?
Well, we legitimately can't do reference-counting operations at compile time.
However, the huge caveat is that, if the value we want to retain/release is a
static literal (isExpressibleAsConstantInitializer), we don't have to because
those object are retain-agnostic.
Probably the right way to handle this is more like how we handle UB in
arithmetic: we should accept the expression in the abstract but reject its
application to objects that aren't known to be retain-agnostic. I'm not sure
if there's any situation in which we could get a non-retain-agnostic object in
the constant evaluator in the first place, so that might be quite simple; but
in case it isn't, I think that's the right rule to use.
We have an Apple-internal refactor that we should be able to upstream that
makes testing isExpressibleAsConstantInitializer somewhat more regular.
> Well, we legitimately can't do reference-counting operations at
> compile time. However, the huge caveat is that, if the value we
> want to retain/release is a static literal
> (isExpressibleAsConstantInitializer), we don't have to because
> those object are retain-agnostic.
I understand that. In fact, I would have expected all those constructors to be
flagged as in error as they are all marked as "constexpr" and may all lead to
reference counting.
What is surprising is that only one of the constructor is marked as
inconsistent with "constexpr" when I would have expected all of them to be (for
the reason you mentioned).
Maybe all C++ constructor that take a pointer to an instance of an Objective-C
class should be marked as incompatible with "constexpr" (at least when ARC is
enabled).
WDYT?
I think there needs to be an actual investigation into why it's working this way, and then we can figure out what to do about it.
Diagnosing constexpr functions that can never produce a constant expression is best-effort (in general this is a non-computable property, so the C++ standard allows implementations to diagnose as much or as little as they care to). In Clang we implement this by basically attempting a trial constant evaluation (skipping subexpressions we can't compute the values of), looking for things that are definitely reachable and definitely not evaluatable.
But our constant evaluator is (by design) only able to evaluate non-value-dependent portions of the AST -- the value-dependent pieces don't maintain the invariants necessary to support such evaluation, and are in general incomplete in various semantically-important ways -- so we don't do any checking for value-dependent expressions. That's why we're only able to diagnose the c
Okay, if this is being rejected in the abstract, we're probably incorrectly thinking that we can't perform a CK_ARCProduceObject (used when passing an argument to an ns_consumed parameter) as a constant expression, when in fact we can if the value is a constant literal.