[cfe-dev] Prevent RetainCountChecker from Analyzing Function Bodies when They Have Certain Annotate Attribute

Malhar Thakkar via cfe-dev cfe-dev at lists.llvm.org
Mon Jul 10 22:03:06 PDT 2017


On Tue, Jul 11, 2017 at 4:48 AM, Devin Coughlin <devin.coughlin at gmail.com>
wrote:

>
> > On Jul 10, 2017, at 6:26 AM, Malhar Thakkar via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
> >
> > Dear Dr. Alexandre,
> >
> > The leak warning is raised by MallocChecker and not the
> RetainCountChecker (which performs reference counting).
> > Adding 'rc_ownership_trusted_implementation' annotation to 'bar' and
> returning true (successfully evaluating 'bar') from evalCall() callback in
> RetainCountChecker prevents the analyzer from analyzing bar's body. This
> causes problems for the MallocChecker as it is unable to find a call to
> 'free' for the call to 'malloc' in foo().
>
> How does allocation work in ISL?

The internal mechanism is not made visible to the users. I believe
allocation is performed by either isl_malloc_or_die(), isl_calloc_or_die()
or isl_realloc_or_die(). Only the declarations of these functions are
visible to the users/developers.

> Are data structures allocated through library-provided functions that
> create an instance of the data structure?

Yes.

> Or does client code call malloc() directly? If the first, the
> library-provided allocations functions could also be annotated a trusted.
> Then, if these are annotated they won’t be inlined and the malloc checker
> won’t see the malloc site — so there won’t be a diagnostic about a leak.
>
What I meant to say with my previous emails is using evalCall() for ISL
works perfectly but say, if we want to generalize for other codebases
written in C, evalCall() might not work. Find an example below to see why
that might not work.

>
>
> > Using evalCall(), we'll be able to suppress leak false positives raised
> in ISL due to obj_free(), obj_cow() and obj_copy(). Now, we want our
> solution (to suppress such false positives) to be as generalized as
> possible. By generalized, I mean using the same "trusted" annotation across
> different codebases.
> > However, this approach (using evalCall()) can't be generalized for other
> codebases in C as it's possible for some codebase to have code similar to
> the one mentioned in my previous email. Such a test-case will result in the
> MallocChecker raising false positives.
>
> Can you give a specific example of the problem you are envisioning with
> evalCall()? Are you worried about other checkers wanting to also evaluate
> the call?
>
> Devin


Consider the following example which might constitute a small part of some
hypothetical codebase in C.

Checking for 'rc_ownership_trusted_implementation' in evalCall() suppresses
leak warnings raised by RetainCountChecker (along some path which assumes
the predicate in the second 'if' branch of 'bar' to be true) but
MallocChecker is unable to find a 'free' for the 'malloc' it has seen in
'foo' for r (as the analyzer doesn't analyze the body of 'bar' due to
evalCall() performed in RetainCountChecker).

Hence, although evalCall() works perfectly for ISL, we may not be able to
generalize it for other C codebases.

#include <stdlib.h>
typedef struct
{
int ref_count;
} rc_struct;
void free(void *);

__attribute__((annotate("rc_ownership_trusted_implementation"))) rc_struct
*bar(rc_struct *r) {
  if (!r)
    return NULL;

  if (--r->ref_count > 0)
    return NULL;

  free(r);
  return NULL;
}

void foo() {
rc_struct *r = (rc_struct *)malloc(sizeof(rc_struct));
bar(r);
} // Leak warning raised for 'r' by MallocChecker.



ᐧ
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170711/b313c7c6/attachment.html>


More information about the cfe-dev mailing list