Skip to content

Thread-safety analysis produces incorrect results for cleanup functions #122758

@bvanassche

Description

@bvanassche

Building the following code with -Wthread-safety produces compiler warnings while no warnings should be reported:

#include <stdio.h>

struct __attribute__((capability("mutex"))) mutex {
};

static void mutex_lock(struct mutex *m)
    __attribute__((exclusive_lock_function(*m)))
    __attribute__((no_thread_safety_analysis))
{
    puts(__func__);
}

static void mutex_unlock(struct mutex *m)
    __attribute__((unlock_function(*m)))
    __attribute__((no_thread_safety_analysis))
{
    puts(__func__);
}

static void mutex_cleanup(struct mutex **m)
    __attribute__((unlock_function(**m)))
{
    puts(__func__);
    mutex_unlock(*m);
}

int main(void)
{
    struct mutex m = {};
    mutex_lock(&m);
#if 1
    struct mutex *m_ptr __attribute__((cleanup(mutex_cleanup))) = &m;
#else
    mutex_unlock(&m);
#endif
    return 0;
}

The following compiler warnings are reported:

annotated-cleanup.c:32:19: warning: releasing mutex 'm_ptr' that was not held [-Wthread-safety-analysis]
   32 |     struct mutex *m_ptr __attribute__((cleanup(mutex_cleanup))) = &m;
      |                   ^
annotated-cleanup.c:37:1: warning: mutex 'm' is still held at the end of function [-Wthread-safety-analysis]
   37 | }
      | ^
annotated-cleanup.c:30:5: note: mutex acquired here
   30 |     mutex_lock(&m);
      |     ^
2 warnings generated.

The program output shows that both the lock and unlock functions are called:

mutex_lock
mutex_cleanup
mutex_unlock

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:analysisquestionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions