[cfe-dev] Ownership attribute for malloc etc. checking

Andrew McGregor andrewmcgr at gmail.com
Tue Jun 29 21:23:58 PDT 2010


Ok, so I implemented what I think is all the suggestions...

The patch is around 100 lines shorter, so that's a definite improvement.

I'm not sure this is as minimal as it could be.

While I was there, I also changed the use of std::sort in the nonnull
parsing, since that's where I picked it up from in the first place.

Andrew

On Tue, Jun 29, 2010 at 2:43 PM, Ted Kremenek <kremenek at apple.com> wrote:

> On Jun 28, 2010, at 7:00 PM, Andrew McGregor wrote:
>
> > So, thinking about this led me to this idea:
> >
> > These attributes actually have minimal differences so far as the checker
> is concerned.  So how about there being only one attribute object  type,
> probably an OwnershipAttr, with an enum kind embedded in it, that can be
> applied to an argument.  Each one would apply to just one argument or the
> return value, but may have several arguments (the so far unimplemented
> calloc case will need this, as will pointer-to-pointer malloc).  The parser
> would have to construct two attribute objects for
> __attribute((ownership_holds, 1, 2)).  That way the dispatch can be a case
> statement on the enum rather than the current mess of casts and tests.  This
> would also save some of the methods from being templates, which I think
> would be unnecessary complexity.
> >
> > Or, again in order to reduce the duplication, I could make templates of
> some of the methods and use the type to represent the attribute kind the
> same way as I have so far.  Disadvantage: this is probably going to bloat.
>
> I'm fine with having one attribute with an enum, but I don't think it is
> mutually exclusive from having subclasses.  You can keep all the key logic
> in one class, and for clients that want to do queries that are specific to a
> particular attribute they can do downcast.  For example:
>
> class OwnershipAttr {
>  enum OwnershipKind { Holds, Takes, ... };
>  OwnershipKind OKind;
> ...
> };
>
> class OwnershipReturnsAttr : public OwnershipAttr {
> public:
>  OwnershipReturnsAttr() : OwnershipAttr(Returns) {}
>
>  static bool classof(OwnershipAttr *A) { return A->OKind == Returns; }
> };
>
> This is basically the same idiom we use with Stmts and Exprs in Clang's
> ASTS.  This gives you the best of both worlds.  You can use the 'enum' when
> you want switch on the ownership kind, but still can use the classes to
> encapsulate the relevant logic and add APIs that are only meaningful for a
> particular attribute.  For example, consider the main analysis function in
> the static analyzer.  It is littered with case statements like:
>
>   case Stmt::BlockExprClass:
>      VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
>      break;
>
> The strength of this approach is you get strong-typing when you want it,
> but it doesn't add a burden if you don't need it (e.g., if you only care
> that something is a OwnershipAttr* instead of a OwnershipReturnsAttr*).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100630/c86bf0e5/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: clang-ownership-withtests-r2.patch
Type: text/x-patch
Size: 27323 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100630/c86bf0e5/attachment.bin>


More information about the cfe-dev mailing list