[PATCH] D87629: Thread safety analysis: Improve documentation for ASSERT_CAPABILITY
Russell Yanofsky via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 17 12:09:57 PDT 2020
ryanofsky marked 4 inline comments as done.
ryanofsky added a comment.
Agree with everything in D87629#2278073 <https://reviews.llvm.org/D87629#2278073>. "Assumed" is the key word, and a wrong assumption doesn't imply UB or generating incorrect code <https://github.com/bitcoin/bitcoin/pull/19929#issuecomment-693722339>. Also comment is good summary of the compile-time and run-time checking tradeoffs.
================
Comment at: clang/docs/ThreadSafetyAnalysis.rst:450
-These are attributes on a function or method that does a run-time test to see
-whether the calling thread holds the given capability. The function is assumed
-to fail (no return) if the capability is not held. See :ref:`mutexheader`,
-below, for example uses.
+These are attributes on a function or method which asserts the calling thread
+already holds the given capability, for example by performing a run-time test
----------------
aaronpuchert wrote:
> The assertion is just a promise though, so it could only happen in debug builds, for example.
> The assertion is just a promise though, so it could only happen in debug builds, for example.
This is true, but the statements seem compatible to me. I'd be happy to update it if I know what change to make.
================
Comment at: clang/docs/ThreadSafetyAnalysis.rst:452
+already holds the given capability, for example by performing a run-time test
+and terminating or throwing if the capability is not held. Presence of this
+annotation causes the analysis to assume the capability is held at the point of
----------------
vasild wrote:
> aaronpuchert wrote:
> > That's an interesting point. We currently do assume that the capability is held even when an exception is thrown, although that's primarily because Clang's source-level CFG doesn't really model exception handling that well:
> >
> > ```
> > Mutex mu;
> > bool a GUARDED_BY(mu);
> >
> > void except() {
> > try {
> > mu.AssertHeld();
> > } catch (...) {
> > a = 0; // No warning.
> > }
> > }
> > ```
> >
> > We can't warn there because `AssertHeld` might terminate in case the mutex isn't held.
> >
> > Not sure if we need to clarify this here: we just assume that the capability is held on a regular return. The other case is basically UB for us.
> Maybe don't mention "throwing", given the example above and `s/at the call/after the call/`.
> It is similar to:
>
> ```
> void f(char x, unsigned char y)
> {
> assert(x >= 0);
> assert(y <= 127);
> if (x > y) { // it is ok to omit a warning about comparing signed and unsigned because AFTER the asserts we know we are good.
> ...
> }
> }
> ```
> That's an interesting point.
Removed language about throwing now. That was just my misunderstanding.
================
Comment at: clang/docs/ThreadSafetyAnalysis.rst:452-454
+and terminating or throwing if the capability is not held. Presence of this
+annotation causes the analysis to assume the capability is held at the point of
+the call. See :ref:`mutexheader`, below, for example uses.
----------------
ryanofsky wrote:
> vasild wrote:
> > aaronpuchert wrote:
> > > That's an interesting point. We currently do assume that the capability is held even when an exception is thrown, although that's primarily because Clang's source-level CFG doesn't really model exception handling that well:
> > >
> > > ```
> > > Mutex mu;
> > > bool a GUARDED_BY(mu);
> > >
> > > void except() {
> > > try {
> > > mu.AssertHeld();
> > > } catch (...) {
> > > a = 0; // No warning.
> > > }
> > > }
> > > ```
> > >
> > > We can't warn there because `AssertHeld` might terminate in case the mutex isn't held.
> > >
> > > Not sure if we need to clarify this here: we just assume that the capability is held on a regular return. The other case is basically UB for us.
> > Maybe don't mention "throwing", given the example above and `s/at the call/after the call/`.
> > It is similar to:
> >
> > ```
> > void f(char x, unsigned char y)
> > {
> > assert(x >= 0);
> > assert(y <= 127);
> > if (x > y) { // it is ok to omit a warning about comparing signed and unsigned because AFTER the asserts we know we are good.
> > ...
> > }
> > }
> > ```
> > That's an interesting point.
>
> Removed language about throwing now. That was just my misunderstanding.
> Maybe don't mention "throwing", given the example above and `s/at the call/after the call/`.
Thanks, update has both changes
================
Comment at: clang/docs/ThreadSafetyAnalysis.rst:453
+and terminating or throwing if the capability is not held. Presence of this
+annotation causes the analysis to assume the capability is held at the point of
+the call. See :ref:`mutexheader`, below, for example uses.
----------------
aaronpuchert wrote:
> It's implemented a bit differently:
>
> ```
> Mutex mu;
> bool a GUARDED_BY(mu);
>
> void f() {
> a = 0; // warning.
> mu.AssertHeld();
> a = 0; // Ok.
> }
> ```
>
> If we were to assume that `mu` is held at the call site, it would also be held right before it.
>
> I'm not sure if this is the right behavior, but assuming that it is, calling an `ASSERT_CAPABILITY` function introduces an assumption which can be used from that point on, and which disappears on join points with branches that don't have the assumption.
> It's implemented a bit differently:
Tweaked to say that assumption applies after the call.
================
Comment at: clang/docs/ThreadSafetyAnalysis.rst:456-457
+
+The given capability must be held on entry to the function, or the function is
+assumed to fail (no return).
----------------
aaronpuchert wrote:
> "The function is assumed to return only if the given capability is held."?
> "The function is assumed to return only if the given capability is held."?
Updated to drop this extra paragraph. I don't think any information is lost and it seems better to avoid implying that annotating a function which does return (NDEBUG assert) will causes the analysis to assume something not true.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D87629/new/
https://reviews.llvm.org/D87629
More information about the cfe-commits
mailing list