[cfe-dev] Thread safety analysis: annotating function calls on pointers as accesses

Andrew Oates via cfe-dev cfe-dev at lists.llvm.org
Mon Jan 4 12:37:42 PST 2021


Hi all,

I'm a big fan of clang's thread safety analysis for C++, and I've been
experimenting with adding it to a C codebase, but running into two
primary limitations.

The first is the inability to mark struct fields as GUARDED_BY a lock
in the same struct (like a member variable can be in C++) --- this is
covered by https://bugs.llvm.org/show_bug.cgi?id=20403, which I'm
happy to see has gotten some recent attention.

The second is that there's no C analogue to the treatment of method
calls in C++ as accesses to the underlying variable, and AFAICT no way
to model that currently.  Two approaches occurred to me (names
obviously provisional),

#1: annotate functions that modify data pointed to by an argument.
For example, something like,

struct linked_list { ... };
void list_push(struct linked_list* list, void* x) ACCESS(*list) { ... }
void* list_front(const struct linked_list* list) ACCESS_SHARED(*list) { ... }

You could imagine it being as general as being able to specify any
sort of expression that should be parsed and treated as an access in
the lexical context of the function body but the analysis context of
the call site, or as narrow as just a list of parameters that should
be considered dereferenced by calls to that function.

#2: annotate variables to indicate that taking their address should be
considered an access,

struct mutex_t mu;
struct linked_list list GUARDED_BY(mu) DEREF_CONSIDERED_ACCESS;
...
list_push(&list, NULL);  // Would be considered a read access on `list`
list_front(&list);  // write access on `list`

#2 feels less clean to me --- the access is a property of the
operation, not the variable, and would flag perfectly safe address-of
operations --- but has the distinct advantage of not needing to
annotate all sorts of functions, only variable declarations that are
already being annotated with GUARDED_BY.

Thoughts on the above?  Would something like that be palatable, or a
different approach?  Or am I missing a way to do this today?

(this is all assuming the guarded-struct-field feature request is
desirable as well --- without that, I don't think there's much utility
in doing this for C code).

Cheers,
Andrew


More information about the cfe-dev mailing list