<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/65127>65127</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            SCOPED_CAPABILITIES think that capabilities REQUIRED during construction are released by methods marked RELEASE
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          johngro
      </td>
    </tr>
</table>

<pre>
    # Repro Steps

Reproduced so far using the following versions of Clang.

1) The version of clang currently distributed with the [Fuchsia](https://fuchsia.dev/fuchsia-src/development/build/toolchain?hl=en) project at Google.
2) x86-64 clang (trunk) on [godbolt.org](https://godbolt.org/)
3) x86-64 clang 16.0.0 on [godbolt.org](https://godbolt.org/)
4) x86-64 clang 15.0.0 on [godbolt.org](https://godbolt.org/)
5) armv8-a clang (trunk) on [godbolt.org](https://godbolt.org/)
6) armv8-a clang 16.0.0 on [godbolt.org](https://godbolt.org/)
7) armv8-a clang 15.0.0 on [godbolt.org](https://godbolt.org/)

arguments are `--std=c++17 -Wall -Wthread-safety-analysis -Werror`

To reproduce, compile the following file [scoped_capability_releases_required_capability.cc.txt](https://github.com/llvm/llvm-project/files/12480766/scoped_capability_releases_required_capability.cc.txt), but be sure to change the extension back to just `.cc` and build using clang and the arguments above.

This example file contains a description of the setup which show various uses of the Clang Thread Safety Analysis feature.  Some of the examples here succeed/fail as they should.  The example starting on line 231, however, fails when it should not.  Please make sure that the `#if 0` gating this failure case has been changed to an `#if 1` in order to successfully reproduce the issue.

For the most simple repro case, please use [scoped_capability_releases_required_capability_extra_simple.cc.txt](https://github.com/llvm/llvm-project/files/12480886/scoped_capability_releases_required_capability_extra_simple.cc.txt)
instead.  This version contains _only_ the most simple repro and none of the extra comments or examples.

# Background

[Clang Thread Safety Analysis](https://clang.llvm.org/docs/ThreadSafetyAnalysis.html) allows users to annotate their code statically in order to enforce invariant related to concurrency and thread safety.  These are modeled as "capabilities" which must be explicitly held (or explicitly not held) in various scenarios defined by the static annotations.  For example, a structure might have a `lock_` member which is an instance of a class which has been properly annotated to be a capability, and a member variable which is annotated as `GUARDED_BY(lock_)`.  Attempts to access the variable when the analyzer cannot statically demonstrate that the lock must have been acquired will result in a warning.

In addition to annotating variables as `GUARDED_BY`, methods may be annotated to indicate that they `REQUIRE` or `EXCLUDE` sets of capabilities as well, allowing capabilities to be acquired and held several stack levels above where a `GUARDED_BY` variable may be accessed.

In addition to this, the analyzer allows users to introduce `SCOPED_CAPABILITIES`, which are RAII style "guards" who typically acquire one or more capabilities during construction, and then release whatever capabilities were acquired either on destruction, or early if a properly annotated method of the guard is used to release the capabilities instead.  See [here](https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#scoped-capability) for the documentation for `SCOPED_CAPABILITY` 

Documentation for `SCOPED_CAPABILITY` says
```
Scoped capabilities are treated as capabilities that are implicitly acquired on construction and released on destruction. They are associated with the set of (regular) capabilities named in thread safety attributes on the constructor or function returning them by value (using C++17 guaranteed copy elision). Acquire-type attributes on other member functions are treated as applying to that set of associated capabilities, while RELEASE implies that a function releases all associated capabilities in whatever mode they’re held.
```

An example is also provided later on in the docuementation, but (assuming that Lock is properly annotated) a user might say something like
```
struct SCOPED_CAPABILITY MyGuard {
  MyGuard(Lock& lock) ACQUIRE(lock) lock_(lock) { lock_.Acquire(); }
  ~MyGuard() RELEASE() { lock_.Release(); }
  Lock& lock_;
};

// An then later on in code

uint32_t AccessGuardedVariable() {
  MyGuard guard{lock_we_need};
  return guarded_variable;
}
```

# The Issue

The issue here is that capabilities which are _REQUIRED_ (but not _ACQUIRED_) during construction are considered to be among the set of capabilities which are also released during destruction (or any method annotated with a parameter-less `RELEASE()` annotation).

The example attached in the Repro Steps section shows a very simple example of this, along with a practical use case of where this matters.  Basically, it shows a situation where we have a spinlock modeled as a capability which requires interrupts to be disabled in order to be used correctly (think of a kernel programming environment in this situation, but there are others where it might apply).  Interrupts being disabled are also modeled as a capability, but attempting to create a guard which acquires and releases spinlocks, but demands that interrupts be disabled during construciton/destruction, fails because the guard thinks that it is re-enabling interrupts when it destructs.

# Expected Behavior.

Only capabilities which are ACQUIRED during construction (or other methods of the scoped capability class, according to documentation) should be assumed to have been RELEASED during destruction (or any other method of the scoped capability class annotated with `RELEASE()`).  Capabilities which are REQUIRED during construction of a scoped capability should still be required, but not assumed to be released later on.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysWU1zIjnS_jXlSwYELgyGgw9gzIQj-o2Z1-7Z2T0RKimhNFZJrKSCrj3sb99IfUBh496dmY7ooKEkpfLjySczy8w5udOID8VkWUxWN6z1tbEPv5ta76y5qYzoHopyDC-4twZePe5dMVoVo0X8DI9Fy1GAM7BlFlon9Q58jbA1Spkj_TqgddJoB2YLj4rp3bAv47Yo5_C1xryNdnHaBby1FrVXHQjpvJVV61HAUfo6XFBMluuW106yYrIqylnt_d4V40VRrotyvY1LQ4GH86-Bs7wo1wIPqMy-Qe2Lcl21UomiXHtjFK-Z1MV4XativEJNqu2t-R25B-bhJ2N2CpP2JS1-m00H07ukb1HOvG31Gy0YTfrtjKiM8kNjd9d07C_Tg3mUPP4g-XY6HA1Hf0no3Uehk78sdEJCmW0OswH7wU6YfhT9A7xwf0XqX3dD_GR21xKkHDCLUExHg4HzohiveFEui3J5ew-D35hSMPjN1xaZGDi2Rd8NmGaqc9LB4De01thiOurL_WrA5jwrykfgptlLhe-SbEuPisnScbNHseFszyqppO82FhUyh25j8Z-ttBeLQ86H_pu_aqv0dVsNuWmKcq3UIf83SAlBWSUVuqJc35Z3s9H9dFqU6z93fTknw6rWQ4XgWovgDfCa6V00E7951IEcKsbfaPH31nny8ZDzYjoCpgWEPE4EFENLT-l4LzKVOeAF_XytpQP8xpq9wuhEbrRnUjtgINBxK_c-0RLJcujbPRxryWtwtTnCgVlpWgetQ5c3BZaDryHK8BqiDIsc5S0y31ocAryaBvORpIKDGi35gHNEYqUtkwqYoz0dXdgqMYTAl1lp55n1ZLTRoKRGKMe35M7aHPGAlr6SEAfHGjVIn6SANn4I8EuIDjTsLXu-Zj7y63RUlGO5hRF5eMd8ZHaygElFWzmdrJmDClGneAmKDtPn07d0WmowVqClxWCbc9tWqe6M7HCldK69DM_a2LDSGOfByWBwOBMuJ9v20YDW_Qn4b_Cbt2wT5f7AXJjN_nguXNUlM4zUziOLkZfuVCpPUN0YrbrNJ56iNNBG96DmLSMaiTlh7Al8F66nur9k_G1nTavFxcpk-T2EX_NgSMgh-SyRpzCc3BUlRAH5_LD2jQpETeQWMsu6CCttPPMBK9ICNyKg30vOCEt9kKHeGssRpKb8ZNqDRcV8hCc3OvYWvEscEcyIdByzy2Fg8cYIVCgoAYuyPAVLUqjLxAINUVFFbt0rySX1KzUqQZUwuPb0VBsfVsg0qU_E4Thq-upA4FZqFFB1kWqCadlq6qCGAOtzuAj9DJy3LSdCgUbuag81OyAwyj9l-NuGsq_BpkKb1JWO0pMAxTQPmAiV0Lm0fsrnvTV7tKo7uT34riLhZ9QGHbQAli8J7q4U9m_Lx8mL09FPvy5eVk-rzfIfRTmLOpZzonKAhffY7H0MdmCJ4IieTNSR0Qkq_0ILPEjvo0BgY7TzNuIkcRldEwMV3BPsYzzmIBylUmDRtcpTXBgcmdXyXZv6rIEJIUMpOEMxtLdJO_fRPuLAR2jQ10Y4aFgX3Nd3p9RC8r6qHYl4efr_X59fnih2xtKDp78_fvl1FR449KHO9MFINx9RqRCN3BFcbEiRyyZTyAJIHZUIpsiB_A0UNcapSpKzbULShUnncGSDQqRQfM9fVDdIu4vgvc9vqX0qBsV09Pr48y9Pq83j4pfF8vnL89fnp9fkz4gsSs-XxfMzON9R61OWu5ZZkRLTgO_2CRHJaggUaKExoXT1nCNaGxwWcNNy0jnj2hPiEm3DsWae_HV5-hjclD2L0tdoqRYLvJBGecsonSRl3JXkijDJJB2MofRpXURKVoIWL-4_14ZXDDWQ4vaDOHgca9ign_Bz2KaiLAwPfVUgp_D0StwCZPrIWP3Ppxzr8rg5HaV_4edr0OpdClDvYjETzSX6KbloA5XFxManiMU6eopVCHtytngXxyGVhi5IYs4ZLtnFROrQU_iKcmZx1ypmyVkXimjWoCCSuSg5wHwabx1dGCKcNTKWkLNtdVTOom8DOdGuhirFgamW4D-Lne_jadggBDHtkRxl9h2gki5gcT6ERTR-4Ls9vrvdBPwmNs_3fnAv2-9VF9Qw0bvJ9p5bLqtlSFuF8PL05Wnx-hQjcQpN38DYIhE5fCaNHHjKRSrRgTiLp7KYjYr53GLgtuFV6MTPhT61z1ShlDOUkQcpUAC1CSGBpT6hHE-AzYNKUc6Yc20TQ8E8fKESI92VzA6tTGC5VKId68AZync6reQbXlU1AgA-pAb8X_dTYIfifhl3Qn5UlDPSoyinoeTRzYvHWEtiraUnqeaefhf3y_hsmGBRlDMqyeMlFPerfMO_z1fQoRTH9Oss4iXG76qIvmqbYpyUpw2n76nzJLqChY702w8I9Xz9ra3UflxuPCxCEQoaovhbqlBn7d75KdJrcb8Mqhxxo2na6ikCKdPiRhSbXPQu1P4cYNQ805D2TBPN5byZxpw46MmUAZcV5VTgNqkTWG0IcIQ76nY2KaYr6pyuVa9wlh5IgfbctzUmvZtLyfrJpSEdTgyYxPdYMHW2THe5Zp2LWOBCBntmWYMe7UBRExdamh5e4sie21pipPcuytnJvGe8zpyJ_ReR4DCqQ2M4TesHtF2efPL5UE1j68EUmZ8VtIyHjjEMjmGQNdvU8oQZt2Heo6WOe8lcbCRISByfw3VO-jbWsHjsiLn3dnupY8d5Hh_6TXPydRoCic48WtumxrdCENIR1sTFSFNh7AW4sRY5lbCinBGFvMUm_g2tRkX8s7OsCcSE-iCt0URe0YHSndXOTOZjn0cNEn11yRzpE1sFqg9VA57PilYYUJEVPeHmE5PzZSx2-Kly8FBQgKVuJ0GQJ7f0CrE7-dRlSQIbpkVKH9lX7KzVu9SQnqxev2vM4suRCjlrU3sVtQmuzfI9ZarFAWpWKZLZuzG_V8lyP47RT9_2yCk9llizgzT2YsfPWnWf5WLO9KtZHvMwF-w4ZOTXVO86pC7OeCEPODdWpAhctHDEJunlUBU6nLaJ5HEemlIar75PC32V_otG77njClVE7D1ed1AmyKsOCnnx8eJko_M0-FWYE1FkaBHH9qwPOxIb5lo0vBEPYzEfz9kNPtxO5-O78fx2dn9TP-BtNZ_PxS3n5WjM-Bjvq3IsJnwrKs7GQtzIh3JUjkez8agc303L--F0PJ_cj2dsWk2mUzabFHcjbJhUp1b9JhSMh-nktry_UaxC5cIfbMpS4zFWk6Isi8nqxj6E11JVu3PF3UhJ591Zipde4cOVuSpC_Uoh-q5zyfsnv1Rdb8y1bygyUm5aqx7-8Nu0YBPNJsHm_wQAAP__SAUP0Q">