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

    <tr>
        <th>Summary</th>
        <td>
            clang warns that completion is called twice but that can be ruled out through static code analysis
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

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

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

<pre>
    clang says that completion may be called twice in the following code:

```
- (void)readPacket:
        (void (^)( NSData *_Nullable, NSError *_Nullable))completion
{
        NSData * packet = nil;
        NSError * error = nil;

        [self obtainLock];
        {
                if (_pendingCallback) {
                        error = [self makePendingError];
                } else {
                        packet = [self getPacket];
                        if (packet) {
                                if (_asyncCompletion) {
                                        dispatch_async(_queue, ^{
                                                completion(packet, nil);
                                        });
                                        packet = nil;
                                }
                        } else {
                                _pendingCallback = completion;
                        }
                }
        }
        [self releaseLock];

        if (packet || error) {
                completion(packet, error); // <-- Here clang says: "Completion handler is called twice"
        }
}
```

I don't see how this would be the case. Completion is only called in the end, if either `packet` or `error` is set. Completion may only be called earlier when it should finish async but in that case `packet` is explicitly set back to `nil`, so it won't be called again in the end. Or it may be called later, when it is stored to `_pendingCallback`, but that only happens if `packet` and `error` are both `nil`, so there is for sure no call in the end either. When either `packet` or `error` are set in the end, completion was for sure never called before, never stored anywhere and never passed to any external function.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVU1v4zYT_jX0ZRCDpj4cHXxI7A3eF2jTBfbQ42JEjSw2NOmSVLz-9wUpOZLtpCgQOBI5fD5mRkP0Xu0N0YYVz6zYLbAPnXWbrW2U2f-O7q33i9o2543UaPbg8ewhdBhA2sNRU1DWwAHPUBNI1JoaCCclCZSB0BG0Vmt7UmYP0jbEsifGd4xffks-_qXXB2Di8d2qhonKETbfUb5RmJ2pxv0Yx4pvTMQFeP2xw4DAxNPP115rrDUxsYXXH9-cs-5mvWKimpSPwOvnD4YJDI6JHli2A6M0y-ZBH9BAw9Nd0EVx8exJt2DrgMr8ZuUbK3ZzrDk545Vqo7mfRzIx_1vUukb5xkQFN4GMVxP1heWAb_R9OJoU3nJFuh2Q9vQJ3MzvBW9PYSzCPdBF63Dsc4WTIfRnI7dT4r8KZ7xqlD9ikN1wJh7-u6c-1TQW_YtTjM_rOsnaprqI6l7-R0L-ZffrHrgCuFn8OseMV7e1TeAz6fccNwTz1_nzWDNHmtDTfauNcfOqAVtv2Xo7NPEnNfkio5dwlj0DEy9MvADLtg8P8D9yBNOgYNkTMCGmskOHptHkQPmracGE-MTTx8P1mBh-_w9NVLUO4ImgsycInfJwsr1u4jCKw0eipyXM6JUHa_T5wj3OKDJNdKVaIBU6csBKPpotOdj0PlgueYTwFK5Q4_hLsNMMJHRakYNTRwZUAN8lXa0yyneQGhvqPgwK4jDF2C5zWuWBfh21kiroc6SE1CzBxrDYiyWPor2N8KcxFZMA3KMyM4NL-MPFyOtRrTGQizAXndFdsC7WJRHdDaKBNUpPupPtDo9HMj4m8MoCmuYqdegIahu6Owcx6RS5W-vA947A2CRxZmCszRL-jFL_Q6EiW0zbdZFnt9YJ54T0Tu6Slppa69LAGZbHlKA5n5LSaGzYOaL3Q7LQnIF-BXIGNbS9kZFjuWg2WVNlFS5os1rzcrUqyzxfdJt6XeVZJiQVbVHIiucy4zwvqzrHPCseaaE2goucr0S-Wq_WIl-2j40synZdkqyLIpMs53RApZdavx-W1u0XyvueNusqy7KFxpq0T5e6EOmLjN9YsVu4TYx_qPu9ZznXygc_IQQVNI03_Qmdub_qbz7cqRMkmthYro97Nq062-878AGDkun6BzSoz175Re_0pgvhGEfEMEH2KnR9vZT2wMRLFDT-ezg6-xfJwMRL8ueZeEkW_wkAAP__jOGjLw">