[cfe-dev] ThreadSafetyAnalysis in C code

Aaron Ballman via cfe-dev cfe-dev at lists.llvm.org
Mon Jan 10 04:41:13 PST 2022


On Mon, Jan 10, 2022 at 6:10 AM Marco Elver <elver at google.com> wrote:
>
> Hello,
>
> We are interested in applying ThreadSafetyAnalysis to C code
> (specifically the Linux kernel).

That's fantastic to hear!

> However, the very common usecase of declaring a struct member to be
> protected by another lockable struct member inside the same struct does
> not work (see addition to test below). This results in an error:
>
>         clang/test/Sema/warn-thread-safety-analysis.c:36:24: error: use of undeclared identifier 'mu'
>           int data1 GUARDED_BY(mu);
>                                ^
>         clang/test/Sema/warn-thread-safety-analysis.c:38:24: error: use of undeclared identifier 'mu'
>           int data2 GUARDED_BY(mu);
>
> AFAIK, this is the main limitation preventing us to use it on the Linux
> kernel.
>
> Does anyone know what's going on here?

This is https://github.com/llvm/llvm-project/issues/20777

The crux of the issue is there are some lookup difficulties because C
doesn't have the notion of a "this" pointer for the structure object
itself.

~Aaron

>
> Thanks,
> -- Marco
>
> ------ >8 ------
>
> diff --git a/clang/test/Sema/warn-thread-safety-analysis.c b/clang/test/Sema/warn-thread-safety-analysis.c
> index a45fb8e0f382..6b75db4c246e 100644
> --- a/clang/test/Sema/warn-thread-safety-analysis.c
> +++ b/clang/test/Sema/warn-thread-safety-analysis.c
> @@ -31,6 +31,13 @@ struct Foo {
>    struct Mutex *mu_;
>  };
>
> +// Struct with mutex protecting data within.
> +struct Bar {
> +  int data1 GUARDED_BY(mu);
> +  struct Mutex mu;
> +  int data2 GUARDED_BY(mu);
> +};
> +
>  // Declare mutex lock/unlock functions.
>  void mutex_exclusive_lock(struct Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
>  void mutex_shared_lock(struct Mutex *mu) SHARED_LOCK_FUNCTION(mu);
> @@ -46,6 +53,7 @@ int a_ GUARDED_BY(foo_.mu_);
>  int *b_ PT_GUARDED_BY(foo_.mu_) = &a_;
>  int c_ GUARDED_VAR;
>  int *d_ PT_GUARDED_VAR = &c_;
> +struct Bar bar_;
>
>  // Define test functions.
>  int Foo_fun1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
> @@ -117,6 +125,13 @@ int main() {
>    (void)(*d_ == 1);
>    mutex_unlock(foo_.mu_);
>
> +  bar_.data1 = 0; // expected-warning{{writing variable 'data1' requires holding mutex 'bar_.mu' exclusively}}
> +  bar_.data2 = 0; // expected-warning{{writing variable 'data2' requires holding mutex 'bar_.mu' exclusively}}
> +  mutex_exclusive_lock(&bar_.mu);
> +  bar_.data1 = 1;
> +  bar_.data2 = 1;
> +  mutex_unlock(&bar_.mu);
> +
>    mutex_exclusive_lock(&mu1);    // expected-note {{mutex acquired here}}
>    mutex_shared_unlock(&mu1);     // expected-warning {{releasing mutex 'mu1' using shared access, expected exclusive access}}
>                                   // expected-note at -1{{mutex released here}}


More information about the cfe-dev mailing list