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

Andrew Oates via cfe-dev cfe-dev at lists.llvm.org
Sat May 29 06:22:40 PDT 2021


Bump?


On Thu, Jan 21, 2021 at 9:39 AM Andrew Oates <andrew at andrewoates.com> wrote:
>
> I hacked up a version of this over the weekend to play around, and it
> works quite nicely for my use case.  I made it a parameter attribute
> on the function being called that indicates that the function accesses
> the pointed-to object, e.g.
>
> void list_push(struct list_t* list ACCESS_POINTER, void* val);
> bool list_empty(const struct list_t* list ACCESS_POINTER_SHARED);
>
> The version I threw together just looks for (ignoring parens and
> casts) "foo(a, &guarded_by_var, b)" and "foo(c, pt_guarded_by_var, d)"
> type call sites.  I'm confident there are cases this misses, and I
> haven't contributed to clang before so I'm also confident I'll need
> feedback to get it into submission shape --- but would this sort of
> feature be accepted?
>
>
> On Mon, Jan 4, 2021 at 3:37 PM Andrew Oates <andrew at andrewoates.com> wrote:
> >
> > 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