title | description | author | ms.author | ms.service | ms.topic | ms.date |
---|---|---|---|---|---|---|
Warning C26132 |
Documentation on static analysis warning C26132 |
Rastaban |
philc |
visual-cpp |
article |
02/11/2025 |
Variable 'variable name' should be protected by 'lock 1', but 'lock 2' is held instead. Possible annotation mismatch.
The analyzer issues Warning C26132 when it detects that a lock, which is annotated to protect a value, isn't held while accessing the value. However, a related lock is held. The code may be thread-safe, so you might need to update the annotations.
This diagnostic usually doesn't indicate a bug in the code, but rather a mismatch between the annotations and the actual locking behavior. If so, the diagnostic should be resolved as there may be other static analysis issues that aren't being reported due to the inconsistent annotations.
In the following example, C26132 is emitted when data
is used.
The annotation specifies that customLock01
should protect the variable data
, but CustomLockAcquire
is responsible for acquiring the related lock customLock01->cs
.
#include <sal.h>
struct CustomLock
{
int cs; // "Critical Section" lock
};
_Acquires_exclusive_lock_(criticalSection->cs) // notice the `->` indirection
void CustomLockAcquire(CustomLock* criticalSection);
_Releases_lock_(criticalSection->cs) // notice the `->` indirection
void CustomLockRelease(CustomLock* criticalSection);
// global lock
CustomLock customLock01;
void Initialize(_Guarded_by_(customLock01) int* data)
{
CustomLockAcquire(&customLock01);
*data = 1; // C26132
CustomLockRelease(&customLock01);
}
In this example, the Initialize
function is thread-safe and behaves as designed, but that design isn't correctly reflected in the concurrency SAL annotations. Fix by adjusting the annotations on the custom locking functions to use criticalSection
rather than criticalSection->cs
. The warning could also be fixed by changing the _Guarded_by_
annotation from customLock01
to customLock01.cs
.
#include <sal.h>
struct CustomLock
{
int cs; // "Critical Section" lock
};
_Acquires_exclusive_lock_(criticalSection)
void CustomLockAcquire(CustomLock* criticalSection);
_Releases_lock_(criticalSection)
void CustomLockRelease(CustomLock* criticalSection);
// global lock
CustomLock customLock01;
void Initialize(_Guarded_by_(customLock01) int* data)
{
CustomLockAcquire(&customLock01);
*data = 1;
CustomLockRelease(&customLock01);
}