<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">