Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-1650

clang TSA does not analyze __attribute__((cleanup)) functions

    • clang-17.0.6-4.el9
    • None
    • None
    • sst_pt_llvm_rust_go
    • ssg_platform_tools
    • 16
    • 19
    • 3
    • False
    • Hide

      None

      Show
      None
    • No
    • None
    • Release Note Not Required
    • None

      Description of problem:
      clang's Thread Safety Analysis does not take into account _attribute((cleanup)). Therefore it misses lock guards and similar patterns where a resource is released in an __attribute_((cleanup)) function.

      This appears to affect both C and C++ programs. The use of _attribute_((cleanup)) is somewhat common in QEMU because it is a C program without C++ RAII abilities.

      Version-Release number of selected component (if applicable):
      clang-15.0.7-2.el9.x86_64

      How reproducible:
      100%

      Steps to Reproduce:
      1. $ cat >a.c
      #include <assert.h>
      #include <pthread.h>

      typedef pthread_mutex_t _attribute_((capability("mutex"))) mutex;

      static mutex lock = PTHREAD_MUTEX_INITIALIZER;
      static int counter _attribute_((guarded_by(lock)));

      void mutex_lock(mutex *m) _attribute((acquire_capability(lock))) __attribute_((no_thread_safety_analysis))
      {
      pthread_mutex_lock(m);
      }

      void mutex_unlock(mutex *m) _attribute((release_capability(lock))) __attribute_((no_thread_safety_analysis))
      {
      pthread_mutex_unlock(m);
      }

      struct guard
      {
      /* Nothing */
      };

      static void guard_cleanup(struct guard *unused) _attribute_((release_capability(lock)))
      {
      mutex_unlock(&lock);
      }

      int main(int argc, char **argv)
      {

      { mutex_lock(&lock); struct guard __attribute__((cleanup(guard_cleanup))) guard; counter++; }

      counter--; /* this should fail */
      return 0;
      }
      ^D
      2. clang -Wthread-safety -o a a.c

      Actual results:
      a.c:40:1: warning: mutex 'lock' is still held at the end of function [-Wthread-safety-analysis]
      }
      ^
      a.c:32:9: note: mutex acquired here
      mutex_lock(&lock);
      ^
      1 warning generated.

      This is wrong. The lock is released in guard_cleanup() before the scope inside main() ends.

      Expected results:
      A warning should identify that counter-- accesses the field without holding the lock.

      Additional info:

            tbaeder@redhat.com Timm Baeder
            stefanha@redhat.com stefanha@redhat.com (Inactive)
            Thomas Stellard Thomas Stellard
            Jesus Checa Hidalgo Jesus Checa Hidalgo
            Votes:
            0 Vote for this issue
            Watchers:
            13 Start watching this issue

              Created:
              Updated:
              Resolved: